編集:解決策は
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
setvbuf(stdout,NULL,_IONBF,0);
stdout を非バッファに設定するのは SETVBUF です。宛先が実際の画面でない場合は改行文字を出力していましたが、バッファリングされると思います。
編集: LINE 1 の後にfflush(stdout)を配置し、LINE 4 の後にfflush(fout)を配置すると、期待どおりに動作します。ただし、LINE 1 の後にfflush(stdout)がないと機能しません。問題は、実行しようとしているプログラムにfflushを配置できないことです。
自分のプロセスから別のプログラムを開始しようとしています。私はそのコードにアクセスできませんが、ユーザーとのやり取りに stdin と stdout を使用していることは知っています。2 つのパイプを作成し、フォークして、子の stdin/stdout を適切なパイプの端にリダイレクトすることで、そのプログラムを開始しようとしています。ポイントは、親がファイル記述子を介して子と通信できる必要がある一方で、stdin/stdout はそのままである必要があるということです。POPEN syscall は単方向パイプのみを開きます。次のコードはほとんど機能します。
LINE 1..4 としてマークされた 4 つの行があります。
LINE 1 はパイプに送信する子、LINE 2 はパイプから受信する子、LINE 3 はパイプに送信する親、LINE 4 はパイプから受信する親、
これは、動作を確認するためのおもちゃの例にすぎません。問題は、LINE1..4 の 4 行すべてがコメント解除されていることです。端末に表示される出力は次のとおりです。
PARENT1: -1
FD: 1 0 4 5 0 1
DEBUG1: 0
DEBUG2: 0
LINE 1 と LINE 3 のみがコメント解除されている場合、連続したデータ ストリームが表示されます。LINE 2 と LINE 4 だけをコメント解除した場合も同様です。ただし、完全な双方向通信が必要です。また、コメント付きの SLEEP を追加しても動作は変わりません。
ここで何が問題になる可能性がありますか。なぜ双方向 POPEN がないのだろうか。
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);