aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Eßer <se@FreeBSD.org>2022-05-24 08:47:40 +0000
committerStefan Eßer <se@FreeBSD.org>2022-05-24 08:47:40 +0000
commitbe038c3afcaec78d6e92c33f03ec6d2523b3c719 (patch)
tree8173c8f64137c1b8b4762f5a7afe1a38c5a1dff2
parent34978f7edd15ef5aa9c14a6eecb18ae5d6fd8842 (diff)
downloadsrc-be038c3afcae.tar.gz
src-be038c3afcae.zip
bin/sleep: add support for multiple delay values
The sleep time is calculated as the sum of all arguments passed. This makes the FreeBSD version of sleep functionally compatible with the version in GNU coreutils. MFC after: 1 week
-rw-r--r--bin/sleep/sleep.116
-rw-r--r--bin/sleep/sleep.c50
2 files changed, 40 insertions, 26 deletions
diff --git a/bin/sleep/sleep.1 b/bin/sleep/sleep.1
index 3ce82936a0e7..85086acec5ad 100644
--- a/bin/sleep/sleep.1
+++ b/bin/sleep/sleep.1
@@ -32,7 +32,7 @@
.\" @(#)sleep.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.Dd December 31, 2020
+.Dd May 24, 2022
.Dt SLEEP 1
.Os
.Sh NAME
@@ -40,21 +40,21 @@
.Nd suspend execution for an interval of time
.Sh SYNOPSIS
.Nm
-.Ar number[unit]
+.Ar number[unit] ...
.Sh DESCRIPTION
The
.Nm
-command
-suspends execution for a minimum of
+command suspends execution for a minimum of
.Ar number
seconds (the default, or unit
.Ar s ) ,
-or minutes (unit
+minutes (unit
.Ar m ) ,
hours (unit
.Ar h ) ,
or days (unit
.Ar d ) .
+If multiple arguments are passed, the delay will be the sum of all values.
.Pp
If the
.Nm
@@ -72,9 +72,9 @@ The
.Nm
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, but is also implemented in GNU sh-utils
-since version 2.0a (released in 2002).
+.Xr strtod 3 and it 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
diff --git a/bin/sleep/sleep.c b/bin/sleep/sleep.c
index 8f383e43c479..55e0aba9871a 100644
--- a/bin/sleep/sleep.c
+++ b/bin/sleep/sleep.c
@@ -64,34 +64,48 @@ int
main(int argc, char *argv[])
{
struct timespec time_to_sleep;
- double d;
+ double d, 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)
+ if (argc < 2)
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)
+ 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;
+ }
+ if (seconds > INT_MAX)
usage();
- if (d <= 0)
+ if (seconds <= 0)
return (0);
- original = time_to_sleep.tv_sec = (time_t)d;
- time_to_sleep.tv_nsec = 1e9 * (d - time_to_sleep.tv_sec);
+ 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);
@@ -116,7 +130,7 @@ static void
usage(void)
{
- fprintf(stderr, "usage: sleep number[unit]\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);