This task is usually done using threads. In one thread getchar
is called which blocks the thread execution, another thread does sleep()
and then kills the first thread.
Another way to do this is to use non-blocking read()
from the standard input using pselect (2)
, but it's more tricky and does not suit small applications well.
Though a solution with pthreads
in unix-style is quite verbose:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
struct read_int {
int success;
int value;
struct timespec timeout;
};
void* read_thread(void *arg) {
struct read_int *s = arg;
printf("Enter a number: ");
scanf("%d", &s->value);
s->success = 1;
return NULL;
}
#define CHECK_RET(ret, func) \
if (ret) { fprintf(stderr, func"() == %d\n", ret); return ret; }
int main() {
pthread_t rthr;
pthread_attr_t thr_attr;
struct read_int s = { 0 };
int ret;
ret = clock_gettime(CLOCK_REALTIME, &s.timeout);
if (ret == -1) { fprintf(stderr, "clock_gettime() == %d\n", ret); return ret; }
s.timeout.tv_sec += 5;
ret = pthread_attr_init(&thr_attr);
CHECK_RET(ret, "pthread_attr_init");
ret = pthread_create(&rthr, &thr_attr, read_thread, &s);
CHECK_RET(ret, "pthread_create");
ret = pthread_attr_destroy(&thr_attr);
CHECK_RET(ret, "pthread_attr_destroy");
pthread_timedjoin_np(rthr, NULL, &s.timeout);
if (s.success) {
printf("\ngot value %d\n", s.value);
} else {
pthread_cancel(rthr);
printf("\nTimed out, exiting...\n\n");
}
}