From nobody Mon Mar 25 15:59:24 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4V3HgJ5DdPz5FClm; Mon, 25 Mar 2024 15:59:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4V3HgJ4kS2z4Sjs; Mon, 25 Mar 2024 15:59:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1711382364; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZXxrdlkJsXmyXsElZAtrTWWkwj0C8Rgc7+jibOEfqkY=; b=xBWyhfzteNu8HPNtaPA6McxV1JpV3ZGfrhZ9Z8hhqsIeiA57+MZ6itQhROOfgEUCJd7VgS F3MmGhauz5QXQeUj9NfvIN9T+VG9Csy/0wnTifxkF8wdkXR89gSKeBnulGJvr0HueEJkDU YZmVGON/3/Uaeiq1AIYObGH3+jKvcwgMW67U1Md3WfvU/MkolzCe/uE2FJbXW/G1o61H6N wNo+YEW8sbMgmD7AHK9sorbMYSQ8baYPGq4wqi3Cd2FAmSNO2ZuAVER0OWH/rF+YT7gzx1 +ykkh/ZuD46QneS18np2jiExAoPujxXRzKZYGeFVW8PRmhFKH9yQJfaPjcTugQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1711382364; a=rsa-sha256; cv=none; b=k081frFv0Y+rTqbXuAmPAQvLqijIZZASKCWt11CCLregxalPUKbtW80PP+DH4bI3Sd0k+6 6GqDH9SKS8jSphh+qiIO6IfjjILdMWQqKKxCOZtOXdlFNksuE54ZJN1cHzfV+VVuFzovkj ySm0jDZ7hJYEnqy7OvfKb5wx8teSfcpJE6WKabgbSAq/i328dz/kysloPG06F+VjfF0XPJ AqrgRA3lKI8Arpi3DKldwrITUxlyJu9KokSR9ndDqwXv4O/LD+yz/cQSCiHpdsFfJHo99f I2B+crrqTm7xCY5KMZ4QXMekNymFklRWPn3FcmNsGZjzhXSwb83SCgbXDlhnnA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1711382364; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZXxrdlkJsXmyXsElZAtrTWWkwj0C8Rgc7+jibOEfqkY=; b=c5Hu+KPlzpOMUDYcYgJZg9UADHtoKgi7E5VAfv9OpMwHPmH28D2euJioSRSJYVI05FaAPe L4LotHh/s7TDLAtG1/r3VruZuQ3pAUJWGY41vbn8C9AlVSiwvSV9du2L7OldNgElNPcqY0 RWJFx5ooK2vY+W5LEDKi4l9H8lj7ObDjD3BmMFZc1qJQdhI1qCQQjwyBHIIbMGs/ygu8fq nlgi/DnXNQ/mCt8gpW6YTA7lktCHIrAhmB2Oqe14FmX7u5LKF/2VAaio9pBWWZsPu6LagD 5RboMrEL9udA74GwxG4PghTCSh5fjV55TxbA1XiafhNCxN7jfuniueII6zkG4w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4V3HgJ4KsMzN2P; Mon, 25 Mar 2024 15:59:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 42PFxOGO083882; Mon, 25 Mar 2024 15:59:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 42PFxOGd083880; Mon, 25 Mar 2024 15:59:24 GMT (envelope-from git) Date: Mon, 25 Mar 2024 15:59:24 GMT Message-Id: <202403251559.42PFxOGd083880@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 2295cae7e606 - main - sleep: Overhaul. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: des X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2295cae7e606d75016575927c3d8729745abb17a Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=2295cae7e606d75016575927c3d8729745abb17a commit 2295cae7e606d75016575927c3d8729745abb17a Author: Dag-Erling Smørgrav AuthorDate: 2024-03-25 15:58:31 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-03-25 15:59:02 +0000 sleep: Overhaul. Program: * Add a dummy getopt(3) loop to handle `--`. * Move interval parsing out into a separate function. * Print a diagnostic for every invalid interval. * Check for NaN and infinity. * Improve bounds checks. Manual page: * Miscellaneous markup fixes. * Reword DESCRIPTION section. * Move text about GNU compatibility to STANDARDS section. * Convert examples from csh to sh. Sponsored by: Klara, Inc. Reviewed by: kevans Differential Revision: https://reviews.freebsd.org/D44471 --- bin/sleep/sleep.1 | 77 ++++++++++++++++++------------------- bin/sleep/sleep.c | 111 +++++++++++++++++++++++++++++------------------------- 2 files changed, 98 insertions(+), 90 deletions(-) diff --git a/bin/sleep/sleep.1 b/bin/sleep/sleep.1 index b6af3a648a97..c9069a015706 100644 --- a/bin/sleep/sleep.1 +++ b/bin/sleep/sleep.1 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 25, 2022 +.Dd March 22, 2024 .Dt SLEEP 1 .Os .Sh NAME @@ -38,21 +38,26 @@ .Sh SYNOPSIS .Nm .Ar number Ns Op Ar unit -.Ar ... +.Op ... .Sh DESCRIPTION The .Nm command suspends execution for a minimum of .Ar number seconds (the default, or unit -.Cm s ) , +.Li s ) , minutes (unit -.Cm m ) , +.Li m ) , hours (unit -.Cm h ) , +.Li h ) , or days (unit -.Cm d ) . -If multiple arguments are passed, the delay will be the sum of all values. +.Li d ) . +Intervals can be written in any form allowed by +.Xr strtod 3 . +If multiple intervals are given, they are added together. +If the final sum is zero or negative, +.Nm +exits immediately. .Pp If the .Nm @@ -65,57 +70,49 @@ sleep is printed on the standard output. The .Dv SIGALRM signal is not handled specially by this implementation. -.Pp -The -.Nm -command supports other time units than seconds, -honors a non-integer number of time units to sleep in any form acceptable by -.Xr strtod 3 , -and accepts more than one delay value. -These are non-portable extensions, but they have also been implemented -in GNU sh-utils since version 2.0a (released in 2002). .Sh EXIT STATUS .Ex -std .Sh EXAMPLES -To schedule the execution of a command for -.Va x -number seconds later (with -.Xr csh 1 ) : +To run a command after half an hour: .Pp -.Dl (sleep 1800; sh command_file >& errors)& +.Dl (sleep 0.5h; sh command_file >out 2>err)& .Pp -This incantation would wait a half hour before -running the script command_file. -(See the +This incantation would wait half an hour before +running the script +.Pa command_file . +See the .Xr at 1 -utility.) +utility for another way to do this. .Pp -To reiteratively run a command (with the -.Xr csh 1 ) : +To reiteratively run a command: .Pp .Bd -literal -offset indent -compact -while (1) - if (! -r zzz.rawdata) then - sleep 300 +while :; do + if ! [ -r zzz.rawdata ] ; then + sleep 5m else - foreach i (`ls *.rawdata`) + for i in *.rawdata ; do sleep 70 - awk -f collapse_data $i >> results - end + awk -f collapse_data "$i" + done >results break - endif -end + fi +done .Ed .Pp The scenario for a script such as this might be: a program currently running is taking longer than expected to process a series of files, and it would be nice to have another program start processing the files created by the first -program as soon as it is finished (when zzz.rawdata is created). -The script checks every five minutes for the file zzz.rawdata, +program as soon as it is finished (when +.Pa zzz.rawdata +is created). +The script checks every five minutes for the file +.Pa zzz.rawdata , when the file is found, then another portion processing is done courteously by sleeping for 70 seconds in between each -awk job. +.Xr awk 1 +job. .Sh SEE ALSO .Xr nanosleep 2 , .Xr sleep 3 @@ -125,6 +122,10 @@ The command is expected to be .St -p1003.2 compatible. +.Pp +Support for non-integer intervals, units other than seconds, and +multiple intervals which are added together are non-portable +extensions first introduced in GNU sh-utils 2.0a (released in 2002). .Sh HISTORY A .Nm diff --git a/bin/sleep/sleep.c b/bin/sleep/sleep.c index 20e525ce093c..34d335cf4736 100644 --- a/bin/sleep/sleep.c +++ b/bin/sleep/sleep.c @@ -31,93 +31,100 @@ #include #include #include +#include #include #include #include #include - -static void usage(void) __dead2; +#include static volatile sig_atomic_t report_requested; + static void report_request(int signo __unused) { - report_requested = 1; } +static void __dead2 +usage(void) +{ + fprintf(stderr, "usage: sleep number[unit] [...]\n" + "Unit can be 's' (seconds, the default), " + "m (minutes), h (hours), or d (days).\n"); + exit(1); +} + +static double +parse_interval(const char *arg) +{ + double num; + char unit, extra; + + switch (sscanf(arg, "%lf%c%c", &num, &unit, &extra)) { + case 2: + switch (unit) { + case 'd': + num *= 24; + /* FALLTHROUGH */ + case 'h': + num *= 60; + /* FALLTHROUGH */ + case 'm': + num *= 60; + /* FALLTHROUGH */ + case 's': + if (!isnan(num)) + return (num); + } + break; + case 1: + if (!isnan(num)) + return (num); + } + warnx("invalid time interval: %s", arg); + return (INFINITY); +} + int main(int argc, char *argv[]) { struct timespec time_to_sleep; - double d, seconds; + double seconds; time_t original; - char unit; - char buf[2]; - int i, matches; if (caph_limit_stdio() < 0 || caph_enter() < 0) err(1, "capsicum"); - if (argc < 2) + while (getopt(argc, argv, "") != -1) + usage(); + argc -= optind; + argv += optind; + if (argc < 1) usage(); seconds = 0; - for (i = 1; i < argc; i++) { - matches = sscanf(argv[i], "%lf%c%1s", &d, &unit, buf); - if (matches == 2) - switch(unit) { - case 'd': - d *= 24; - /* FALLTHROUGH */ - case 'h': - d *= 60; - /* FALLTHROUGH */ - case 'm': - d *= 60; - /* FALLTHROUGH */ - case 's': - break; - default: - usage(); - } - else - if (matches != 1) - usage(); - seconds += d; - } + while (argc--) + seconds += parse_interval(*argv++); if (seconds > INT_MAX) usage(); - if (seconds <= 0) - return (0); + if (seconds < 1e-9) + exit(0); original = time_to_sleep.tv_sec = (time_t)seconds; time_to_sleep.tv_nsec = 1e9 * (seconds - time_to_sleep.tv_sec); signal(SIGINFO, report_request); - /* - * Note: [EINTR] is supposed to happen only when a signal was handled - * but the kernel also returns it when a ptrace-based debugger - * attaches. This is a bug but it is hard to fix. - */ while (nanosleep(&time_to_sleep, &time_to_sleep) != 0) { + if (errno != EINTR) + err(1, "nanosleep"); 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); + warnx("about %ld second(s) left out of the original %ld", + (long)time_to_sleep.tv_sec, (long)original); report_requested = 0; - } else if (errno != EINTR) - err(1, "nanosleep"); + } } - return (0); -} -static void -usage(void) -{ - - fprintf(stderr, "usage: sleep number[unit] ...\n"); - fprintf(stderr, "Unit can be 's' (seconds, the default), " - "m (minutes), h (hours), or d (days).\n"); - exit(1); + exit(0); }