>From 5e96377bf15f47af66348efe3cfa28302da97f0d Mon Sep 17 00:00:00 2001 From: Bernhard Voelker Date: Wed, 30 Jul 2014 09:18:57 +0200 Subject: [PATCH] sleep: support subtraction of sleep amounts * src/sleep.c (main): Check for non-negative sleep amount for the resulting total only instead of for each individual argument. * tests/misc/sleep.sh: New file. * tests/local.mk (all_tests): Add it. * doc/coreutils.texi (sleep invocation): Add an example. * NEWS (Improvements): Mention the change. Discussed in http://bugs.gnu.org/7877#67 --- NEWS | 4 +++ doc/coreutils.texi | 5 ++++ src/sleep.c | 9 ++++-- tests/local.mk | 1 + tests/misc/sleep.sh | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 2 deletions(-) create mode 100755 tests/misc/sleep.sh diff --git a/NEWS b/NEWS index 511e626..3760b24 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ GNU coreutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** Improvements + + sleep now supports subtraction of sleep amounts among arguments. + * Noteworthy changes in release 8.23 (2014-07-18) [stable] diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 96f0781..374113f 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -16858,6 +16858,11 @@ Historical implementations of @command{sleep} have required that without a suffix. However, GNU @command{sleep} accepts arbitrary floating point numbers. @xref{Floating point}. +The following example shows how to sleep 10 minutes less than a day: +@example +$ sleep -- 1d -10m +@end example + The only options are @option{--help} and @option{--version}. @xref{Common options}. diff --git a/src/sleep.c b/src/sleep.c index e24c251..bd758ad 100644 --- a/src/sleep.c +++ b/src/sleep.c @@ -125,8 +125,6 @@ main (int argc, char **argv) double s; const char *p; if (! xstrtod (argv[i], &p, &s, c_strtod) - /* Nonnegative interval. */ - || ! (0 <= s) /* No extra chars after the number and an optional s,m,h,d char. */ || (*p && *(p+1)) /* Check any suffix char and update S based on the suffix. */ @@ -139,6 +137,13 @@ main (int argc, char **argv) seconds += s; } + /* Rule out negative and infinite-and-non-positive numbers. */ + if (ok && ! (0 <= seconds)) + { + error (0, 0, _("invalid total sleep time %f"), seconds); + ok = false; + } + if (!ok) usage (EXIT_FAILURE); diff --git a/tests/local.mk b/tests/local.mk index e0f1f84..2d4060c 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -318,6 +318,7 @@ all_tests = \ tests/misc/shred-negative.sh \ tests/misc/shred-passes.sh \ tests/misc/shred-remove.sh \ + tests/misc/sleep.sh \ tests/misc/shuf.sh \ tests/misc/shuf-reservoir.sh \ tests/misc/sort.pl \ diff --git a/tests/misc/sleep.sh b/tests/misc/sleep.sh new file mode 100755 index 0000000..d365536 --- /dev/null +++ b/tests/misc/sleep.sh @@ -0,0 +1,79 @@ +#!/bin/sh +# Exercise sleep summing up and subtracting arguments. + +# Copyright (C) 2014 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src +print_ver_ sleep + +# Check that 0 (Zero) is accepted. +env sleep 0 || fail=1 + +do_sleep () +{ + t=$1 # timeout + exp=$2 # expected exit code + shift 2 || framework_failure_ + timeout $t env sleep -- "$@" + test $? = $exp +} + +# Check that sleep sums up the arguments. +do_sleep .3 0 .01 || fail=1 +do_sleep .3 124 .01 2 || fail=1 +do_sleep .3 124 .09 .01 2 || fail=1 + +# Check that subtracting works. +do_sleep .3 0 1m -59.99s || fail=1 +do_sleep .5 124 1m -59s || fail=1 + +# Check that subtracting works with more arguments. +do_sleep .3 0 1d -23h -59m -59.99s || fail=1 +do_sleep .5 124 1d -23h -59m -59s || fail=1 + +# Check that subtracting works starting with a negative number. +do_sleep .3 0 -1d 24h .01 || fail=1 + +inv_sleep () +{ + rm -f out err err2 || framework_failure_ + + env sleep -- "$@" >out 2>err && fail=1 + sed 's/\(sleep: invalid total sleep time \).*$/\1x/' \ + < err > err2 || framework_failure_ + compare /dev/null out || fail=1 + compare exp err2 || fail=1 + return $fail +} + +cat < exp +sleep: invalid total sleep time x +Try 'sleep --help' for more information. +! + +# Do not allow negative ... +inv_sleep -1 || fail=1 +inv_sleep 1m -61s || fail=1 +inv_sleep 1d -23h -59m -61s || fail=1 + +# ... or otherwise invalid sleep times. +for i in -inf nan -nan ; do + for j in '' 1 inf -inf nan -nan ; do + inv_sleep $i $j || fail=1 + done +done + +Exit $fail -- 1.8.4.5