An approach for *IX'ish systems (including Cygwin on windows):
You could use alarm()
to schedule a SIGALRM
, then use read(fileno(stdin), ...)
.
When the signal arrives read()
shall return with -1
and had set errno
to EINTR
.
Example:
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
alarm(2); /* Set alarm to occur in two seconds. */
{
char buffer[16] = { 0 };
int result = read(fileno(stdin), buffer, sizeof(buffer) - 1);
if (-1 == result)
{
if (EINTR != errno)
{
perror("read() failed");
exit(EXIT_FAILURE);
}
printf("Game over!
");
}
else
{
alarm(0); /* Switch of alarm. */
printf("You entered '%s'
", buffer);
}
}
return EXIT_SUCCESS;
}
Note: In the example above the blocking call to read()
would be interupted on any signal arriving. The code to avoid this is left as an execise to the reader ... :-)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…