Наиболее распространенная причина этого заключается в том, что вы не закрываете конец записи канала, поэтому EOF никогда не отправляется.Типичный пример - когда у вас есть код, который выглядит следующим образом:
int fds[2];
pipe(fds); // open a pipe
if (fork()) {
// parent process
write(fds[1], ... // write data
close(fds[1]); // close it
} else {
// child process
while (read(fds[0], ....) > 0) {
// read until EOF
Проблема здесь в том, что конец записи канала никогда не закрывается - родительский процесс закрывает его, но дочерний процесс все еще имеет записьдескриптор открыт.Таким образом, ребенок никогда не видит EOF в дескрипторе чтения.
Самое первое, что вам нужно сделать после разветвления ребенка, - это close(fds[1]);
, закрывая свою копию дескриптора записи.Таким образом, когда родитель закрывает последнюю оставшуюся ссылку на конец записи канала, дочерний элемент увидит EOF на конце чтения.
Edit
, глядя нассылка, которую вы добавили, это как раз и есть проблема - у дочернего элемента все еще есть конец записи канала, открытый на его стандартный вывод.Не дублируйте конец записи в stdout у ребенка, просто закройте его.Отправьте стандартный вывод куда-нибудь еще (файл журнала или / dev / null)
Редактировать
для двунаправленной связи, вам понадобятся два канала:
int tochild[2], fromchild[2];
pipe(tochild); pipe(fromchild);
if (fork()) {
close(tochild[0]);
close(fromchild[1]);
//write to tochild[1] and read from fromchild[0]
} else {
dup2(tochild[0], 0);
dup2(fromchild[1], 1);
close(tochild[0]); close(tochild[1]);
close(fromchild[0]); close(fromchild[1]);
exec(...
}
Вы должны быть очень осторожны, записывая данные в родительском, однако - если есть много данных, которые нужно отправить ребенку, вы не можете отправить все это до прочтения вывода ребенка, или вы можете зайти в тупик(оба канала заполняются, и родительские блоки пытаются записать больше данных для дочернего, в то время как дочерние блоки пытаются вывести).Вам нужно использовать poll или select, чтобы указать, когда есть данные для чтения или место для записи, и вы можете перевести каналы (по крайней мере, родительский конец) в неблокирующий режим.