0

Ok, in this code I have 2 primary problems.

1: The parent doesn't wait for the child to print before returning to main and printing. I included a waitpid() but it doesn't seem to be working how I expected.

  1. When I redirect, I create the file fine, but nano and vim don't "see" the file, Gedit however can (so I know my output is being sent correctly)

The flow of this function:

A string is input, the string is checked for a trailing & (if it exists, it is removed and the background flag is updated).

Then the string is tokenized on '|'
Each token is tokenized on '<' and '>' Then each string from that is tokenized on ' ' The resulting char ** is executed with the output/input being redirected based off the results of the above tokenizations.

    void execute_command(char * s)
    {
        printf("\n");
        int fd[3][2]; //  since we are guaranteed each type of redirection will be used only once, I only need 3 pipes:  <  >  and |
        //int fd[2];    
        int res;
        pid_t pid;
        int status;
        int stdin_c = dup(0);
        int stdout_c = dup(1);
        int i;
        int background = 0;

        for(i = 0; s[i] != '\0'; i++);
            if(s[i-1] == '&')
            {
                background = 1;
                s[i-1] = '\0';
            }

        char ** piped = token_pipe(s);
        char ** left_a;
        char ** right_a;
        int output = 0;
        int input = 0;

        for(i = 0; piped[i] != NULL; i++)
        {
            left_a = token_leftarrow(piped[i]);
            right_a = token_rightarrow(piped[i]);
            if(left_a[1] != NULL)   
            {
                free(piped[i]);
                piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                strcpy(piped[i], left_a[0]);
                fd[0][0] = open(left_a[1], O_RDONLY);
                input = i;      
            }

            if(right_a[1] != NULL)  
            {
                free(piped[i]);
                piped[i] = calloc(strlen(left_a[0]) + 1, sizeof(char));
                strcpy(piped[i], right_a[0]);
                fd[1][1] = open(right_a[1], O_WRONLY | O_CREAT, 0666);
                output = i;
            }   
        }

        char ** spaced = token_space(piped[0]);
        char ** spaced2 = NULL;
        if(piped[1] != NULL)
        {
            spaced2 = token_space(piped[1]);
            res = pipe(fd[2]);
            if(res < 0)
            {
                printf("Pipe Failure\n");
                exit(-1);
            }// end if
        }   

        if(fork() == 0)
        {
            if(background == 1)
               setpgid(0, 0);
            if(piped[1] != NULL)
            {
                close(fd[2][1]);
                close(0);
                dup(fd[2][0]);

                if(output == 1 && right_a[1] != NULL)
                {
                    dup2(fd[1][1], 1);
                    close(fd[1][1]);
                }         

                execvp(spaced2[0], spaced2);
                perror("Invalid Command");
                exit(-1);
            }
            else
            {   
                if(input == 0 || output == 0)
                {
                    if(right_a[1] != NULL)
                    {
                        dup2(fd[1][1], 1);
                        close(fd[1][1]);
                    }
                    if(left_a[1] != NULL)
                    {
                        dup2(fd[0][0], 0);
                        close(fd[0][0]);
                    }

                }   

                execvp(spaced[0], spaced);
                perror("Invalid command\n");
                exit(-1);
            }
        }
    else
    {
        if(piped[1] != NULL)
        {
            if((pid = fork()) == 0)
            {
                close(fd[2][0]);
                close(1);
                dup(fd[2][1]); 
                if(input == 0 && left_a[1] != NULL)
                {
                    dup2(fd[0][0], 0);
                    close(fd[0][0]);
                }     

                execvp(spaced[0], spaced);
                perror("Invalid Command");
                exit(-1);
            }
            else
                if(background == 0)
                    waitpid(pid, &status, WNOHANG);

        }
        else
            if(background == 0)
                wait(NULL);


        close(fd[2][0]);
        close(fd[2][1]);
        close(fd[0][0]);
        close(fd[1][1]);
        dup2(stdin_c, 0);
        dup2(stdout_c, 1);

      } 


    }
north.mister
  • 500
  • 1
  • 7
  • 24
  • maybe if the code was commented, so we knew what was trying to be accomplished at each code block, then we could help. As it is, I see (what I think) are numerous bad logic sequences, just as a simple start, the call to waitpid() has the WNOHANG parameter, so it will not wait for the child to complete – user3629249 Feb 27 '15 at 01:02
  • the fork() function has three exit cases, not just two. I.E. the code needs to always check the error cases and allow for them, rather than assuming that everything works – user3629249 Feb 27 '15 at 01:05
  • perhaps reading the system function descriptions would help. BTW: there are three standard file descriptors that need to be duped, stdin, stdout, stderr – user3629249 Feb 27 '15 at 01:07
  • I apologize about the commenting, I'll try it without the WNOHANG parameter, and I don't care about stderr in this situation. – north.mister Feb 28 '15 at 00:32

0 Answers0