Как прочитать ввод канала из другого файла?

В моей программе (main.c) я разветвляю процесс, а затем мне нужно отправить данные через канал в дочерний процесс. После системного вызова execl дочерний процесс продолжает свою жизнь в файле process.c. Установив стандартный ввод этого дочернего элемента в дескриптор файла его родителя, я пытаюсь отправить данные из родительского процесса в дочерний процесс. Но дочерний процесс не может получить никаких входных данных, и я не мог понять, почему возникает эта проблема. Спасибо заранее.

main.c

#define PIPE(fd) socketpair(AF_UNIX, SOCK_STREAM, PF_UNIX, fd)

...

char* data="data";
int fd[2];
PIPE(fd); 
write(fd[0],data,sizeof(data));

if(fork()==0){
     dup2(fd[0],0);
     close(fd[0]);
     close(fd[1]);
     execl("process","process",x,y,0);}

процесс.с

...

char* data;
read(0,data,10);
printf("%s\n",data);

person kntgu    schedule 15.03.2018    source источник
comment
fd[0] — конец канала для чтения. Вы пишете ему в родительском процессе и читаете с того же конца в дочернем процессе. Кроме того, вы записываете в него перед вызовом dup2, то есть в этот момент вы не записываете в стандартный вывод.   -  person bnaecker    schedule 15.03.2018
comment
Я использую двунаправленные каналы.   -  person kntgu    schedule 15.03.2018
comment
Трубы по определению являются однонаправленными. Что делает PIPE? Это создание пары каналов, пары сокетов или какого-либо другого механизма двунаправленной связи?   -  person bnaecker    schedule 15.03.2018
comment
Отредактировал мой вопрос...   -  person kntgu    schedule 15.03.2018
comment
Вы по-прежнему пишете и читаете из одного и того же сокета, fd[0]. Данные, записанные на fd[0], будут считаны с fd[1] и наоборот. Кроме того, вам нужно выделить некоторое пространство, используя что-то вроде char* data = malloc(10); в дочернем процессе, иначе вы читаете данные в неопределенную область памяти.   -  person bnaecker    schedule 15.03.2018
comment
Большое спасибо за ваш ответ, я просто пропустил чтение и запись данных в разных частях дескрипторов.   -  person kntgu    schedule 15.03.2018


Ответы (1)


Вы читаете и пишете на одном сокете.

Создание пары сокетов с использованием socketpair(2) позволяет вам взаимодействовать в двух направлениях, так что данные, записанные в первый сокет, считываются из второго, и наоборот.

Здесь fd[0] относится к одному и тому же сокету в родительском и дочернем процессах, поэтому родитель пишет в первый сокет, а дочерний пытается читать из того же сокета. Данные, которые родитель записывает, появятся во втором сокете, в данном случае fd[1].

Итак, вам нужно сделать:

dup2(fd[1], 0); // make stdin of the child refer to the *second* socket

а также

char data[11] = {'\0'}; // make sure to allocate space
read(STDIN_FILENO, data, sizeof(data) - 1);
person bnaecker    schedule 15.03.2018