РЕДАКТИРОВАТЬ: Растворпереадрессации дочернего процесса и стандартный вывод для труб
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
setvbuf(stdout,NULL,_IONBF,0);
Это SETVBUF установить стандартный вывод, чтобы быть не буфером. Несмотря на то, что я печатал символ новой строки, если пункт назначения не является фактическим экраном, я думаю, он становится буферизированным.
EDIT: Когда я ставлю fflush (стандартный вывод) после LINE 1 и fflush (FOUT) после линии 4 работает, как ожидалось. Тем не менее, он не работает без fflush (stdout) после LINE 1. Проблема в том, что я не смог бы поставить fflush в программу, которую планирую запустить.
Я пытаюсь запустить другую программу из своего процесса. У меня нет доступа к его коду, но я знаю, что он использует stdin и stdout для взаимодействия с пользователем. Я пытаюсь запустить эту программу, создав 2 трубы, разворачивая и перенаправляя дочерний stdin/stdout на соответствующие концы труб. Дело в том, что родитель должен иметь возможность общаться с ребенком через дескрипторы файлов, в то время как его stdin/stdout должен быть неповрежденным. Сценарий POPEN открывает только однонаправленную трубу. Следующий код почти работает.
Есть 4 линии, обозначенные как ЛИНИЯ 1..4.
ЛИНИЯ 1 ребенок посылает к трубе, ЛИНИЯ 2 ребенок получает от трубы, ЛИНИИ 3 родитель посылает к трубе, линии 4 родитель получает от трубы,
Это просто игрушка пример убедитесь, что все работает. Проблема заключается в том, что все 4 линий LINE1..4 являются раскомментированы выходом я вижу на терминале
PARENT1: -1
FD: 1 0 4 5 0 1
DEBUG1: 0
DEBUG2: 0
В то время как, если ЛИНИЯ 1 и ЛИНИЯ 3 являются раскомментированы только я вижу непрерывный поток данных. То же самое происходит, если только LINE 2 и LINE 4 раскоментированы. Однако мне нужна полная двунаправленная связь. Также добавление комментария SLEEP не изменяет поведение.
Что может быть проблемой здесь. Интересно, почему нет двунаправленного ПОПЕН.
int pid;
int pipes[2][2];
pipe(pipes[0]);
pipe(pipes[1]);
pid=fork();
if(pid==0)
{
//usleep(1000000);
close(pipes[0][0]);
close(pipes[1][1]);
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
//int c2=dup2(STDIN_FILENO,pipes[1][0]);
fprintf(stderr,"FD: %d %d %d %d %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO);
//FILE*fout=fdopen(pipes[0][1],"w");
//FILE*fin =fdopen(pipes[1][0],"r");
while(1)
{
static int c1=0;
fprintf(stderr,"DEBUG1: %d\n",c1);
printf("%d\n",c1); // LINE 1
fprintf(stderr,"DEBUG2: %d\n",c1);
scanf("%d",&c1); // LINE 2
fprintf(stderr,"DEBUG3: %d\n",c1);
c1++;
}
//fclose(fout);
//fclose(fin);
return 0;
}
close(pipes[0][1]);
close(pipes[1][0]);
char buffer[100];
FILE*fin=fdopen(pipes[0][0],"r");
FILE*fout=fdopen(pipes[1][1],"w");
while(1)
{
int c1=-1;
printf("PARENT1: %d\n",c1);
fscanf(fin,"%d",&c1); // LINE 3
printf("Recv: %d\n",c1);
fprintf(fout,"%d\n",c1+1); // LINE 4
printf("PARENT3: %d\n",c1+1);
}
fclose(fin);
fclose(fout);
Не стесняйтесь отвечать на свой вопрос! Вместо того, чтобы редактировать исходный вопрос с помощью своего решения, вы должны отправить его в качестве ответа, а затем принять его. –