C 重定向子进程';s标准管道和标准管道
编辑: 解决办法是C 重定向子进程';s标准管道和标准管道,c,linux,unix,posix,C,Linux,Unix,Posix,编辑: 解决办法是 int c1=dup2(pipes[0][1],STDOUT_FILENO); int c2=dup2(pipes[1][0],STDIN_FILENO); setvbuf(stdout,NULL,_IONBF,0); SETVBUF可将标准输出设置为非缓冲。即使我正在打印换行符,如果目标不是实际的屏幕,我猜它会被缓冲 编辑: 当我将fflush(stdout)放在第1行之后,将fflush(fout)放在第4行之后时,它会按预期工作。但是,如果没有第1行之后
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
setvbuf(stdout,NULL,_IONBF,0);
SETVBUF可将标准输出设置为非缓冲。即使我正在打印换行符,如果目标不是实际的屏幕,我猜它会被缓冲
编辑: 当我将fflush(stdout)放在第1行之后,将fflush(fout)放在第4行之后时,它会按预期工作。但是,如果没有第1行之后的fflush(stdout),它将无法工作。问题是我无法将fflush放入计划运行的程序中
我正在尝试从我的流程开始另一个程序。我无法访问它的代码,但我知道它使用stdin和stdout进行用户交互。我试图通过创建2个管道来启动该程序,分叉并将孩子的stdin/stdout重定向到正确的管道端。要点是父级应该能够通过文件描述符与子级通信,而其stdin/stdout应该是完整的。POPEN系统调用仅打开单向管道。下面的代码几乎可以工作 有4行标记为第1..4行 第1行是子项发送到管道, 第2行是从管道接收的儿童, 第3行是发送到管道的父级, 第4行是从管道接收的父级 这只是一个玩具的例子,以确保事情的工作。问题是所有4行LINE1..4都未注释,我在终端上看到的输出是
PARENT1: -1
FD: 1 0 4 5 0 1
DEBUG1: 0
DEBUG2: 0
而如果第1行和第3行没有注释,我只看到一个连续的数据流。如果只有第2行和第4行没有注释,也会发生同样的情况。但是,我想要一个完全双向的通信。另外,添加注释睡眠不会改变行为
这里可能有什么问题。我想知道为什么没有双向波本
int pid;
int pipes[2][2];
pipe(pipes[0]);
pipe(pipes[1]);
pid=fork();
if(pid==0)
{
//usleep(1000000);
close(pipes[0][0]);
close(pipes[1][1]);
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
//int c2=dup2(STDIN_FILENO,pipes[1][0]);
fprintf(stderr,"FD: %d %d %d %d %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO);
//FILE*fout=fdopen(pipes[0][1],"w");
//FILE*fin =fdopen(pipes[1][0],"r");
while(1)
{
static int c1=0;
fprintf(stderr,"DEBUG1: %d\n",c1);
printf("%d\n",c1); // LINE 1
fprintf(stderr,"DEBUG2: %d\n",c1);
scanf("%d",&c1); // LINE 2
fprintf(stderr,"DEBUG3: %d\n",c1);
c1++;
}
//fclose(fout);
//fclose(fin);
return 0;
}
close(pipes[0][1]);
close(pipes[1][0]);
char buffer[100];
FILE*fin=fdopen(pipes[0][0],"r");
FILE*fout=fdopen(pipes[1][1],"w");
while(1)
{
int c1=-1;
printf("PARENT1: %d\n",c1);
fscanf(fin,"%d",&c1); // LINE 3
printf("Recv: %d\n",c1);
fprintf(fout,"%d\n",c1+1); // LINE 4
printf("PARENT3: %d\n",c1+1);
}
fclose(fin);
fclose(fout);
你的代码很长,所以我不确定我是否理解了所有内容,但你为什么不使用? 您想在tird进程中重定向子进程的输出,还是在父进程中使用它 以下示例在子进程中使用cat
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int p[2];
pipe(p);
pid = fork();
if (pid == 0)
{
dup2(p[1], 1); // redirect the output (STDOUT to the pipe)
close(p[0]);
execlp("cat", "cat", NULL);
exit(EXIT_FAILURE);
}
else
{
close(p[1]);
fd_set rfds;
char buffer[10] = {0};
while (1)
{
FD_ZERO(&rfds);
FD_SET(p[0], &rfds);
select(p[0] + 1, &rfds, NULL, NULL, NULL); //wait for changes on p[0]
if(FD_ISSET(p[0], &rfds))
{
int ret = 0;
while ((ret = read(p[0], buffer, 10)) > 0) //read on the pipe
{
write(1, buffer, ret); //display the result
memset(buffer, 0, 10);
}
}
}
}
}
#包括
#包括
int main()
{
pid_t pid;
int p[2];
管道(p);
pid=fork();
如果(pid==0)
{
dup2(p[1],1);//重定向输出(STDOUT到管道)
接近(p[0]);
execlp(“cat”、“cat”、NULL);
退出(退出失败);
}
其他的
{
关闭(p[1]);
fd_集rfds;
字符缓冲区[10]={0};
而(1)
{
FD_ZERO(和RFD);
FD_集(p[0],&rfds);
选择(p[0]+1,&rfds,NULL,NULL,NULL);//等待p[0]上的更改
if(FD_ISSET(p[0],&RFD))
{
int-ret=0;
而((ret=read(p[0],buffer,10))>0)//在管道上读取
{
write(1,buffer,ret);//显示结果
memset(缓冲区,0,10);
}
}
}
}
}
事实上我找到了解决办法。将标准输出设置为非缓冲状态是SETVBUF(即使我正在打印换行符,但目标不是实际屏幕,我想,它会被缓冲。我这样做的原因是我正在启动的程序有一个PRINT-EVAL循环,我想通过编程对其做出响应。@user1068779很高兴您找到了解决方案。您仍然可以在父进程中写入p。)[1] 回答回答你自己的问题没关系!你不应该用你的答案编辑原始问题,而应该将其作为答案发布,然后接受它。