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

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -