パイプからデータを受け取っているときにstdinで使用されたときのselect()の振る舞いについての理解を理解しようとしています。パイプ上でstdinを使用したときのselect()の動作
は基本的に私は次のコードを使用して簡単なCプログラムを持っていた: のhello.c:次のように私はプログラムを実行した場合、私はプログラムの実行中にキーを入力すると
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <termios.h>
int main(int argc, char *argv[])
{
int flags, opt;
int nsecs, tfnd;
fd_set rfds;
struct timeval tv;
int retval;
int stdin_fileno_p1 = STDIN_FILENO+1;
char c;
int n;
/* Turn off canonical processing on stdin*/
static struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
while (1)
{
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(stdin_fileno_p1, &rfds, NULL, NULL, &tv);
if (retval && (retval!=-1))
{
n = read(STDIN_FILENO, &c, 1);
write(STDOUT_FILENO, &c, 1);
}
else printf("No Data\n");
usleep(100000);
}
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
}
私はエコー文字を見ることができました。キーを押さないと、「No Data」と表示されます。
./hello
ただし、プログラムを次のように使用すると、プログラムは「データなし」と表示されることはありません。代わりに最後の文字「c」が繰り返し表示されます。
echo -n abc | ./hello
私はこの観察に困惑し、観察された動作を理解するのを助けることができれば感謝します。
ありがとうございました。これは、fdが閉じたファイルを参照するときにselect()がエラー条件(-1)を返さないことを意味しますか? – ubndra
記述子のいずれかが閉じたファイルを参照する場合、 'select'は-1を返します。あなたのプログラムのSTDIN記述子を決して閉じないので、あなたのプログラムでは起こりません。 'read'が0を返すときに' close(STDIN_FILENO) 'を実行してループの中にいれば、次の' select'呼び出しから-1が表示されます。 ( 'echo'プログラムでパイプの書き込み側で実行される' close'は、プログラム内のパイプの読み込み側を閉じません。プログラム内の 'read'に対する 'end of file' 。) – ottomeister