以下のプログラムを実行すると stdin の入力待ちになり、 改行を入力するとメッセージを出して終了する。 Ctrl-C (SIGINT) を送ると「detected exception; retry」と 出て継続。また一秒ごとに「timed out; retry」と 出力して select をやりなおす。
sigaction を使っているので微妙に移植性が低いかもしれない。
このディレクトリの select.c がプレーンテキスト版なので コンパイルにでも使ってほしい。
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <signal.h>
static void
noop(int signo)
{
return;
}
#define BUFSIZE 1024
int
main(int argc, char **argv)
{
char *buf[BUFSIZE];
struct sigaction act;
act.sa_handler = noop;
sigemptyset(&act.sa_mask);
#ifdef SA_RESTART
act.sa_flags = SA_RESTART;
#endif
if (sigaction(SIGINT, &act, NULL) < 0) { /* SIGINTをマスク */
fputs("sigaction errror\n", stderr);
exit(3);
}
for (;;) {
int n;
fd_set readset;
struct timeval time;
/* fd_setの準備 */
FD_ZERO(&readset);
FD_SET(STDIN_FILENO, &readset);
/* timeの準備 */
time.tv_sec = 1;
time.tv_usec = 0;
/* selectする */
n = select(STDIN_FILENO + 1, &readset, NULL, NULL, &time);
if (n > 0)
break;
/* 返り値が 0 ならタイムアウト */
if (n == 0) puts("timed out; retry");
/* 返り値が負の数なら例外 */
else if (n < 0) puts("detect exception; retry");
}
read(STDIN_FILENO, buf, BUFSIZE); /* 絶対にブロックしない */
puts("read ok");
exit(0);
}
Copyright (c) 2002 Minero Aoki
<aamine@loveruby.net>