From archie@whistle.com  Tue May 30 13:41:56 2000
Return-Path: <archie@whistle.com>
Received: from bubba.whistle.com (bubba.whistle.com [207.76.205.7])
	by hub.freebsd.org (Postfix) with ESMTP id 2FDAD37BD7B
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 30 May 2000 13:41:54 -0700 (PDT)
	(envelope-from archie@whistle.com)
Received: (from archie@localhost)
	by bubba.whistle.com (8.9.3/8.9.2) id NAA34482;
	Tue, 30 May 2000 13:41:53 -0700 (PDT)
Message-Id: <200005302041.NAA34482@bubba.whistle.com>
Date: Tue, 30 May 2000 13:41:53 -0700 (PDT)
From: Archie Cobbs <archie@whistle.com>
Reply-To: archie@whistle.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: select(2) timeout limited to 100000000 seconds
X-Send-Pr-Version: 3.2

>Number:         18909
>Category:       kern
>Synopsis:       select(2) timeout limited to 100000000 seconds
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 30 13:50:00 PDT 2000
>Closed-Date:    
>Last-Modified:  Tue Jul 10 03:41:37 UTC 2012
>Originator:     Archie Cobbs
>Release:        FreeBSD 3.4-RELEASE i386
>Organization:
Whistle Communications, Inc.
>Environment:

	3.4-REL, 4.0-stable, 5.0-current

>Description:

	select(2) returns EINVAL if the timeout is specified for
	longer than 100000000 seconds.

	Is this according to some specification? If so, nevermind,
	but please document this limitation in the man page. As it
	stands, there's nothing in the man page that indicates there
	is such an arbitrary limitation.

	Otherwise, it should support up to the maximum possible value
	that can be specified in a struct timeval.

>How-To-Repeat:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <err.h>

void
main(int ac, char *av[]) {
	struct timeval tv;
	fd_set fds;
	int r;

	switch (ac) {
	default:
		errx(1, "usage: xx [secs]");
	case 2:
		tv.tv_sec = strtol(av[1], 0, NULL);
		break;
	case 1:
		tv.tv_sec = 100000001;
		break;
	}
	tv.tv_usec = 0;

	FD_ZERO(&fds);
	FD_SET(0, &fds);

	r = select(1, &fds, NULL, NULL, &tv);
	if (r < 0)
		err(1, "select");
}


>Fix:

	Either allow all valid struct timeval's, or else please
	document this shortcoming in the man page.


>Release-Note:
>Audit-Trail:

