2

I'm trying to create a simple shell interface program that takes shell commands as user input from the parent process and send the simple shell command to the child process via a pip IPC which actually executes the shell command. The child while loop keeps repeating even after typing "quit"

int main() {
    char userInput[BUFFER_SIZE];

    int fpipe[2];
    pid_t pid;

    // INTRODUCTION TO PROGRAM
    printf("------- WELCOME TO THE FORKED PARENT -------\n");
    printf("------- YOU MAY QUIT AT ANY TIME BY TYPING 'quit' or 'q' -------\n");

    if (pipe(fpipe)== -1){
        printf("------- PIPE HAS FAILED -------\n");
        return 1;
    }

    pid = fork();

    if (pid < 0){
        printf("------- FORK HAS FAILED -------\n");
        return 1;
    }

    if (pid > 0){
        close(fpipe[0]);
        printf("\nosh> ");
        scanf("%s", userInput);

        while ((strcmp(userInput,"quit") != 0 && strcmp(userInput,"q") != 0)){
            printf("\nosh> ");
            write(fpipe[1], userInput, strlen(userInput)+1);
            scanf("%s", userInput);
        }
        close(fpipe[1]);
    }

    else{
        close(fpipe[1]);

        while(1){
            if (read(fpipe[0], userInput, BUFFER_SIZE) == -1){
                return 1;

            }
            if ((strcmp(userInput,"quit") != 0 && strcmp(userInput,"q") != 0)){
                system(userInput);
                printf("osh> ");
            }
            else{
                break;
            }
        }
        close(fpipe[0]);
    }
    return 0;
}
3
  • Why does the child print an osh> prompt? That's only need in the parent. Commented Mar 12, 2020 at 0:20
  • Try printing userInput in the child, to see what it thinks it's processing. Commented Mar 12, 2020 at 0:25
  • The read() call returns 0 on EOF; it only returns -1 on an error, and EOF is not an error. Test while (read(fpipe[0], userInput, BUFFER_SIZE) > 0) for your loop condition. Commented Mar 12, 2020 at 0:40

1 Answer 1

4

The problem is that the loop in the parent stops when the user enters quit, it doesn't send it to the child. So the child's condition for stopping the loop is never matched. It keeps reading from the pipe, which returns nothing because it's at EOF, so it keeps executing the last command that was sent.

The simplest solution is for the child to break out of the loop when it gets EOF from the pipe, rather than looking for quit.

        while(1){
            int n;
            n = read(fpipe[0], userInput, BUFFER_SIZE);
            if (n == -1) {
                return 1;
            }
            if (n == 0) {
                break;
            }
            system(userInput);
        }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.