0

I have a function that takes an array of strings and the size of the array. I have a loop that tokenizes the string into command and arguements and then forks and executes the commands one by one. For each command I need to pipe the output to the next commands input. I'm not entirely sure if my dup/close calls are correct. Any help would be appreciated. I have it set to not pipe if only one command in array.

void runcmds(char **cmds, int count){
    int fd[2];
    int index;
    pid_t pID;
    for (index = 0; index < count; index++){
        //tokenize string
        token *newToken = mytoken(cmds[index]);
        if (count > 1){ //pipe if more than one command
            pipe(fd);
        }
        pID = fork();
        if (pID < 0){ //fork failed
           printf("Error: fork\n");
           exit(1);
        }
        else if (pID == 0){
            if (count == 1){
                ; //no need to pipe
            }
            //if first command of multiple commands
            else if ((index == 0) && (count > 1)){
                close(1); //close stdout
                dup(fd[1]); //replace stdout with pipe write
                close(fd[0]);//close pipe read
            }
            //if last command
            else if (index == (count - 1)){
                close(0); //close stdin
                dup(fd[0]); //replace stdin with pipe read
                close(fd[1]); //close pipe write
            //if middle command
            else{
                close(0);
                dup(fd[0]);
                close(1);
                dup(fd[1]);
            }
            //execute command
            if (execvp(newToken->command, newToken->args) < 0){
                //execvp failed
                printf("Error: execvp\n");
                exit(1);
             }
        }
        waitpid(pID, NULL, 0);
        if ((index == 0) && (count > 1)){
            close(fd[1]);
        }
        else if (index == (count - 1)){
            close(fd[0]);
        }
        else{
             ; //middle commands need both open
        }
    }
    return;
}
chrk
  • 4,037
  • 2
  • 39
  • 47
  • What specific error are you getting? – merlin2011 Jun 29 '14 at 22:40
  • No specific errors. I can get it to execute single commands but with multiple commands it just sort of hangs. – user3788565 Jun 29 '14 at 22:42
  • Is your intended purpose to chain the commands, using stdout from a prior as stdin to the next, etc.? And when `newToken` is crafted, your first argument is the same as the executing command, right? – WhozCraig Jun 30 '14 at 00:24
  • That is correct. The mytoken function breaks a string down into words and storing them into an array. The newToken->command is set equal to the first word stored in that array. For example ls -1 /tmp would be stored as ls, -1, /tmp and command set to ls. I need to chain them together in the same fashion as ls -1 /tmp | wc -l would. – user3788565 Jun 30 '14 at 02:23

0 Answers0