You can use the following sample programs to replace sleep and select.
This sample replacement program for sleep guarantees to sleep for the specified interval, even if interrupted.
sleep example
#include <errno.h>
#include <sys/time.h>
int SLEEP(int amount)
{
struct timestruc_t Requested, Remaining;
double famount = amount;
int rc;
while (famount > 0.0) {
Requested.tv_sec = (unsigned long) famount;
Requested.tv_nsec =
(int) ((famount - Requested.tv_sec)*1000000000.);
rc = nsleep ( &Requested, &Remaining );
if ((rc == -1) && (errno == EINTR)) {
/* Sleep interrupted. Resume it */
famount = Remaining.tv_sec + Remaining.tv_nsec /
1000000000.;
continue;
}
else /* Completed sleep. Set return to zero */
{
return (0);
}
} /* end of while */
/* famount = 0; exit */
return (0);
}
This sample replacement program for select restores the status of the file descriptor bit masks and handles the remaining time after an interrupt.
select example
#include <stdio.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
int SELECT(int maxfds, fd_set *reads, fd_set *writes, fd_set *errors,
struct timeval *timeout)
{
struct timestruc_t Timer1, Timer2;
struct timeval timetogo;
static fd_set readcopy;
static fd_set writecopy;
static fd_set errcopy;
int rc;
double worktime;
double remaining;
/* If we get interrupted, will need to restore select bits */
if (reads) bcopy(reads,&readcopy,sizeof(fd_set));
if (writes) bcopy(writes,&writecopy,sizeof(fd_set));
if (errors) bcopy(errors,&errcopy,sizeof(fd_set));
/* two cases: if timeout specifies a time structure, we
need to worry about timeouts. Otherwise, we can
ignore it */
if (timeout == NULL) {
while (TRUE) {
rc = select(maxfds,reads,writes,errors,NULL);
if ((rc == -1) && (errno == EINTR)) { /* interrupted */
if (reads) bcopy(&readcopy,reads,sizeof(fd_set));
if (writes) bcopy(&writecopy,writes,sizeof(fd_set));
if (errors) bcopy(&errcopy,errors,sizeof(fd_set));
continue;
}
else return(rc);
}
}
else { /* timeout is not null */
timetogo.tv_sec = timeout->tv_sec;
timetogo.tv_usec = timeout->tv_usec;
remaining = timetogo.tv_sec + timetogo.tv_usec/1000000.;
/*
fprintf(stderr,"remaining time = %f\n",remaining);
fflush(stderr);
*/
gettimer(TIMEOFDAY, &Timer2);
while (TRUE) {
Timer1.tv_sec = Timer2.tv_sec;
Timer1.tv_nsec = Timer2.tv_nsec;
rc = select(maxfds,reads,writes,errors,&timetogo);
if ((rc == -1) && (errno == EINTR)) { /* interrupted */
gettimer(TIMEOFDAY, &Timer2);
/* compute amount remaining */
worktime = (Timer2.tv_sec - Timer1.tv_sec) +
(Timer2.tv_nsec - Timer1.tv_nsec)/1000000000.;
remaining = remaining - worktime;
timetogo.tv_sec = (long) remaining;
timetogo.tv_usec = (int) ((remaining - timetogo.tv_sec)*
1000000.);
/* restore the select bits */
if (reads) bcopy(&readcopy,reads,sizeof(fd_set));
if (writes) bcopy(&writecopy,writes,sizeof(fd_set));
if (errors) bcopy(&errcopy,errors,sizeof(fd_set));
continue;
}
else return(rc);
}
}
}