3

親と子のプロセスがあり、親は子から出力を読み取り、子の入力に送信できます。これまでのところ、すべてがシェル スクリプトで正常に動作しており、データを入出力するコマンドをテストしています。簡単な C プログラムでテストしたところ、動作しませんでした。Cプログラムは次のとおりです。

#include <stdio.h>

int main( void ) {
  char stuff[80];
  printf("Enter some stuff:\n");
  scanf("%s", stuff);

  return 0;
}

C プログラムの問題は、select が子 fd からの読み取りに失敗し、プログラムを終了できないことです。選択を行うビットは次のとおりです。

//wait till child is ready
fd_set set;
struct timeval timeout;

FD_ZERO( &set ); // initialize fd set
FD_SET( PARENT_READ, &set ); // add child in to set
timeout.tv_sec = 3;
timeout.tv_usec = 0;

int r = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
if( r < 1 ) { // we didn't get any input
    exit(1);
}

これがシェルプログラムではなくCプログラムで発生する理由を知っている人はいますか?

編集:子プロセスが引数で exec を呼び出すことを指摘する必要があるため、その時点以降は子プロセスにアクセスできません。

4

2 に答える 2

2

問題は、子プロセスが端末ではなくパイプに書き込んでいるため、出力を完全にバッファリングしていることです。setvbuf行バッファリングまたはバッファなしモードを強制するために使用するか、明示的fflushに then の後に子プロセスを追加するか、Expect に付属するunbufferprintfプログラムを使用して、子プロセスの libc をだましてプログラムが対話的に動作していると思わせます。

于 2010-05-03T09:50:41.717 に答える
1

C プログラムでの入力をブロックする前に、stdout をフラッシュします。

fflush(stdout);

シェルでは、これはしばしば暗黙的です。

または、 を使用setvbuf()してバッファリングを無効にする (または行バッファリングを有効にする) こともできます。これは、データが書き込まれる前に呼び出す必要があります。

setvbuf(stdout, NULL, _IONBF, 0)
于 2010-05-03T09:49:35.897 に答える