Каналы и процессы

Предпосылка: Напишите программу, которая запрашивает у пользователя две входные строки. Каждая входная строка должна быть командой unix с разрешенными аргументами. Например, i nput 1 может быть ls -l , а вход 2 может быть more . Затем программа создаст канал и два дочерних процесса. Первый дочерний процесс выполнит команду, указанную в первом вводе. Он будет выводиться в конвейер вместо стандартного вывода. Второй дочерний процесс выполнит команду, указанную во втором вводе. Он будет принимать входные данные из канала, а не из стандартного ввода.Родительский процесс будет ждать завершения двух своих дочерних процессов, а затем все повторится. Выполнение остановится, когда в качестве первой команды будет введен символ «@». Вот код, который у меня есть:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){

    /* Program Termination Symbol */
    const char terminate = '@';

    /* String delimiter */
    const char delimiter = ' ';

    /* Pipe file ID's */
    int fileID[2];

    /* Parent ID's */
    int pid1, pid2;

    /* String token */
    char * token, * token2;

    /* User input */
    char * user_input, line[100];

    user_input = (char *) malloc(100);

    /* Unix Commands */
    char * command1[10], *command2[10];

    for (int i=0; i<10; i++)
    {
    command1[i] = (char *)malloc(100*sizeof(char));
    command2[i] = (char *)malloc(100*sizeof(char));
    }

    /* Begin main program logic */

    printf("Please enter the first command: \n");

    user_input = gets(line);

    while (user_input[0] != terminate)
    {
    token = (char *) malloc(100*sizeof(char));

    for (int i=0; i<10; i++)
        {
        if (i == 0)
        {
        token = strtok(user_input, &delimiter); 
        } else {
        token = strtok(NULL, &delimiter);
        }

        if (token != NULL)
        {
        strcpy(command1[i], token);
        } else {
        command1[i] = 0;
        }
        }

    printf("Please enter the second command: \n");  
    user_input = gets(line);

    token2 = (char *) malloc(100*sizeof(char));

    for (int i=0; i<10; i++)
    {
        if (i == 0)
        {
        token2 = strtok(user_input, &delimiter);
        } else {
        token2 = strtok(NULL, &delimiter);
        }

        if (token2 != NULL)
        {
        strcpy(command2[i], token2);
        } else {
        command2[i] = 0;
        }
    }   


    /* Pipe and execute user commands */

    /* Create pipe */
    pipe(fileID);

    /* Create child processes */

    pid1 = fork();

    if (pid1 != 0)
    {
        pid2 = fork();
    }

    /* First child process */
    if (pid1 == 0)
    {
        dup2(fileID[1], 1);
        execvp(command1[0], command1);
    }

    /* Second child process */
    if (pid2 == 0)
    {
        dup2(fileID[0], 0);
        execvp(command2[0], command2);
    }   

    /* Wait for children to terminate */
    wait(&pid1);
    wait(&pid2);

    /* Repeat */
        printf("Please enter the first command: \n");
    user_input = gets(line);
    }

    return 0;
}

Я столкнулся с проблемой ожидания. Если у меня есть и то, и другое, что для меня имеет смысл (одно ожидание на каждого ребенка), программа зависает после выполнения первого канала. Если я удалю второе ожидание, программа снова начнет свой цикл, но не будет принимать ввод с клавиатуры, кроме ввода, и выдаст ошибку segfault. Итак, с обоими ожиданиями ввод и вывод ...

Please enter the first command:
ls
Please enter the second command:
more
Pipe
Pipe.c
Pipe.c~

... и затем он блокируется. Если я удалю второе ожидание, ввод / вывод будет ...

Please enter the first command:
ls
Please enter the second command:
more
Pipe
Pipe.c
Pipe.c~
Please enter the first command:
(I hit enter, nothing else will work)
Segmentation fault

У кого-нибудь есть предложения? Это явно связано с ожиданием двух процессов, но я не понимаю, как с этим справиться.


Эта программа теперь на 100% работоспособна - большое вам спасибо за вашу помощь! Stack overflow был одним из лучших ресурсов в Интернете. Большое спасибо за то, что нашли время просмотреть мой код и дать мне свои предложения.

6
задан tshepang 1 May 2014 в 19:21
поделиться