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:
parent
62e9894c48
commit
ba29cbc528
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue