c - Multiple child processes writing to parent the result of a unix command executed with popen -
i have write c code that:
- accepts 'n' command line arguments (unix commands)
- for each arguments main program launches 2 child processes
- each child process execute unix command (args[i]) random delay , using popen , send answer parent process parent process print first n/2 responses received
- only pipe channel must used communication between parent process , child processes
i have written following source code:
#include <stdio.h> #include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <wait.h> #include <time.h> #include <string.h> #include <errno.h> #define dim 100 int main(int argc, char *args) { int t, nrr=argc-1,f,p[2],prid,d; file *fd1, *fd2; //pipe channel creation if(pipe(p)<0) { perror("pipe channel creation error!"); exit(1); } for(i=1;i<argc;i++) { d=strlen(args[i]); if((f=fork())==0) { //first child process char *buffer = malloc(dim*sizeof(char)); //the child process write parent process close(p[0]); //delay process execution srand(time(null)); int s=rand()%2; sleep(s); fd1 = popen(args[i],"r"); //writing pid parent process prid=getpid(); if(write(p[1],&prid,sizeof(int))!=sizeof(int)) { perror("pipe writing error!"); exit(3); } //writing command string length if(write(p[1],&d,sizeof(int))!=sizeof(int)) { perror("pipe writing error!"); exit(3); } //writing command string if(write(p[1],args[i],sizeof(args[i]))!=sizeof(args[i])) { perror("pipe writing error!"); exit(3); } //writing command output result string while(fread(buffer,dim,1,fd1)>0) { if(write(p[1],buffer,sizeof(buffer))!=sizeof(buffer)) { perror("pipe writing error!"); exit(3); } } free(buffer); pclose(fd1); exit(i+1); } else if((f=fork())==0) { //second child process char *buffer = malloc(dim*sizeof(char)); //the child process write parent process close(p[0]); //delay process execution srand(time(null)); int s=rand()%2; sleep(s); fd2 = popen(args[i],"r"); //writing pid parent process prid=getpid(); if(write(p[1],&prid,sizeof(int))!=sizeof(int)) { perror("pipe writing error!"); exit(3); } //writing command string length if(write(p[1],&d,sizeof(int))!=sizeof(int)) { perror("pipe writing error!"); exit(3); } //writing command string if(write(p[1],args[i],sizeof(args[i]))!=sizeof(args[i])) { perror("pipe writing error!"); exit(3); } //writing command output result string while(fread(buffer,dim,1,fd2)>0) { if(write(p[1],buffer,sizeof(buffer))!=sizeof(buffer)) { perror("pipe writing error!"); exit(3); } } free(buffer); pclose(fd2); exit(i+2); } } if(f>0) { //parent process behavior close(p[1]); //the parent process not write child processes for(i=0;i<nrr;i++) { //we read , print first 'n' responses received through pipe channel child processes waitpid(-1,null,0); char *cmd,*buffer; //read pid of child process if(read(p[0],&prid,sizeof(int))!=sizeof(int)) { perror("pipe reading error!") exit(2); } //read command string length if(read(p[0],&d,sizeof(int))!=sizeof(int)) { perror("pipe reading error!") exit(2); } //read command cmd = malloc(d*sizeof(char)); if(read(p[0],cmd,sizeof(cmd))!=sizeof(cmd)) { perror("pipe reading error!") exit(2); } printf("\nprocess %d -> %s:\n",prid,cmd); //read , print unix command result buffer = malloc(dim*sizeof(char)); while(read(p[0],buffer,sizeof(buffer))>0) { printf("%s",buffer); } free(buffer); free(cmd); //wait other n/2 child processes terminate while(waitpid(-1,null,0)>0) { if(errno == echild) break; } } } return 0; } my code compiles , runs; have tried "ls" argument. program not show expected output. have introduced check prints , detected following issues:
- in child processes cannot read whole "ls" output fd1 , fd2
- the parent process not receive anything/does not receive correctly "ls" output string sent through pipe child processes (it receives though correctly child process id , command name).
could there problems caused multiples child processes try write (probably in same time) in same pipe channel? or there other issues didn't think of?
many thanks.
each child needs it's own pipes parent, p should 2d array, p[child][file id]. @ no time trying collect command data @ no point accessing pipe relating stdout of command. how plan send commands output parent. need tell parent how many bytes of text coming, writing best solution. allows malloc buffer ready store string , can block read rather byte @ time til '\0'
Comments
Post a Comment