Двухстороннее общение между родителем и ребенком с использованием двух каналов в C на Linux - PullRequest
3 голосов
/ 16 февраля 2012

Я пытаюсь создать двустороннюю связь между родительским и дочерним процессами, используя 2 канала, используя C в Linux.Родитель - это моя программа, а ребенок - просто случайная программа (скажем, «кошка»).

Я пытаюсь использовать read() в родительском элементе для чтения дочернего вывода, но это дает мне errno 9, что плоходескриптор файла.

Вот мой код

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

#define Read            0
#define Write           1
#define ParentRead      read_pipe[1]
#define ParentWrite     write_pipe[0]
#define ChildRead       write_pipe[1]
#define ChildWrite      read_pipe[0]

int main()
{
    int data_processed;

    /** Pipe for reading for subprocess */
    int read_pipe[2];
    /** Pipe for writing to subprocess */
    int write_pipe[2];

    char buffer[100];
    memset(buffer, '\0', 100);

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0)
    {
        pid_t pid = fork();
        if (pid == (pid_t)-1)
        {
            fprintf(stderr, "Fork failure");
            exit(EXIT_FAILURE);
        }
        else if (pid == (pid_t)0) //Child process
        {
            close(Read);
            close(Write);
            close(ParentRead);
            close(ParentWrite);
            dup(ChildRead);
            dup(ChildWrite);
            execlp("cat", (char*)NULL);
            exit(EXIT_FAILURE);
        }
        else { //Parent process
            close(ChildRead);
            close(ChildWrite);

            write(ParentWrite, "abc", 3);
            int r = read(ParentRead, buffer, 99);
            printf("%d %d", r, errno);
            puts(buffer);
        }
    }

    exit(EXIT_SUCCESS);
}

Ответы [ 2 ]

2 голосов
/ 17 февраля 2012

Если вы хотите перенаправить stdin и stdout на каналы, вам нужно использовать системный вызов dup2 (2).

dup2 (ChildRead, 0);
dup2 (ChildWrite, 1);

PS Также я нашел неправильные направления чтения / записи в каналах.Вот правильный путь

#define ParentRead      read_pipe[0]
#define ParentWrite     write_pipe[1]
#define ChildRead       write_pipe[0]
#define ChildWrite      read_pipe[1]

Помните: pipe [0] - это fd для чтения, pipe [1] - это fd для записи.

И еще одна ошибка в execlp.Не забудьте установить первый аргумент, который вы отправляете в исполняемую программу, как имя программы

execlp("cat", "cat", (char*)NULL);
0 голосов
/ 17 февраля 2012

Что произойдет, если вы просто выполните чтение / запись? Я не уверен, что dup и cat - вот что вам нужно, если честно:

char buf[256];
int len;

len = read(ChildRead, 256);
write(ChildWrite, len);

И, если подумать, если вы знаете, на каком fd вы хотите оказаться, используйте dup2, а не dup. Знайте свои API, люди!

И, подумав еще дальше, вы можете посмотреть на источник вызова popen (3), который делает именно это, в более общем смысле.

...