关闭管道不会将 EOF 发送到另一端
Closing a pipe does not send EOF to other end
我想 运行 来自 C 程序的外部命令。比方说,作为最小的工作示例,我想 运行 'cat' 命令。我使用 fork() 和 execl() 生成新进程,并通过管道与它通信。
这就是我的问题所在。在终端中,我会通过按 CTRL-D 告诉 'cat' 我已完成输入。在这里,我试图通过关闭文件描述符来做到这一点——请参阅下面代码中带有 close(outpipefd[1]) 的行——但这似乎不起作用。由于 'cat' 正在等待更多输入,我的代码停止了。
我的代码如下...我做错了什么?提前致谢!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
int main(void)
{
pid_t pid=0;
int inpipefd[2];
int outpipefd[2];
/*
We create the pipes for communicating with the child process
*/
pipe(inpipefd);
pipe(outpipefd);
if((pid=fork())==0)
{
/*
Child
*/
dup2(outpipefd[0],STDIN_FILENO);
dup2(inpipefd[1],STDOUT_FILENO);
dup2(inpipefd[1],STDERR_FILENO);
/*
We spawn the process
*/
execl("/bin/cat","cat",(char *)(NULL));
/*
Nothing below this line should be executed by child process.
If so, it means that the execl function wasn't successfull, so lets exit!
*/
exit(1);
}
/*
Parent.
Close unused pipe ends.
*/
close(outpipefd[0]);
close(inpipefd[1]);
/*
Now we can write to outpipefd[1] and read from inpipefd[0]
*/
char *greeting="Hello world!\n";
write(outpipefd[1],greeting,strlen(greeting));
/*
Here I believe that closing the pipe should be equivalent to
pressing CTRL-D in a terminal, therefore terminating the cat command...
This is unfortunately not the case!
*/
close(outpipefd[1]);
while(1)
{
char buf[256];
for(int c=0;c<256;c++)
buf[c]=0;
if(read(inpipefd[0], buf, 256)<=0)
break;
printf("OUTPUT: %s\n", buf);
}
/*
Send SIGKILL signal to the child process
*/
int status;
kill(pid, SIGKILL);
waitpid(pid, &status, 0);
return 0;
}
child 仍然打开了两个管道的两端,因为您从未关闭其中的任何 FD。在每个引用管道写入端的 FD 关闭之前,它不会 return EOF。
您还必须关闭子项中未使用的管端,否则仍然会有东西打开阻塞另一端。关闭父 和子 中不使用的内容,您将获得 EOF。
我想 运行 来自 C 程序的外部命令。比方说,作为最小的工作示例,我想 运行 'cat' 命令。我使用 fork() 和 execl() 生成新进程,并通过管道与它通信。
这就是我的问题所在。在终端中,我会通过按 CTRL-D 告诉 'cat' 我已完成输入。在这里,我试图通过关闭文件描述符来做到这一点——请参阅下面代码中带有 close(outpipefd[1]) 的行——但这似乎不起作用。由于 'cat' 正在等待更多输入,我的代码停止了。
我的代码如下...我做错了什么?提前致谢!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
int main(void)
{
pid_t pid=0;
int inpipefd[2];
int outpipefd[2];
/*
We create the pipes for communicating with the child process
*/
pipe(inpipefd);
pipe(outpipefd);
if((pid=fork())==0)
{
/*
Child
*/
dup2(outpipefd[0],STDIN_FILENO);
dup2(inpipefd[1],STDOUT_FILENO);
dup2(inpipefd[1],STDERR_FILENO);
/*
We spawn the process
*/
execl("/bin/cat","cat",(char *)(NULL));
/*
Nothing below this line should be executed by child process.
If so, it means that the execl function wasn't successfull, so lets exit!
*/
exit(1);
}
/*
Parent.
Close unused pipe ends.
*/
close(outpipefd[0]);
close(inpipefd[1]);
/*
Now we can write to outpipefd[1] and read from inpipefd[0]
*/
char *greeting="Hello world!\n";
write(outpipefd[1],greeting,strlen(greeting));
/*
Here I believe that closing the pipe should be equivalent to
pressing CTRL-D in a terminal, therefore terminating the cat command...
This is unfortunately not the case!
*/
close(outpipefd[1]);
while(1)
{
char buf[256];
for(int c=0;c<256;c++)
buf[c]=0;
if(read(inpipefd[0], buf, 256)<=0)
break;
printf("OUTPUT: %s\n", buf);
}
/*
Send SIGKILL signal to the child process
*/
int status;
kill(pid, SIGKILL);
waitpid(pid, &status, 0);
return 0;
}
child 仍然打开了两个管道的两端,因为您从未关闭其中的任何 FD。在每个引用管道写入端的 FD 关闭之前,它不会 return EOF。
您还必须关闭子项中未使用的管端,否则仍然会有东西打开阻塞另一端。关闭父 和子 中不使用的内容,您将获得 EOF。