nanosleep() replacement

Darren Tucker dtucker at
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)


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 -
       tremain.tv_sec += tremain.tv_usec / 1000000L;
       tremain.tv_usec %= 1000000L;
       TIMEVAL_TO_TIMESPEC(&tremain, rem)

       if (rc < 0) {
               rc = -1;
               errno = EINTR;

Darren Tucker (dtucker at
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