Родительско-дочерний IPC через именованный канал: ошибка сегментации - PullRequest
0 голосов
/ 20 октября 2019

Я создаю собственную оболочку. Требование: Основной (родительский) процесс разветвляется на дочерний процесс и выполняет команду в дочернем процессе. Затем потомок делится выводом с родителем через именованный канал. Я использую вызов popen () для потомка, чтобы перехватить вывод, но не смог сообщить его родителю.

Я попробовал следующие примеры кодов, которые я нашел. Но либо программа не останавливается, либо нет чтения / записи в канал.

#include <stdio.h>
#include <fcntl.h> 
#include <stdlib.h>

#define MAXCHAR 100 // max number of characters for a command
#define PIPE "./temp" // PATH to named pipe

#define clear() printf("\033[H\033[J")

void execute(char * input) {
    pid_t pid;
    int status;

    pid = fork();

    if (pid < 0) {
        printf("Error : Could not create the child process\n");
        exit(1);
    } 
    else if (pid == 0) {
        puts("in child process now");
        FILE *fp = popen(input, "r");

        if(fp == NULL) {
            printf("...Sorry Failed to run command...\n");
            exit(1);
        }

        int fd = open(PIPE, O_CREAT | O_RDWR);

        if (fd < 0) {
            printf("cant open file");
            exit(1);
        }

        puts("Child: pipe open to write\n");

        int c = getc(fp);
        while(c != EOF) {
            putchar(c);
            write(fd, &c, 1);
            c = getc(fp);
        }

        pclose(fp);
        close(fd);
        exit(0);
    }
    else {
        while(wait(&status) != pid);
        printf("child completed\n");

        int fd = open(PIPE, O_RDWR);
        if (fd < 0) {
            printf("cant open file\n");
            exit(1);
        }
        puts("Parent: opened file for writing\n");

        char c;
        while((c = getc(fd)) != 0)
            putchar(c);

    close(fd);
    }
}

int main() {
    char inputString[MAXCHAR];

    if(mkfifo(PIPE, 0666) < 0) {
        printf("Error creating pipe!!!\n");
        exit(1);
    }

    while(1) {
        puts("SHELL > ");

        gets(inputString);
        // try again if no empty input given 
        if(strcmp(inputString, "") == 0) {
            printf("...No command provided...\n");
            continue;
        }
        if (strcmp(inputString, "exit") == 0 || strcmp(inputString, 
            "q") == 0) {
            printf("...exiting now...\n");
            break;
        }

    // execute the command
    execute(inputString);

    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...