Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Sep 1998 11:16:49 -0700 (PDT)
From:      Matthew Dillon <dillon@backplane.com>
To:        Doug Rabson <dfr@nlsystems.com>
Cc:        "Andrey A. Chernov" <ache@nagual.pp.ru>, John Birrell <jb@FreeBSD.ORG>, cvs-committers@FreeBSD.ORG, cvs-all@FreeBSD.ORG
Subject:   Re: cvs commit: src/lib/libc/gen sleep.c
Message-ID:  <199809051816.LAA22705@apollo.backplane.com>
References:   <Pine.BSF.4.01.9809051454130.360-100000@herring.nlsystems.com>

next in thread | previous in thread | raw e-mail | index | archive | help
    The sleep code is totally broken in regards to its comparisons.  The
    argument is an unsigned int, but values are stored in time_t which is
    currently a signed long.  The code, as it stands, is not clean if either
    time_t changes from signed to unsigned, or if time_t changes from a 32 bit
    value to a 64 bit value.  Since there is no harm in doing multiple 
    sleeps, why not just fix the code?  We no tv_sec must be at least large
    enough to hold INT_MAX, so:

    unsigned int
    sleep(seconds)
	unsigned int seconds;
    {
	while (seconds != 0) {
	    struct timespec time_to_sleep;
	    struct timespec time_remaining;

	    time_to_sleep.tv_sec  = (seconds > INT_MAX) ? INT_MAX : seconds;
	    time_to_sleep.tv_nsec = 0;

	    if (nanosleep(&time_to_sleep, &time_remaining) == -1) {
		/*
		 * time_remaining only valid if EINTR, else assume no
		 * time elapsed.
		 */
		if (errno == EINTR)
		    seconds -= time_to_sleep.tv_sec - time_remaining.tv_sec;
		    if (time_remaining.tv_nsec)
			++seconds;
		break;
	    }
	    seconds -= time_to_sleep.tv_sec;
	}
	return(seconds);
    }

						-Matt

    Matthew Dillon  Engineering, HiWay Technologies, Inc. & BEST Internet 
                    Communications & God knows what else.
    <dillon@backplane.com> (Please include original email in any response)    

:> >   Modified files:
:> >     lib/libc/gen         sleep.c 
:> >   Log:
:> >   Use INT_MAX instead of LONG_MAX since the variable being compared
:> >   is an int, not a long.
:> 
:> 
:> Please back it out, the test covers the case when 
:> sizeof(unsigned) == sizeof(long) and prevents to overflow signed long with
:> unsigned value.
:
:Something needs to change here.  LONG_MAX is too big to compare against an
:int and generates a warning on the alpha.  Maybe compare against UINT_MAX?
:
:--
:Doug Rabson				Mail:  dfr@nlsystems.com
:Nonlinear Systems Ltd.			Phone: +44 181 951 1891
					Fax:   +44 181 381 1039
:					Fax:   +44 181 381 1039
:
:




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199809051816.LAA22705>