&rfdsに何が入るかがわかりません。
FD_SET(0, &rfds)で、ファイル名をキーボードから入力するのでしょうか?
rdfs
の内容は隠蔽されているので、基本、プログラマーが意識する必要はありません。FD_SET(0, &rfds)
を実行すると、標準入力であるファイルディスクリプターの0
番がrdfs
の構造体にフラグ情報として収められ、select
で監視対象として使えるようになります。
その後、select
実行中にキーボードから入力(実際はENTERキーを押し、\n
が入力)されるまで停まっています。入力が済めば、ファイルディスクリプターの0
番に変化があったことでselect
から抜けてきます。FD_ISSET
で本当に正しく0
番に変化があったことを検査してからread
すれば、入力された値を読み出すことができる、というわけです。
質問者さんのコードを少し修正して何が起こるのか分かるようにしてみましたので、読んでみてください
C
1#include <stdio.h>
2#include <sys/time.h>
3#include <sys/types.h>
4#include <unistd.h>
5
6int main(void) {
7
8 fd_set rfds;
9 struct timeval tv;
10 int retval;
11
12 /* stdin (fd 0) を監視し、入力があった場合に表示する。*/
13 FD_ZERO(&rfds);
14 FD_SET(0, &rfds);
15
16 /* 5 秒間監視する。*/
17 tv.tv_sec = 5;
18 tv.tv_usec = 0;
19
20 retval = select(1, &rfds, NULL, NULL, &tv);
21 /* この時点での tv の値を信頼してはならない。*/
22
23 if (retval == -1) {
24 perror("select()");
25 } else if (retval) {
26 printf("今、データが取得できました。\n");
27
28 /* ファイルディスクリプターの0、つまり標準入力に変化があったかをFD_ISSETで検査する。
29 ※実際はバッファリングされているので、ENTERキーを押すまで停まっている
30 */
31 int ret = FD_ISSET(0, &rfds);
32 if (ret != 0) {
33 /* ファイルディスクリプターの0、つまり標準入力に変化があった。
34 * readしてみる。
35 */
36 char s[32];
37 ssize_t read_len = read(0, s, sizeof(s) - 1);
38 if (read_len != -1) {
39 s[read_len] = '\0';
40 printf("s=[%s]\n", s);
41 }
42 }
43 } else {
44 printf("5 秒以内にデータが入力されませんでした。\n");
45 }
46
47 return 0;
48}
49
これを実行すると、以下のようになります。
sh
1$ gcc -Wall t6.c -o t6
2
3$ ./t6
4TEST STRING!!!
5今、データが取得できました。
6s=[TEST STRING!!!
7]
8$
キーボードから入力、つまり標準入力の0
番のファイルディスクリプターから読んだ"TEST STRING!!!\n"
がread
でき、出力表示されていることが分かります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/31 07:34