我一直试图让这个工作,并开始认为不可能以这种方式使用管道。
这可能吗?在父进程使用fgets while循环将输入推送到子进程时保持管道打开?然后,子进程将检测输入(通过标准输入)并将其打印到屏幕上。
如果不可能,为什么不呢?
pipe.c:
#define MAXINPUTLINE 10240
int pid, p[2];
char input[MAXINPUTLINE];
int main(void)
{
char* arguments[] = {"./bin/child_program", "arg1", NULL};
if(pipe(p) == -1) {
printf("Pipe Failed\n");
exit(1);
}
pid = fork();
if(pid == -1) {
printf("Fork Failed\n");
exit(1);
}
int status;
if(pid == 0) { //child
close(p[1]); //close stdout
dup2(p[0],0); //open stdin
execvp(arguments[0],arguments);
}
else { //parent
close(p[0]);
while (fgets(input, sizeof(input), stdin))
write(p[1],input,strlen(input)+1);
wait(&status);
}
return 0;
}
child_program:
#define MAXINPUTLINE
int main(int argc, char *argv[])
{
char input[MAXINPUTLINE];
while (fgets(input, sizeof(input), stdin)) {
printf(" Input Recieved: %s :",input);
}
return 0;
}
答案 0 :(得分:0)
我有一个工作代码,用于解决您在此处尝试实现的目标:
static bool
start_subprocess(char *const command[], int *pid, int *infd, int *outfd)
{
int p1[2], p2[2];
if (!pid || !infd || !outfd)
return false;
if (pipe(p1) == -1)
goto err_pipe1;
if (pipe(p2) == -1)
goto err_pipe2;
if ((*pid = fork()) == -1)
goto err_fork;
if (*pid) {
*infd = p1[1];
*outfd = p2[0];
close(p1[0]);
close(p2[1]);
return true;
} else {
dup2(p1[0], 0);
dup2(p2[1], 1);
close(p1[0]);
close(p1[1]);
close(p2[0]);
close(p2[1]);
execvp(*command, command);
/* Subprocess error occured. */
fprintf(stderr, "error running %s: %s\n", *command, strerror(errno));
abort();
}
err_fork:
close(p2[1]);
close(p2[0]);
err_pipe2:
close(p1[1]);
close(p1[0]);
err_pipe1:
return false;
}
您可以将此功能视为公共领域。它接受以NULL结尾的命令行参数列表,包括命令本身,并设置进程ID 和文件描述符以与 stdin 和 stdout 输出参数。
最重要的是,您将获得关于read
/ write
POSIX样式函数(和系统调用),fgets
/ fputs
和类似(缓冲)ANSI的一些知识风格的功能和它们之间的桥梁,如fdopen
。