以下のプログラムを実行すると 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>