|
リニューアル
サイトリニューアル中です。本ページは以下URLへ移動しました。
Prog.さな雑記
関数仕様
- 機能
複数のファイルディスクリプタを同時に監視する
- 書式
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
|
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select (int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
void FD_CLR (int fd, fd_set *fds);
int FD_ISSET (int fd, fd_set *fds);
void FD_SET (int fd, fd_set *fds);
void FD_ZERO (fd_set *fds);
|
- 引数
引数名 | 説明 |
---|
nfds | 3つの集合(readfds,writefds,exceptfds)に含まれるファイルディスクリプタの最大値に 1 を足したもの | readfds | 読み出しが可能かどうかを監視するファイルディスクリプタの集合へのポインタ or NULL | writefds | 書込みが可能かどうかを監視するファイルディスクリプタの集合へのポインタ or NULL | exceptfds | 例外が発生したかどうかを監視するファイルディスクリプタの集合へのポインタ or NULL | timerout | Timeout になる時間を指定する timeval 構造体へのポインタ (NULL の場合は無期限) | fds | ファイルディスクリプタの集合へのポインタ | fd | ファイルディスクリプタ |
- 戻り値
正の値 : 変化があったファイルディスクリプタの総数(readfds,writefds,exceptfds)
0 : Timeout
-1 : エラーが発生
- エラー
errno | 内容 |
---|
EBADF | 何れかの集合に無効なファイルディスクリプタが指定された | EINTR | シグナルを受信した | EINVAL | timeout に入っている値を含め、値が不正である | ENOMEM | 内部テーブルにメモリを割り当てることができなかった |
集合を扱う為のマクロ
関数名 | 内容 |
---|
FD_CLR () | 集合(fds)にセットされているファイルディスクリプタ(fd)を、集合から削除する | FD_ISSET () | 集合(fds)にファイルディスクリプタがあるかどうか調べる。このマクロは select() が終了した後に使うと便利 | FD_SET () | 集合(fds)に、ファイルディスクリプタ(fd)をセットする | FD_ZERO () | 集合(fds)を削除する |
注意
Linux では、select() は timeout を変更し、
残りの停止時間を反映するようになっている。
しかし、他のほとんどの実装はこのようになっていない
(POSIX.1-2001はどちらの動作も認めている)。
このため、timeout を参照している Linux のコードを
他の OS へ移植する場合、問題が起こる。
select() から復帰した後、timeout は未定義であると考えるべきである。
サンプル
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
-
|
|
|
|
|
|
|
|
|
-
|
!
|
|
|
-
|
!
|
|
-
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
!
|
-
|
!
|
-
|
-
|
!
|
-
|
!
!
!
|
|
|
|
|
|
|
|
|
|
|
!
| #include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define MYSQL_SOCKET "/tmp/mysql.sock"
#define CLAMD_SOCKET "/tmp/clamd.sock"
#define max(a,b) ((a >= b) ? a : b)
int
main (void)
{
int mysql_fd = -1;
int clamd_fd = -1;
int maxfd = -1;
fd_set fds;
struct timeval tv;
int ret;
mysql_fd = open (MYSQL_SOCKET, O_RDONLY);
if (mysql_fd < 0)
{
goto error;
}
clamd_fd = open (CLAMD_SOCKET, O_RDONLY);
if (clamd_fd < 0)
{
goto error;
}
while (1)
{
FD_ZERO (&fds);
FD_SET (mysql_fd, &fds);
maxfd = max (maxfd, mysql_fd);
FD_SET (clamd_fd, &fds);
maxfd = max (maxfd, clamd_fd);
tv.tv_sec = 5;
tv.tv_usec = 0;
ret = select (maxfd + 1, &fds, NULL, NULL, &tv);
if (ret < 0)
{
if (errno == EINTR)
continue;
else
goto error;
}
else if (ret == 0)
{
continue;
}
else
{
if (FD_ISSET (mysql_fd, &fds))
{
}
if (FD_ISSET (clamd_fd, &fds))
{
}
}
}
close (mysql_fd);
close (clamd_fd);
_exit (0);
error:
if (mysql_fd >= 0)
close (mysql_fd);
if (clamd_fd >= 0)
close (clamd_fd);
_exit (1);
}
|
|
|