Почему труба вырывается из петли? - PullRequest
0 голосов
/ 22 марта 2019

Я работаю над программой оболочки для c и попытался выяснить, почему она продолжала выходить из цикла после запроса ответа пользователя.Он правильно запускает команду, но по какой-то причине вылетает.Я не мог понять, почему, и я думаю, что это как-то связано с тем, как я делаю конвейеры.

Это то, что у меня есть для примера, он должен выполнить команду piped и спроситьпользователь должен продолжать выполнять команду снова и снова, пока пользователь не введет что-либо, кроме «да».Может ли это быть execvp, что вызывает перерыв?Как я мог получить его, чтобы он продолжал цикл?Редактировать с обновлением разветвления.

#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>


int main()
{
    char str[3];
    do{
        char* leftSide[] = {"ls", NULL};
        char* rightSide[] = {"wc", NULL};

        pid_t id, id2;
        int pipe_fd[2];

        pipe(pipe_fd);
        id = fork();

        if(id == 0){
            dup2(pipe_fd[0],0);
            close(pipe_fd[1]);
            close(pipe_fd[0]);
            if(execvp(rightSide[0], rightSide) == -1){
                perror("error running pipe right command");
            }
        }
        else{
            id2 = fork();
            if(id2 == 0){
                dup2(pipe_fd[1],1);
                close(pipe_fd[1]);
                close(pipe_fd[0]);
                if(execvp(leftSide[0],leftSide) == -1){
                    perror("error running pipe left command");
                }
            }
            else{
                wait(NULL); 
                wait(NULL); 
            }
        }

        printf("Continue?");
        fgets(str, 3, stdin);
        str[3] = '\0';
    }while(strcmp(str, "yes") == 0);

    return 0;
}

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

Вы завершаете свою программу на

    if(execvp(leftSide[0],leftSide) == -1){

Вы должны fork() дважды; один раз для rightSide и один раз для leftSide.

1 голос
/ 22 марта 2019

Здесь есть две проблемы:

  1. Как отметил @ensc, в его ответе ваша программа завершается, когда вы вызываете execvp. Вам нужно будет сделать двоих детей, родитель останется в вашей программе, запрашивая у пользователя дополнительные данные, пока дети будут выполнять leftside и rightside.

  2. Вторая проблема связана с fgets

Согласно справочной странице:

fgets () считывает из потока не более одного символа меньше размера и сохраняет их в буфере, указанном s. Чтение останавливается после EOF или новой строки. Если читается новая строка, сохраняется в буфере .

Таким образом, строка, введенная пользователем, будет "yes\n", а не "yes", а strcmp всегда будет неудачным.

...