aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/timeout
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
commit9268022b74279434ed6300244e3f977e56a8ceb5 (patch)
tree377ac0ac449528621eb192cd245adadb5fd53668 /usr.bin/timeout
parent29c34e9d2781cf25403647fb5af7d7ddb23be7e1 (diff)
parent8c3d6a4ab2a4a95d864d9a32d0157d7de90498a4 (diff)
downloadsrc-9268022b74279434ed6300244e3f977e56a8ceb5.tar.gz
src-9268022b74279434ed6300244e3f977e56a8ceb5.zip
Merge from head@274682
Notes
Notes: svn path=/projects/bmake/; revision=274683
Diffstat (limited to 'usr.bin/timeout')
-rw-r--r--usr.bin/timeout/Makefile6
-rw-r--r--usr.bin/timeout/tests/Makefile7
-rw-r--r--usr.bin/timeout/tests/timeout.sh215
-rw-r--r--usr.bin/timeout/timeout.119
-rw-r--r--usr.bin/timeout/timeout.c16
5 files changed, 255 insertions, 8 deletions
diff --git a/usr.bin/timeout/Makefile b/usr.bin/timeout/Makefile
index 46ca6e36e8a9..c1957aeadeeb 100644
--- a/usr.bin/timeout/Makefile
+++ b/usr.bin/timeout/Makefile
@@ -1,5 +1,11 @@
# $FreeBSD$
+.include <src.opts.mk>
+
PROG= timeout
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.prog.mk>
diff --git a/usr.bin/timeout/tests/Makefile b/usr.bin/timeout/tests/Makefile
new file mode 100644
index 000000000000..6303718dd222
--- /dev/null
+++ b/usr.bin/timeout/tests/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/usr.bin/timeout
+
+ATF_TESTS_SH= timeout
+
+.include <bsd.test.mk>
diff --git a/usr.bin/timeout/tests/timeout.sh b/usr.bin/timeout/tests/timeout.sh
new file mode 100644
index 000000000000..e04e6f93b0b7
--- /dev/null
+++ b/usr.bin/timeout/tests/timeout.sh
@@ -0,0 +1,215 @@
+# $FreeBSD$
+
+atf_test_case nominal
+nominal_head()
+{
+ atf_set "descr" "Basic tests on timeout(1) utility"
+}
+
+nominal_body()
+{
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 5 true
+}
+
+atf_test_case time_unit
+time_unit_head()
+{
+ atf_set "descr" "Test parsing the default time unit"
+}
+
+time_unit_body()
+{
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 1d true
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 1h true
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 1m true
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 1s true
+}
+
+atf_test_case no_timeout
+no_timeout_head()
+{
+ atf_set "descr" "Test disabled timeout"
+}
+
+no_timeout_body()
+{
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x timeout 0 true
+}
+
+atf_test_case exit_numbers
+exit_numbers_head()
+{
+ atf_set "descr" "Test exit numbers"
+}
+
+exit_numbers_body()
+{
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:2 \
+ -x timeout 5 sh -c \'exit 2\'
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:124 \
+ -x timeout .1 sleep 1
+
+ # With preserv status exit shoudl be 128 + TERM aka 143
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:143 \
+ -x timeout --preserve-status .1 sleep 10
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:124 \
+ -x timeout -s1 -k1 .1 sleep 10
+
+ atf_check \
+ -o empty \
+ -e empty \
+ -s exit:0 \
+ -x sh -c 'trap "" CHLD; exec timeout 10 true'
+}
+
+atf_test_case with_a_child
+with_a_child_head()
+{
+ atf_set "descr" "When starting with a child (coreutils bug#9098)"
+}
+
+with_a_child_body()
+{
+ out=$(sleep .1 & exec timeout .5 sh -c 'sleep 2; echo foo')
+ status=$?
+ test "$out" = "" && test $status = 124 || atf_fail
+
+}
+
+atf_test_case invalid_timeout
+invalid_timeout_head()
+{
+ atf_set "descr" "Invalid timeout"
+}
+
+invalid_timeout_body()
+{
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid duration\n" \
+ -s exit:125 \
+ -x timeout invalid sleep 0
+
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid duration\n" \
+ -s exit:125 \
+ -x timeout --kill-after=invalid 1 sleep 0
+
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid duration\n" \
+ -s exit:125 \
+ -x timeout 42D sleep 0
+
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid duration\n" \
+ -s exit:125 \
+ -x timeout 999999999999999999999999999999999999999999999999999999999999d sleep 0
+
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid duration\n" \
+ -s exit:125 \
+ -x timeout 2.34e+5d sleep 0
+}
+
+atf_test_case invalid_signal
+invalid_signal_head()
+{
+ atf_set "descr" "Invalid signal"
+}
+
+invalid_signal_body()
+{
+ atf_check \
+ -o empty \
+ -e inline:"timeout: invalid signal\n" \
+ -s exit:125 \
+ -x timeout --signal=invalid 1 sleep 0
+}
+
+atf_test_case invalid_command
+invalid_command_head()
+{
+ atf_set "descr" "Invalid command"
+}
+
+invalid_command_body()
+{
+ atf_check \
+ -o empty \
+ -e inline:"timeout: exec(.): Permission denied\n" \
+ -s exit:126 \
+ -x timeout 10 .
+}
+
+atf_test_case no_such_command
+no_such_command_head()
+{
+ atf_set "descr" "No such command"
+}
+
+no_such_command_body()
+{
+ atf_check \
+ -o empty \
+ -e inline:"timeout: exec(enoexists): No such file or directory\n" \
+ -s exit:127 \
+ -x timeout 10 enoexists
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case nominal
+ atf_add_test_case time_unit
+ atf_add_test_case no_timeout
+ atf_add_test_case exit_numbers
+ atf_add_test_case with_a_child
+ atf_add_test_case invalid_timeout
+ atf_add_test_case invalid_signal
+ atf_add_test_case invalid_command
+ atf_add_test_case no_such_command
+}
diff --git a/usr.bin/timeout/timeout.1 b/usr.bin/timeout/timeout.1
index 028fc622380f..70a91066a6d1 100644
--- a/usr.bin/timeout/timeout.1
+++ b/usr.bin/timeout/timeout.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 19, 2014
+.Dd Oct 28, 2014
.Dt TIMEOUT 1
.Os
.Sh NAME
@@ -108,7 +108,22 @@ is not set, an exit status of 124 is returned.
.Pp
If
.Ar command
-exits after receiving a signal, the exit status returned is the signal number plus 128.
+exits after receiving a signal, the exit status returned is the signal number
+plus 128.
+.Pp
+If
+.Ar command
+is an invalid command, the exit status returned is 126.
+.Pp
+If
+.Ar command
+is a non existing command, the exit status returned is 127.
+.Pp
+If an invalid parameter is passed to
+.Fl s
+or
+.Fl k ,
+the exit status return is 125.
.Sh SEE ALSO
.Xr kill 1 ,
.Xr signal 3
diff --git a/usr.bin/timeout/timeout.c b/usr.bin/timeout/timeout.c
index 817160003e36..214ab138d393 100644
--- a/usr.bin/timeout/timeout.c
+++ b/usr.bin/timeout/timeout.c
@@ -68,7 +68,7 @@ parse_duration(const char *duration)
ret = strtod(duration, &end);
if (ret == 0 && end == duration)
- errx(EXIT_FAILURE, "invalid duration");
+ errx(125, "invalid duration");
if (end == NULL || *end == '\0')
return (ret);
@@ -89,11 +89,11 @@ parse_duration(const char *duration)
ret *= 60 * 60 * 24;
break;
default:
- errx(EX_USAGE, "invalid duration");
+ errx(125, "invalid duration");
}
if (ret < 0 || ret >= 100000000UL)
- errx(EX_USAGE, "invalid duration");
+ errx(125, "invalid duration");
return (ret);
}
@@ -116,7 +116,7 @@ parse_signal(const char *str)
return (i);
}
- errx(EX_USAGE, "invalid signal");
+ errx(125, "invalid signal");
}
static void
@@ -260,8 +260,12 @@ main(int argc, char **argv)
signal(SIGTTOU, SIG_DFL);
error = execvp(argv[0], argv);
- if (error == -1)
- err(EX_UNAVAILABLE, "exec()");
+ if (error == -1) {
+ if (errno == ENOENT)
+ err(127, "exec(%s)", argv[0]);
+ else
+ err(126, "exec(%s)", argv[0]);
+ }
}
if (sigprocmask(SIG_BLOCK, &signals.sa_mask, NULL) == -1)