3

編集:解決策は

 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);
4

1 に答える 1