Make sleep handle non-integer values. Document the same, noting that

the extension is grotesquely non-portable.

As requested by Denny Gentry in pr-3914. He supplied some code, but I
used all my own code in the change, and wrote documentation for the
man page.

This is creeping featurism at its worst. I added it only because I
can't see a good reason for refusing. However, I'm disgusted with
myself for doing it anyway.
This commit is contained in:
perry 1997-08-04 01:13:07 +00:00
parent 62e9894c48
commit ba29cbc528
3 changed files with 79 additions and 14 deletions

View File

@ -1,6 +1,8 @@
# $NetBSD: Makefile,v 1.8 1997/07/20 22:38:01 christos Exp $
# $NetBSD: Makefile,v 1.9 1997/08/04 01:13:07 perry Exp $
# @(#)Makefile 8.1 (Berkeley) 5/31/93
PROG= sleep
LDADD+= -lm
DPADD+= ${LIBM}
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
.\" $NetBSD: sleep.1,v 1.9 1995/07/25 19:37:43 jtc Exp $
.\" $NetBSD: sleep.1,v 1.10 1997/08/04 01:13:09 perry Exp $
.\"
.\" Copyright (c) 1990, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
@ -47,17 +47,16 @@
.Ar seconds
.Sh DESCRIPTION
The
.Nm sleep
.Nm
utility
suspends execution for a minimum of
.Ar seconds .
.Nm Sleep
is used to schedule the execution of other commands (see
It is usually used to schedule the execution of other commands (see
.Sx EXAMPLES
below).
.Pp
The
.Nm Sleep
.Nm
utility exits with one of the following values:
.Bl -tag -width flag
.It Li \&0
@ -67,6 +66,14 @@ was received.
.It Li \&>\&0
An error occurred.
.El
.Pp
Note: The
.Nx
.Nm
command will accept and honor a non-integer number of specified
seconds. This is a non-portable extension, and its use will nearly
guarantee that a shell script will not execute properly on another
system.
.Sh EXAMPLES
To schedule the execution of a command for
.Va x
@ -106,13 +113,12 @@ when the file is found, then another portion processing
is done courteously by sleeping for 70 seconds in between each
awk job.
.Sh SEE ALSO
.Xr setitimer 2 ,
.Xr alarm 3 ,
.Xr nanosleep 2 ,
.Xr sleep 3 ,
.Xr at 1
.Sh STANDARDS
The
.Nm sleep
.Nm
command is expected to be
.St -p1003.2
compatible.

View File

@ -1,4 +1,4 @@
/* $NetBSD: sleep.c,v 1.9 1997/07/20 21:28:27 christos Exp $ */
/* $NetBSD: sleep.c,v 1.10 1997/08/04 01:13:10 perry Exp $ */
/*
* Copyright (c) 1988, 1993, 1994
@ -43,16 +43,26 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\n\
#if 0
static char sccsid[] = "@(#)sleep.c 8.3 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: sleep.c,v 1.9 1997/07/20 21:28:27 christos Exp $");
__RCSID("$NetBSD: sleep.c,v 1.10 1997/08/04 01:13:10 perry Exp $");
#endif
#endif /* not lint */
/*
* XXX shouldn't need sys/time.h, but there was an include file bug
* which may be fixed soon.
*/
#include <sys/time.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <locale.h>
void usage __P((void));
void alarmhandle __P((int));
int main __P((int, char *[]));
int
@ -60,10 +70,16 @@ main(argc, argv)
int argc;
char *argv[];
{
int ch, secs;
char *arg, *temp;
double val, ival, fval;
struct timespec ntime;
int fracflag;
int ch;
setlocale(LC_ALL, "");
(void)signal(SIGALRM, alarmhandle);
while ((ch = getopt(argc, argv, "")) != EOF)
switch(ch) {
case '?':
@ -76,8 +92,42 @@ main(argc, argv)
if (argc != 1)
usage();
if ((secs = atoi(*argv)) > 0)
(void)sleep(secs);
/*
* Okay, why not just use atof for everything? Why bother
* checking if there is a fraction in use? Because the old
* sleep handled the full range of integers, that's why, and a
* double can't handle a large long. This is fairly useless
* given how large a number a double can hold on most
* machines, but now we won't ever have trouble. If you want
* 1000000000.9 seconds of sleep, well, that's your
* problem. Why use an isdigit() check instead of checking for
* a period? Because doing it this way means locales will be
* handled transparently by the atof code.
*/
fracflag = 0;
arg = *argv;
for (temp = arg; *temp != '\0'; temp++)
if (!isdigit(*temp))
fracflag++;
if (fracflag) {
val = atof(arg);
if (val <= 0)
exit(0);
ival = floor(val);
fval = (1000000000 * (val-ival));
ntime.tv_sec = ival;
ntime.tv_nsec = fval;
}
else{
ntime.tv_sec = atol(arg);
if (ntime.tv_sec <= 0)
exit(0);
ntime.tv_nsec = 0;
}
(void)nanosleep(&ntime, NULL);
exit(0);
}
@ -88,3 +138,10 @@ usage()
(void)fprintf(stderr, "usage: sleep seconds\n");
exit(1);
}
void
alarmhandle(i)
int i;
{
_exit(0);
}