c - Implementing pipelining in a Linux shell -


i'm trying develop shell in linux operating systems project. 1 of requirements support pipelining (where calling ls -l|less passes output of first command second). i'm trying use c pipe() , dup2() commands redirection doesn't seem happening (less complains didn't receive filename). can identify i'm going wrong/how might go fixing that?

edit: i'm thinking need use either freopen or fdopen somewhere since i'm not using read() or write()... correct?

(i've heard others who've done project using freopen() way solve problem; if think better, tips going direction appreciated.)

here's execute_external() function, executes commands not built-in shell. various commands in pipe (e.g. [ls -l] , [less]) stored in commands[] array.

 void execute_external() {             int numcommands = 1;     char **commands;     commands = malloc(sizeof(char *));      if(strstr(raw_command, "|") != null)             {         numcommands = separate_pipeline_commands(commands);     }     else     {         commands[0] = malloc(strlen(raw_command) * sizeof(char));         commands[0] = raw_command;     }      int i;     int pipefd[2];     (i = 0; < numcommands; i++)     {         char **parameters_array = malloc(strlen(commands[i]) * sizeof(char *));         int num_params;         num_params = str_to_str_array(commands[i], parameters_array);          if (numcommands > 1 && > 0 && != numcommands - 1)         {             if (pipe(pipefd) == -1)             {                 printf("could not open pipe.");             }         }          pid_t pid = fork();           pmesg(2, "process forked. id = %i. \n", pid);         int status;         if (fork < 0)         {             fprintf(to_write_to, "could not fork process complete external command.\n");             exit(exit_failure);         }          if (pid == 0) // child process         {             if (numcommands > 1) { close(pipefd[1]); } // close unused write end of pipe                            if (i == 0) // may pipelining , first process             {                 dup2(1, pipefd[1]); // set source descriptor (for next iteration of loop) proc's stdout             }             if (i !=0 && (i != numcommands-1)) // pipelining , not first or last process             {                 dup2(pipefd[0], 0); // set stdin of process source of previous process             }             if (execvp(parameters_array[0], parameters_array) < 0)             {                 fprintf(to_write_to, "could not execute external command. errno: %i.\n", errno);                 exit(exit_failure);             }             else    { pmesg(2, "executed child process.\n");}         }         else         {             if (numcommands > 1) { close(pipefd[0]); } // close unused read end of pipe             if (backgrounding == 0) { while(wait(&status) != pid); }// wait child finish executing         }          free(parameters_array);     } free(commands);     } 

it looks there couple of bugs going on in code.

first, dup2's in child. in order connect pipe need dup2 stdout of parent write end pipefd[1] of pipe. hook read end stdin.

also looks on of dup2's backwards dup2 fildes duplicated fildes2. when reassign stdin want dup2(in, 0) , stdout want dup2(out, 1).

so stripped down piece of piping code going like:

 int pipefd[2];  pipe(pipefd);   pid_t pid = fork();   if (pid == 0) //the child  {       dup2(pipefd[0], 0);  }  else  {       dup2(pipefd[1], 1);  } 

Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -