git: 34978f7edd15 - main - bin/sleep: add support for units other than seconds

From: Stefan Eßer <se_at_FreeBSD.org>
Date: Tue, 24 May 2022 08:05:11 UTC
The branch main has been updated by se:

URL: https://cgit.FreeBSD.org/src/commit/?id=34978f7edd15ef5aa9c14a6eecb18ae5d6fd8842

commit 34978f7edd15ef5aa9c14a6eecb18ae5d6fd8842
Author:     A. Mallory <mallorya@fastmail.com>
AuthorDate: 2022-05-24 07:43:38 +0000
Commit:     Stefan Eßer <se@FreeBSD.org>
CommitDate: 2022-05-24 07:43:38 +0000

    bin/sleep: add support for units other than seconds
    
    The coreutils version of this command accepts a unit designation of s,
    m, h, or d (for seconds, minutes, hours, days) immediately following
    the number of (fractional) units to delay.
    
    The submitted patch has been modified in one detail: the test meant to
    detect the presence of the unit modified was not specific (!= 1) and
    would have accepted a non-numeric initial element or extra characters
    following the union. The committed version accepts only the number
    immediately followed by one of the defined unit designators and no
    further characters.
    
    PR:             264162
    MFC after:      1 week
---
 bin/sleep/sleep.1 | 12 ++++++++++--
 bin/sleep/sleep.c | 18 +++++++++++++++---
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/bin/sleep/sleep.1 b/bin/sleep/sleep.1
index 924bc732a0d0..3ce82936a0e7 100644
--- a/bin/sleep/sleep.1
+++ b/bin/sleep/sleep.1
@@ -40,13 +40,21 @@
 .Nd suspend execution for an interval of time
 .Sh SYNOPSIS
 .Nm
-.Ar seconds
+.Ar number[unit]
 .Sh DESCRIPTION
 The
 .Nm
 command
 suspends execution for a minimum of
-.Ar seconds .
+.Ar number
+seconds (the default, or unit
+.Ar s ) ,
+or minutes (unit
+.Ar m ) ,
+hours (unit
+.Ar h ) ,
+or days (unit
+.Ar d ) .
 .Pp
 If the
 .Nm
diff --git a/bin/sleep/sleep.c b/bin/sleep/sleep.c
index b4b54a336100..8f383e43c479 100644
--- a/bin/sleep/sleep.c
+++ b/bin/sleep/sleep.c
@@ -66,6 +66,7 @@ main(int argc, char *argv[])
 	struct timespec time_to_sleep;
 	double d;
 	time_t original;
+	char unit;
 	char buf[2];
 
 	if (caph_limit_stdio() < 0 || caph_enter() < 0)
@@ -74,8 +75,17 @@ main(int argc, char *argv[])
 	if (argc != 2)
 		usage();
 
-	if (sscanf(argv[1], "%lf%1s", &d, buf) != 1)
-		usage();
+	if (sscanf(argv[1], "%lf%c%1s", &d, &unit, buf) == 2)
+		switch(unit) {
+			case 'd': d *= 24;
+			case 'h': d *= 60;
+			case 'm': d *= 60;
+			case 's': break;
+			default:  usage();
+		}
+	else
+		if (sscanf(argv[1], "%lf%1s", &d, buf) != 1)
+			usage();
 	if (d > INT_MAX)
 		usage();
 	if (d <= 0)
@@ -106,6 +116,8 @@ static void
 usage(void)
 {
 
-	fprintf(stderr, "usage: sleep seconds\n");
+	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);
 }