From owner-freebsd-bugs Wed Apr 24 22:50:27 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 0DAC737B427 for ; Wed, 24 Apr 2002 22:50:01 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g3P5o1C50044; Wed, 24 Apr 2002 22:50:01 -0700 (PDT) (envelope-from gnats) Received: from topaz.mdcc.cx (topaz.mdcc.cx [212.204.230.141]) by hub.freebsd.org (Postfix) with ESMTP id 7981037B404 for ; Wed, 24 Apr 2002 22:48:32 -0700 (PDT) Received: from k7.mavetju.org (topaz.mdcc.cx [212.204.230.141]) by topaz.mdcc.cx (Postfix) with ESMTP id 4A89C2B6CB for ; Thu, 25 Apr 2002 07:48:26 +0200 (CEST) Received: by k7.mavetju.org (Postfix, from userid 1001) id A8057397; Thu, 25 Apr 2002 15:49:24 +1000 (EST) Message-Id: <20020425054924.A8057397@k7.mavetju.org> Date: Thu, 25 Apr 2002 15:49:24 +1000 (EST) From: Edwin Groothuis Reply-To: Edwin Groothuis To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/37442: [PATCH] sleep.c to support time multipliers Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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 --- 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 #include #include +#include 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 --- 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 @@ -51,6 +51,7 @@ #include #include #include +#include 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