Date: Thu, 25 Apr 2002 15:49:24 +1000 (EST) From: Edwin Groothuis <edwin@mavetju.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/37442: [PATCH] sleep.c to support time multipliers Message-ID: <20020425054924.A8057397@k7.mavetju.org>
next in thread | raw e-mail | index | archive | help
>Number: 37442 >Category: bin >Synopsis: [PATCH] sleep.c to support time multipliers >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Apr 24 22:50:00 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Edwin Groothuis >Release: FreeBSD 4.5-RELEASE i386 >Organization: - >Environment: System: FreeBSD k7.mavetju.org 4.5-RELEASE FreeBSD 4.5-RELEASE #3: Mon Mar 11 13:32:05 EST 2002 edwin@k7.mavetju.org:/usr/src/sys/compile/k7 i386 Makefile: 1.8 1.5.2.1 sleep.c: 1.11 1.9.2.1 sleep.1: 1.17 1.5.2.2 >Description: I want to run my nightly downloads run in an xterm, so I can check if they've run properly. Often I have to delay them for hours and am now pretty good skilled in the multiplication table of 1800, but now and then things are one hour off. To solve this, I've modified sleep(1) to support multipliers: sleep 1h will sleep for one hour, sleep 2.5m will sleep for two and a half minute. >How-To-Repeat: >Fix: Two patches, one against the 4.5 code, one against the -current of today. This is patch against the 4.5 code: --- Makefile-4.5 Thu Apr 25 15:25:49 2002 +++ Makefile Thu Apr 25 15:09:25 2002 @@ -3,6 +3,8 @@ PROG= sleep +LDADD= -lm + WARNS?= 2 .include <bsd.prog.mk> --- sleep.1-4.5 Thu Apr 25 15:25:41 2002 +++ sleep.1 Thu Apr 25 15:18:15 2002 @@ -44,12 +44,18 @@ .Sh SYNOPSIS .Nm .Ar seconds +.Nm +.Ar number[multiplier] .Sh DESCRIPTION The .Nm command suspends execution for a minimum of -.Ar seconds . +.Ar seconds +or for the time specified by +.Ar number[multiplier] . +The multiplier can be `s' for seconds, `m' for minutes, `h' for +hours and `d' for days. .Pp If the .Nm @@ -85,6 +91,10 @@ number seconds later: .Pp .Dl (sleep 1800; sh command_file >& errors)& +.Pp +or +.Pp +.Dl (sleep .5h; sh command_file >& errors)& .Pp This incantation would wait a half hour before running the script command_file. --- sleep.c-4.5 Thu Apr 25 15:25:38 2002 +++ sleep.c Thu Apr 25 15:12:59 2002 @@ -51,6 +51,7 @@ #include <stdlib.h> #include <time.h> #include <unistd.h> +#include <math.h> int main __P((int, char *[])); void usage __P((void)); @@ -61,7 +62,7 @@ char *argv[]; { struct timespec time_to_sleep; - long l; + double d; int ch, neg; char *p; @@ -95,33 +96,43 @@ 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; - } while (l /= 10); + d = atof(p); + while (*p != 0) { + if (!isdigit(*p) && *p != '.') + break; + p++; } + /* Do multiplier trick. */ + switch (*p) { + case 0: + case 's': + break; + case 'm': + d *= 60; + break; + case 'h': + d *= 60 * 60; + break; + case 'd': + d *= 24 * 60 * 60; + break; + default: + usage(); + /* NOTREACHED */ + } + + if (d > INT_MAX) + d = INT_MAX; + + /* + * Split up the double into an integer (seconds) and + * fractional (nanoseconds) part. + */ + time_to_sleep.tv_sec = (time_t)floor(d); + time_to_sleep.tv_nsec = + (time_t)1000000000L * (d - time_to_sleep.tv_sec); + if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) (void)nanosleep(&time_to_sleep, (struct timespec *)NULL); @@ -132,6 +144,6 @@ usage() { (void)fprintf(stderr, "usage: sleep seconds\n"); + (void)fprintf(stderr, " or: sleep number[multiplier]\n"); exit(1); } This is the patch against -current --- Makefile-1.8 Thu Apr 25 15:24:31 2002 +++ Makefile Thu Apr 25 15:09:25 2002 @@ -1,6 +1,8 @@ # @(#)Makefile 8.1 (Berkeley) 5/31/93 -# $FreeBSD: src/bin/sleep/Makefile,v 1.8 2001/12/04 01:57:46 obrien Exp $ +# $FreeBSD: src/bin/sleep/Makefile,v 1.5.2.1 2001/08/01 05:23:25 obrien Exp $ PROG= sleep + +LDADD= -lm .include <bsd.prog.mk> --- sleep.1-1.17 Thu Apr 25 15:25:03 2002 +++ sleep.1 Thu Apr 25 15:18:15 2002 @@ -33,7 +33,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)sleep.1 8.3 (Berkeley) 4/18/94 -.\" $FreeBSD: src/bin/sleep/sleep.1,v 1.17 2001/08/07 15:48:27 ru Exp $ +.\" $FreeBSD: src/bin/sleep/sleep.1,v 1.15.2.2 2001/08/16 10:01:09 ru Exp $ .\" .Dd April 18, 1994 .Dt SLEEP 1 @@ -44,12 +44,18 @@ .Sh SYNOPSIS .Nm .Ar seconds +.Nm +.Ar number[multiplier] .Sh DESCRIPTION The .Nm command suspends execution for a minimum of -.Ar seconds . +.Ar seconds +or for the time specified by +.Ar number[multiplier] . +The multiplier can be `s' for seconds, `m' for minutes, `h' for +hours and `d' for days. .Pp If the .Nm @@ -85,6 +91,10 @@ number seconds later: .Pp .Dl (sleep 1800; sh command_file >& errors)& +.Pp +or +.Pp +.Dl (sleep .5h; sh command_file >& errors)& .Pp This incantation would wait a half hour before running the script command_file. --- sleep.c-1.11 Thu Apr 25 15:23:38 2002 +++ sleep.c Thu Apr 25 15:38:19 2002 @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)sleep.c 8.3 (Berkeley) 4/2/94"; #endif static const char rcsid[] = - "$FreeBSD: src/bin/sleep/sleep.c,v 1.11 2002/02/02 06:50:56 imp Exp $"; + "$FreeBSD: src/bin/sleep/sleep.c,v 1.9.2.1 2001/08/01 05:23:25 obrien Exp $"; #endif /* not lint */ #include <ctype.h> @@ -51,6 +51,7 @@ #include <stdlib.h> #include <time.h> #include <unistd.h> +#include <math.h> void usage(void); @@ -58,7 +59,7 @@ main(int argc, char *argv[]) { struct timespec time_to_sleep; - long l; + double d; int ch, neg; char *p; @@ -92,33 +93,43 @@ 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; - } while (l /= 10); + d = atof(p); + while (*p != 0) { + if (!isdigit(*p) && *p != '.') + break; + p++; } + /* Do multiplier trick. */ + switch (*p) { + case 0: + case 's': + break; + case 'm': + d *= 60; + break; + case 'h': + d *= 60 * 60; + break; + case 'd': + d *= 24 * 60 * 60; + break; + default: + usage(); + /* NOTREACHED */ + } + + if (d > INT_MAX) + d = INT_MAX; + + /* + * Split up the double into an integer (seconds) and + * fractional (nanoseconds) part. + */ + time_to_sleep.tv_sec = (time_t)floor(d); + time_to_sleep.tv_nsec = + (time_t)1000000000L * (d - time_to_sleep.tv_sec); + if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) (void)nanosleep(&time_to_sleep, (struct timespec *)NULL); @@ -130,5 +141,6 @@ { (void)fprintf(stderr, "usage: sleep seconds\n"); + (void)fprintf(stderr, " or: sleep number[multiplier]\n"); exit(1); } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020425054924.A8057397>