c - Redirect child process's stdin and stdout to pipes -
edit: solution
int c1=dup2(pipes[0][1],stdout_fileno); int c2=dup2(pipes[1][0],stdin_fileno); setvbuf(stdout,null,_ionbf,0);
it setvbuf set stdout non-buffered. though printing newline character if destination not actual screen, guess, becomes buffered.
edit: when put fflush(stdout) after line 1 , fflush(fout) after line 4 works expected. however, not work without fflush(stdout) after line 1. problem not able put fflush in program planning run.
i trying start program process. don't have access code know uses stdin , stdout user interaction. trying start program creating 2 pipes, fork-ing , redirecting child's stdin/stdout proper pipe ends. points parent should able communicate child via file descriptors, while stdin/stdout should intact. popen syscall opens unidirectional pipe. following code works.
there 4 lines marked line 1..4.
line 1 child sending pipe, line 2 child receiving pipe, line 3 parent sending pipe, line 4 parent receiving pipe,
this toy example make sure things work. issue is 4 lines line1..4 uncommented output see on terminal
parent1: -1 fd: 1 0 4 5 0 1 debug1: 0 debug2: 0
while if line 1 , line 3 uncommented see continuous stream of data. same happens if if line 2 , line 4 uncommented. however, want full bidirectional communication. adding commented sleep not change behavior.
what issue here. wonder why there no bidirectional popen.
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);
your code quite long i'm not sure have understand why don't use select ? want redirect output of child in tird process or use in parent process ?
the following exemple cat in child process.
#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 output (stdout 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 changes on p[0] if(fd_isset(p[0], &rfds)) { int ret = 0; while ((ret = read(p[0], buffer, 10)) > 0) //read on pipe { write(1, buffer, ret); //display result memset(buffer, 0, 10); } } } } }
Comments
Post a Comment