X-Git-Url: https://git.saurik.com/apple/shell_cmds.git/blobdiff_plain/2ac7f7944aa87a432c2735764a2da6bb88d37197..deb63bfb0b6f1eb3b14b2a2adb33a6f90d11095a:/sleep/sleep.c diff --git a/sleep/sleep.c b/sleep/sleep.c index 87785b9..d41556c 100644 --- a/sleep/sleep.c +++ b/sleep/sleep.c @@ -1,6 +1,4 @@ -/* $NetBSD: sleep.c,v 1.15 1998/07/28 11:41:58 mycroft Exp $ */ - -/* +/*- * Copyright (c) 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. * @@ -12,10 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -33,113 +27,105 @@ * SUCH DAMAGE. */ -#include +#if 0 #ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"); +static char const copyright[] = +"@(#) Copyright (c) 1988, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -#if 0 static char sccsid[] = "@(#)sleep.c 8.3 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: sleep.c,v 1.15 1998/07/28 11:41:58 mycroft Exp $"); -#endif #endif /* not lint */ +#endif +#include +__FBSDID("$FreeBSD: src/bin/sleep/sleep.c,v 1.20 2005/08/07 09:11:38 stefanf Exp $"); -#include #include -#include -#include +#include #include #include +#include #include -#include +#include -void usage __P((void)); -void alarmhandle __P((int)); -int main __P((int, char *[])); +void usage(void); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - char *arg, *temp; - double val, ival, fval; - struct timespec ntime; - int fracflag; - int ch; - - (void)setlocale(LC_ALL, ""); + struct timespec time_to_sleep; + long l; + int neg; + char *p; + + if (argc == 2) { + p = argv[1]; + } else if (argc == 3 && !strcmp("--", argv[1])) { + // POSIX issue: "sleep -- 3" should be the same as "sleep 3", + // normally getopt makes this kind of thing work, but sleep has + // no options, so we do it "the easy way" + p = argv[2]; + } else { + usage(); + return(1); + } - (void)signal(SIGALRM, alarmhandle); + /* Skip over leading whitespaces. */ + while (isspace((unsigned char)*p)) + ++p; - while ((ch = getopt(argc, argv, "")) != -1) - switch(ch) { - case '?': - default: + /* Check for optional `+' or `-' sign. */ + neg = 0; + if (*p == '-') { + neg = 1; + ++p; + if (!isdigit((unsigned char)*p) && *p != '.') { usage(); + return(1); } - argc -= optind; - argv += optind; - - if (argc != 1) - usage(); - - /* - * 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; + else if (*p == '+') + ++p; + + /* Calculate seconds. */ + if (isdigit((unsigned char)*p)) { + l = strtol(p, &p, 10); + if (l > INT_MAX) { + /* + * Avoid overflow when `seconds' is huge. This assumes + * that the maximum value for a time_t is <= INT_MAX. + */ + l = INT_MAX; + } + } else + l = 0; + time_to_sleep.tv_sec = (time_t)l; + + /* Calculate nanoseconds. */ + time_to_sleep.tv_nsec = 0; + + if (*p == '.') { /* Decimal point. */ + l = 100000000L; + do { + if (isdigit((unsigned char)*++p)) + time_to_sleep.tv_nsec += (*p - '0') * l; + else + break; + l /= 10; + } while (l); } - (void)nanosleep(&ntime, NULL); + if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) + (void)nanosleep(&time_to_sleep, (struct timespec *)NULL); - exit(0); - /* NOTREACHED */ + return(0); } void -usage() +usage(void) { - (void)fputs("usage: sleep seconds\n", stderr); - exit(1); - /* NOTREACHED */ -} + const char msg[] = "usage: sleep seconds\n"; -/* ARGSUSED */ -void -alarmhandle(i) - int i; -{ - _exit(0); - /* NOTREACHED */ + write(STDERR_FILENO, msg, sizeof(msg) - 1); }