From: David Malone <dwmalone@maths.tcd.ie>
To: freebsd-gnats-submit@FreeBSD.org, archie@whistle.com
Cc:  
Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds
Date: Tue, 30 May 2000 23:15:20 +0100

 Here is what "The Single UNIX  Specification, Version 2" that I
 downloaded about a year ago says:
 
      Implementations may place limitations on the maximum timeout
      interval supported. On all implementations, the maximum timeout
      interval supported will be at least 31 days. If the timeout
      argument specifies a timeout interval greater than the
      implementation-dependent maximum value, the maximum value will be
      used as the actual timeout value. Implementations may also place
      limitations on the granularity of timeout intervals. If the
      requested timeout interval requires a finer granularity than the
      implementation supports, the actual timeout interval will be
      rounded up to the next supported value.
 
 So it looks the implimentation doesn't agree with this, and the
 man page should probably say what the max timeout is.
 
 (Excerpt is from http://www.opennc.org/onlinepubs/7908799/xsh/select.html).
 
 	David.
 

From: Bruce Evans <bde@zeta.org.au>
To: Kelly Yancey <kbyanc@posi.net>
Cc: David Malone <dwmalone@maths.tcd.ie>,
	freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds
Date: Wed, 31 May 2000 16:58:20 +1000 (EST)

 Everything that is implemented using itimers has this limit.  The limit
 is only documented explicitly in setitimer.2, alarm.3 and ualarm.3.
 
 The possible existence of a limit is documented in select.2:
 
      [EINVAL]		The specified time limit is invalid.  One of its com-
 			ponents is negative or too large.
 
 Saying exactly which values are too large in the man page wouldn't be very
 useful.  Programs (sic) would have to read the man page to determine the
 limit, since it would be machine-dependent.  A limit reported by sysconf(2)
 would be more useful, but there is no standard for this.
 
 The limit of 10^8 seconds is imposed to reduce the chance of overflows
 in computations involving itimers.  Note that timeouts of 10^8 seconds
 don't actually work, at least for select().  10^8 seconds is 1157+
 days, by the default configuration of HZ = 100, timeouts in 32-bit
 ticks are limited to only 248+ days.  If you increase HZ to 10^5 then
 you may even notice this bug :-).
 
 On Tue, 30 May 2000, Kelly Yancey wrote:
 
 > On Tue, 30 May 2000, David Malone wrote:
 
 > >  Here is what "The Single UNIX  Specification, Version 2" that I
 > >  downloaded about a year ago says:
 > >  
 > >       Implementations may place limitations on the maximum timeout
 > >       interval supported. On all implementations, the maximum timeout
 > >       interval supported will be at least 31 days. If the timeout
 
 Setting HZ to More than about 800 will break this.  There are many possible
 problems like this, so nonstandard values of HZ aren't really supported.
 
 > >       argument specifies a timeout interval greater than the
 > >       implementation-dependent maximum value, the maximum value will be
 > >       used as the actual timeout value. Implementations may also place
 > >       limitations on the granularity of timeout intervals. If the
 > >       requested timeout interval requires a finer granularity than the
 > >       implementation supports, the actual timeout interval will be
 > >       rounded up to the next supported value.
 > >  
 > >  So it looks the implimentation doesn't agree with this, and the
 > >  man page should probably say what the max timeout is.
 > >  
 > >  (Excerpt is from http://www.opennc.org/onlinepubs/7908799/xsh/select.html).
 > >  
 > 
 >   I read this to say that returning EINVAL (as reported in the submitted
 > PR) is the Wrong Thing and that we should be rounding the interval down
 > instead. The culprit is kern_time.c:itimerfix which is called by select,
 
 I read this as a bug in the SUS :-).  The easiest workaround is to not
 have a limit.  It seems to be easy to fix for select() and poll(), since
 there is already a loop where we check after some wakeups to see if the
 timeout expired (see old fixes for this problem in nanosleep()).
 
 >   So someone more wise will definately need to review this (simple) patch
 > as it may have far-reaching affects.
 
 It affects setitimer(), etc.  The SUS requires setitimer() and alarm() to
 handle the full interval.  POSIX requires this for alarm() IIRC.
 
 Bruce
 
 

From: David Malone <dwmalone@maths.tcd.ie>
To: Bruce Evans <bde@zeta.org.au>
Cc: Kelly Yancey <kbyanc@posi.net>, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds 
Date: Wed, 07 Jun 2000 22:37:57 +0100

 > Everything that is implemented using itimers has this limit.  The limit
 > is only documented explicitly in setitimer.2, alarm.3 and ualarm.3.
 
 Unless I'm mistaken, select (and poll and the kevent stuff) don't
 actually have anything to do with itimers, as the implementation
 of their timeouts is with tsleep, which uses timeout, which uses
 callouts. They are just borrowing the itimerfix() function for
 a use for which it wasn't intended?
 
 Probably what is needed is a timevalisvalid() function. There is
 already a (static) timevalfix() function, however it doesn't do
 what is required here.
 
 > The limit of 10^8 seconds is imposed to reduce the chance of overflows
 > in computations involving itimers.  Note that timeouts of 10^8 seconds
 > don't actually work, at least for select().  10^8 seconds is 1157+
 > days, by the default configuration of HZ = 100, timeouts in 32-bit
 > ticks are limited to only 248+ days.  If you increase HZ to 10^5 then
 > you may even notice this bug :-).
 
 I guess this means that itimerfix should really say something like:
 
 -        if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
 +        if (tv->tv_sec < 0 || tv->tv_sec/hz > 1000000 ||
              tv->tv_usec < 0 || tv->tv_usec >= 1000000)
 
 to avoid problems on such systems?
 
 > I read this as a bug in the SUS :-).  The easiest workaround is to not
 > have a limit.  It seems to be easy to fix for select() and poll(), since
 > there is already a loop where we check after some wakeups to see if the
 > timeout expired (see old fixes for this problem in nanosleep()).
 
 > It affects setitimer(), etc.  The SUS requires setitimer() and alarm() to
 > handle the full interval.  POSIX requires this for alarm() IIRC.
 
 I'd be interested in trying to fix this, and really just need more
 info on how timevals should be handeled. Is adding a timevalisvalid()
 function/macro reasonable? How should negative timevals be represented?
 Is -1.5s written as:
 
 	tv_sec = -2; tv_usec = 500000;
 or	tv_sec = -1; tv_usec = -500000;
 
 I'd presume it is the first, but you never can tell.
 
 	David.
 

From: Bruce Evans <bde@zeta.org.au>
To: David Malone <dwmalone@maths.tcd.ie>
Cc: Kelly Yancey <kbyanc@posi.net>, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: kern/18909: select(2) timeout limited to 100000000 seconds 
Date: Thu, 8 Jun 2000 18:31:18 +1000 (EST)

 On Wed, 7 Jun 2000, David Malone wrote:
 
 > > Everything that is implemented using itimers has this limit.  The limit
 > > is only documented explicitly in setitimer.2, alarm.3 and ualarm.3.
 > 
 > Unless I'm mistaken, select (and poll and the kevent stuff) don't
 > actually have anything to do with itimers, as the implementation
 > of their timeouts is with tsleep, which uses timeout, which uses
 > callouts. They are just borrowing the itimerfix() function for
 > a use for which it wasn't intended?
 
 I think it was intended.  For both itimers and select(), the value of
 timeout()'s `tick' arg was once calculated using hzto().  This involved
 a timevaladd() of the current time to a timeout.  It was important
 that the addition doesn't overflow.  This was arranged by limiting
 the timeout.  32-bit signed time_t's will overflow in 2038, and timeouts
 of 10^8 would have started overflowing things in 2035.
 
 FreeBSD now uses tvtohz() instead of hzto(), so the limit of 10^8 is
 no longer very appropriate for either itimers or select().  A limit
 of (timeval when time_t's overflow) - (current time) would be about
 right.  It would be better to have no limit until the current time
 actually overflows time_t (which won't happen becauase either time_t
 or the code will be changed before then), but this may require more
 changes to avoid overflow in intermediate computations.
 
 > I'd be interested in trying to fix this, and really just need more
 > info on how timevals should be handeled. Is adding a timevalisvalid()
 > function/macro reasonable? How should negative timevals be represented?
 > Is -1.5s written as:
 > 
 > 	tv_sec = -2; tv_usec = 500000;
 > or	tv_sec = -1; tv_usec = -500000;
 > 
 > I'd presume it is the first, but you never can tell.
 
 The first is enforced in various places.
 
 Bruce
 
 
Responsible-Changed-From-To: freebsd-bugs->dwmalone 
Responsible-Changed-By: dwmalone 
Responsible-Changed-When: Tue Jul 11 04:43:05 PDT 2000 
Responsible-Changed-Why:  
I'm interested in this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18909 
Responsible-Changed-From-To: dwmalone->freebsd-bugs 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Tue Jul 10 03:41:37 UTC 2012 
Responsible-Changed-Why:  
over to the pool (approved by bugmeister) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=18909 
>Unformatted:
