В родительском файле может быть только один стандартный дескриптор входного файла и один стандартный дескриптор выходного файла. Ваш код выглядит следующим образом:
for (int i = 0; i < n; i++){
Pipe(fd[i]);
if (fork() == 0){
close(fd[i][0]);
dup2(fd[i][1], 0);
dup2(fd[i][1], 1);
close(fd[i][1]);
execv(code, arguments);
}
else {
close(fd[i][1]);
dup2(fd[i][0], 0);
dup2(fd[i][0], 1);
close(fd[i][0]);
}
…poll setup…
}
Это тщательно сбрасывает стандартный ввод и стандартный вывод в родительский элемент при каждом создании дочернего элемента, оставляя программу только с подключением к последнему дочернему элементу.
Вы не должны использовать dup2()
в родителях; вам, вероятно, нужно держать дескрипторы файлов открытыми в массиве, чтобы использовать их для отдельного общения с детьми.
Я не рассмотрел, почему вы используете индексы [0]
и [1]
после fd[i]
как вы, но это не так.
Вы должны поставить как минимум exit(1);
или _exit(1);
после вызова execv()
; Я бы предпочел, чтобы сообщение об ошибке выводилось также на stderr
, сообщая о сбое execv()
. Вам не нужно проверять возвращаемое значение; если execv()
возвращается, это не удалось; если это удастся, он не вернется. В противном случае, если execv()
завершится неудачно, вы можете получить несколько процессов, все они думают, что они являются родителями. Это приводит к хаосу. Всегда следите за тем, чтобы не выполнять другие программы!