Reputation: 97
So i made this function which acts like a countdown.I want to read a command while the countdown decreases. My big problem is making read()
the wait for a input while countdown is decreasing.As you can see I tried using select()
but after the first printf("timeout.\n");
it stops trying to read. I made the show only once timeout
or else it would go until countdown reached 0. I need to try read again.
int timer(int seconds)
{
time_t start, end;
double elapsed;
int opened=0;
char command[10];
struct timeval tv;
int fd_stdin,rv;
fd_set rd;
fd_stdin=fileno(stdin);
FD_ZERO(&rd);
FD_SET(fileno(stdin),&rd);
tv.tv_sec=5;
tv.tv_usec=0;
time(&start); /* start the timer */
do
{
time(&end);
elapsed = difftime(end, start);
if(fmod(elapsed,5)==0)
{
printf("Time remaining: %f minutes.\n", (seconds-elapsed)/60);
sleep(1);
if(opened==0)
{
printf("Use opentest to open your test.\n");
opened=1;
}
fflush(stdout);
}
int c;
rv=select(fd_stdin+1,&rd,NULL,NULL,&tv);
if(rv==-1)
{
perror("Error on select.\n");
exit(1);
}
else if (rv==0 && c!=1)
{
printf("timeout.\n");
rv=select(fd_stdin+1,&rd,NULL,NULL,&tv);
c=1;
}
else
{
c=0;
read(fd_stdin,command,10);
}
}
while(elapsed < seconds);
return 0;
}
EDIT: to use the fmod()
function , I compile like this: gcc client.c -lm -o client.exe
. I don`t think this is the problem but I am not sure.
Upvotes: 1
Views: 393
Reputation: 597941
select()
modifies the fd_set
upon exit to reflect which descriptors have been signaled. You are not resetting the fd_set
after each timeout.
Also, on some platforms, select()
modifies the timeval
structure to reflect how much time is remaining, so you would have to reset the timeval
each time you call select()
on those platforms.
Also, your c
variable is declared inside the loop and is uninitialized. Move it outside the loop instead.
Try something more like this:
int timer(int seconds)
{
time_t start, end;
double elapsed;
int opened = 0;
char command[10];
struct timeval tv;
int fd_stdin, rv;
fd_set rd;
int c = 0;
fd_stdin = fileno(stdin);
time(&start); /* start the timer */
do
{
time(&end);
elapsed = difftime(end, start);
if (fmod(elapsed, 5) == 0)
{
printf("Time remaining: %f minutes.\n", (seconds-elapsed)/60);
sleep(1);
if (opened == 0)
{
printf("Use opentest to open your test.\n");
opened = 1;
}
fflush(stdout);
}
FD_ZERO(&rd);
FD_SET(fd_stdin, &rd);
tv.tv_sec = 5;
tv.tv_usec = 0;
rv = select(fd_stdin+1, &rd, NULL, NULL, &tv);
if (rv == -1)
{
perror("Error on select.\n");
exit(1);
}
else if (rv == 0)
{
if (c != 1)
{
printf("timeout.\n");
c = 1;
}
}
else
{
c = 0;
read(fd_stdin, command, 10);
}
}
while (elapsed < seconds);
return 0;
}
Upvotes: 1