Is there a way to timeout a reading from stdin in order for the program not to hang for too long ?
read(0, var, numberofbytes);
Is there a way to timeout a reading from stdin in order for the program not to hang for too long ?
read(0, var, numberofbytes);
You can use ncurses or if you don't want to, you can use select as described in this blog post. Basically, you can use select
and specify the timeout. If the stdin FD is set, then you can read from it safely and won't block. If you want more info on select, check this out and of course wikipedia. It's a handy call to know about.
EDIT: I feel compelled to supply code, so here it is, straight from the blog post with some comments.
// if != 0, then there is data to be read on stdin
int kbhit()
{
// timeout structure passed into select
struct timeval tv;
// fd_set passed into select
fd_set fds;
// Set up the timeout. here we can wait for 1 second
tv.tv_sec = 1;
tv.tv_usec = 0;
// Zero out the fd_set - make sure it's pristine
FD_ZERO(&fds);
// Set the FD that we want to read
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
// select takes the last file descriptor value + 1 in the fdset to check,
// the fdset for reads, writes, and errors. We are only passing in reads.
// the last parameter is the timeout. select will return if an FD is ready or
// the timeout has occurred
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
// return 0 if STDIN is not ready to be read.
return FD_ISSET(STDIN_FILENO, &fds);
}
Call alarm()
or ualarm()
before calling read()
. This will cause a SIGALRM
signal to be delivered to the process, interrupting the read(), provided that you haven't told the O/S to restart system calls after interrupts. Be sure to cancel the alarm if the read()
returns normally.
Use select, poll or any other IO multiplexing facility. They all take a timeout argument. Note that this will not work if stdin is a regular file, but it will if stdin is a terminal/tty,socket,pipe.
e.g.
fd_set selectset;
struct timeval timeout = {10,0}; //timeout of 10 secs.
int ret;
FD_ZERO(&selectset);
FD_SET(0,&selectset);
ret = select(1,&selectset,NULL,NULL,&timeout);
if(ret == 0)
//timeout
else if(ret == -1)
//error
else
// stdin has data, read it
// (we know stdin is readable, since we only asked for read events
//and stdin is the only fd in our select set.