From owner-cvs-all Sat Sep 5 11:18:15 1998 Return-Path: Received: (from daemon@localhost) by hub.freebsd.org (8.8.8/8.8.8) id LAA27168 for cvs-all-outgoing; Sat, 5 Sep 1998 11:18:15 -0700 (PDT) (envelope-from owner-cvs-all) Received: from apollo.backplane.com (apollo.backplane.com [209.157.86.2]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id LAA27102; Sat, 5 Sep 1998 11:17:58 -0700 (PDT) (envelope-from dillon@backplane.com) Received: (dillon@localhost) by apollo.backplane.com (8.8.8/8.6.5) id LAA22705; Sat, 5 Sep 1998 11:16:49 -0700 (PDT) Date: Sat, 5 Sep 1998 11:16:49 -0700 (PDT) From: Matthew Dillon Message-Id: <199809051816.LAA22705@apollo.backplane.com> To: Doug Rabson Cc: "Andrey A. Chernov" , John Birrell , cvs-committers@FreeBSD.ORG, cvs-all@FreeBSD.ORG Subject: Re: cvs commit: src/lib/libc/gen sleep.c References: Sender: owner-cvs-all@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk 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. (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 : :