Использование процесса fork на C не удалось во время цикла - PullRequest
2 голосов
/ 12 марта 2020

Я пытаюсь создать простую программу интерфейса оболочки, которая принимает команды оболочки в качестве пользовательского ввода от родительского процесса и отправляет простую команду оболочки дочернему процессу через IP-адрес pip C, который фактически выполняет команду оболочки. Ребенок пока l oop продолжает повторяться даже после того, как набрал "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;
}

1 Ответ

4 голосов
/ 12 марта 2020

Проблема в том, что l oop в родительском элементе останавливается, когда пользователь вводит quit, он не отправляет его дочернему элементу. Таким образом, условие ребенка для остановки l oop никогда не соответствует. Он продолжает чтение из канала, который ничего не возвращает, потому что он находится в EOF, поэтому он продолжает выполнять последнюю отправленную команду.

Самое простое решение для дочернего элемента - выйти из l oop, когда он получает EOF из трубы, а не ищет quit.

        while(1){
            int n;
            n = read(fpipe[0], userInput, BUFFER_SIZE);
            if (n == -1) {
                return 1;
            }
            if (n == 0) {
                break;
            }
            system(userInput);
        }
...