nanosleep() replacement
Darren Tucker
dtucker at zip.com.au
Mon Mar 17 22:16:50 EST 2003
Darren Tucker wrote:
> Tim Rice wrote:
> > I put together a nanosleep() for systems without it.
> >
> > Please review/test before I commit.
>
> I can confirm that this works on Solaris 8 (configured without librt,
> which is where nanosleep is), however it doesn't seem to cope well with
> the lower limits.
This turned out to be because select() is interrupted by SIGALRM and the
replacement function does not set errno in this case (gettimeofday
resets errno after the select). Scp checks errno for EINTR.
The higher speeds were less affected because they had less chance of
being interrupted.
I did some fiddling and got pretty close to the real nanosleep with the
modified function below.
limit nanosleep bsd-misc orig bsd-misc modified
1 1 30 1
8 8 48 8
64 64 66 61
128 129 130 129
256 255 255 256
(all kbits/sec, calculated from kbytes/sec reported by scp)
-Daz.
int nanosleep(const struct timespec *req, struct timespec *rem)
{
int rc;
extern int errno;
struct timeval tstart, tstop, tremain, time2wait;
TIMESPEC_TO_TIMEVAL(&time2wait, req)
gettimeofday(&tstart, NULL);
rc = select(0, NULL, NULL, NULL, &time2wait);
gettimeofday (&tstop, NULL);
tremain.tv_sec = tstop.tv_sec - tstart.tv_sec - time2wait.tv_sec;
tremain.tv_usec = tstop.tv_usec - tstart.tv_usec -
time2wait.tv_usec;
tremain.tv_sec += tremain.tv_usec / 1000000L;
tremain.tv_usec %= 1000000L;
TIMEVAL_TO_TIMESPEC(&tremain, rem)
if (rc < 0) {
rc = -1;
errno = EINTR;
}
return(rc);
}
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
More information about the openssh-unix-dev
mailing list