From owner-svn-src-all@FreeBSD.ORG Sat Aug 21 08:49:54 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0147B1065675; Sat, 21 Aug 2010 08:49:54 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E60718FC08; Sat, 21 Aug 2010 08:49:53 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7L8nrXL061673; Sat, 21 Aug 2010 08:49:53 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7L8nrTO061670; Sat, 21 Aug 2010 08:49:53 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201008210849.o7L8nrTO061670@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 21 Aug 2010 08:49:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211536 - stable/8/bin/sleep X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Aug 2010 08:49:54 -0000 Author: kib Date: Sat Aug 21 08:49:53 2010 New Revision: 211536 URL: http://svn.freebsd.org/changeset/base/211536 Log: MFC r210679: Report the time left for the sleep on SIGINFO. Be stricter in the checking of interval specification. MFC r210696: Deal with proper format for printing time_t. MFC r210749: Simplify argument parser by using sscanf(); simplify usage() by not refusing to use stdio. Reduce nesting level in the sleep loop by returning earlier for negative timeouts. Limit the maximum timeout to INT_MAX seconds. MFC r210750: Document the new argument parser for sleep(1) and SIGINFO behaviour. Remove higlight for the unportability notice. Modified: stable/8/bin/sleep/sleep.1 stable/8/bin/sleep/sleep.c Directory Properties: stable/8/bin/sleep/ (props changed) Modified: stable/8/bin/sleep/sleep.1 ============================================================================== --- stable/8/bin/sleep/sleep.1 Sat Aug 21 04:04:46 2010 (r211535) +++ stable/8/bin/sleep/sleep.1 Sat Aug 21 08:49:53 2010 (r211536) @@ -51,6 +51,10 @@ suspends execution for a minimum of If the .Nm command receives a signal, it takes the standard action. +When the +.Dv SIGINFO +signal is received, the estimate of the amount of seconds left to +sleep is printed on the standard output. .Sh IMPLEMENTATION NOTES The .Dv SIGALRM @@ -58,14 +62,11 @@ signal is not handled specially by this .Pp The .Nm -command will accept and honor a non-integer number of specified seconds -(with a -.Ql .\& -character as a decimal point). -.Bf Sy +command allows and honors a non-integer number of seconds to sleep +in any form acceptable by +.Xr strtod 3 . This is a non-portable extension, and its use will nearly guarantee that a shell script will not execute properly on another system. -.Ef .Sh EXIT STATUS .Ex -std .Sh EXAMPLES Modified: stable/8/bin/sleep/sleep.c ============================================================================== --- stable/8/bin/sleep/sleep.c Sat Aug 21 04:04:46 2010 (r211535) +++ stable/8/bin/sleep/sleep.c Sat Aug 21 08:49:53 2010 (r211536) @@ -42,84 +42,61 @@ static char sccsid[] = "@(#)sleep.c 8.3 __FBSDID("$FreeBSD$"); #include +#include #include +#include +#include #include #include #include -#include -void usage(void); +static void usage(void); + +static volatile sig_atomic_t report_requested; +static void +report_request(int signo __unused) +{ + + report_requested = 1; +} int main(int argc, char *argv[]) { struct timespec time_to_sleep; - long l; - int neg; - char *p; + double d; + time_t original; + char buf[2]; - if (argc != 2) { + if (argc != 2) usage(); - return(1); - } - - p = argv[1]; - /* Skip over leading whitespaces. */ - while (isspace((unsigned char)*p)) - ++p; - - /* Check for optional `+' or `-' sign. */ - neg = 0; - if (*p == '-') { - neg = 1; - ++p; - if (!isdigit((unsigned char)*p) && *p != '.') { - usage(); - return(1); - } - } - 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); + if (sscanf(argv[1], "%lf%1s", &d, buf) != 1) + usage(); + if (d > INT_MAX) + usage(); + if (d <= 0) + return (0); + original = time_to_sleep.tv_sec = (time_t)d; + time_to_sleep.tv_nsec = 1e9 * (d - time_to_sleep.tv_sec); + + signal(SIGINFO, report_request); + while (nanosleep(&time_to_sleep, &time_to_sleep) != 0) { + if (report_requested) { + /* Reporting does not bother with nanoseconds. */ + warnx("about %d second(s) left out of the original %d", + (int)time_to_sleep.tv_sec, (int)original); + report_requested = 0; + } else + break; } - - if (!neg && (time_to_sleep.tv_sec > 0 || time_to_sleep.tv_nsec > 0)) - (void)nanosleep(&time_to_sleep, (struct timespec *)NULL); - - return(0); + return (0); } -void +static void usage(void) { - const char msg[] = "usage: sleep seconds\n"; - write(STDERR_FILENO, msg, sizeof(msg) - 1); + fprintf(stderr, "usage: sleep seconds\n"); + exit(1); }