svn commit: r287392 - in stable/10: etc/mtree usr.bin usr.bin/timeout usr.bin/timeout/tests
Baptiste Daroussin
bapt at FreeBSD.org
Wed Sep 2 05:45:49 UTC 2015
Author: bapt
Date: Wed Sep 2 05:45:47 2015
New Revision: 287392
URL: https://svnweb.freebsd.org/changeset/base/287392
Log:
MFC: r268745,r268746,r268747,r268748,r268749,r268861,r268750,r268751,r268763
r273769,r273771,r276771,r278810
New BSDL timeout(1) utility compatible with GNU timeout
Relnotes: yes
Added:
stable/10/usr.bin/timeout/
- copied from r268745, head/usr.bin/timeout/
stable/10/usr.bin/timeout/tests/
- copied from r273771, head/usr.bin/timeout/tests/
Modified:
stable/10/etc/mtree/BSD.tests.dist
stable/10/usr.bin/Makefile
stable/10/usr.bin/timeout/Makefile
stable/10/usr.bin/timeout/timeout.1
stable/10/usr.bin/timeout/timeout.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/etc/mtree/BSD.tests.dist
==============================================================================
--- stable/10/etc/mtree/BSD.tests.dist Wed Sep 2 02:50:41 2015 (r287391)
+++ stable/10/etc/mtree/BSD.tests.dist Wed Sep 2 05:45:47 2015 (r287392)
@@ -323,6 +323,8 @@
..
..
..
+ timeout
+ ..
variables
modifier_M
..
Modified: stable/10/usr.bin/Makefile
==============================================================================
--- stable/10/usr.bin/Makefile Wed Sep 2 02:50:41 2015 (r287391)
+++ stable/10/usr.bin/Makefile Wed Sep 2 05:45:47 2015 (r287392)
@@ -157,6 +157,7 @@ SUBDIR= alias \
tee \
${_tests} \
time \
+ timeout \
tip \
top \
touch \
Modified: stable/10/usr.bin/timeout/Makefile
==============================================================================
--- head/usr.bin/timeout/Makefile Wed Jul 16 09:55:36 2014 (r268745)
+++ stable/10/usr.bin/timeout/Makefile Wed Sep 2 05:45:47 2015 (r287392)
@@ -1,5 +1,11 @@
# $FreeBSD$
+.include <bsd.own.mk>
+
PROG= timeout
+.if ${MK_TESTS} != "no"
+SUBDIR+= tests
+.endif
+
.include <bsd.prog.mk>
Modified: stable/10/usr.bin/timeout/timeout.1
==============================================================================
--- head/usr.bin/timeout/timeout.1 Wed Jul 16 09:55:36 2014 (r268745)
+++ stable/10/usr.bin/timeout/timeout.1 Wed Sep 2 05:45:47 2015 (r287392)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 16, 2014
+.Dd Oct 28, 2014
.Dt TIMEOUT 1
.Os
.Sh NAME
@@ -44,12 +44,18 @@
starts the
.Ar command
with its
-.Ar args
-and kills if it is still runs after
-.Ar duration .
+.Ar args.
+If
+.Ar command
+is still running after
+.Ar duration ,
+it is killed.
+By default,
+.Ar SIGTERM.
+is sent.
.Bl -tag -width "-k time, --kill-after time"
.It Fl -preserve-status
-Always exist with the same status as
+Always exits with the same status as
.Ar command
even if it times out.
.It Fl -foreground
@@ -57,14 +63,67 @@ Do not propagate timeout to the
.Ar command
children.
.It Fl s Ar sig , Fl -signal Ar sig
-Speficy the signal to send on timeout by default
+Specify the signal to send on timeout.
+By default,
.Ar SIGTERM .
+is sent.
.It Fl k Ar time , Fl -kill-after Ar time
-Send a second kill if the
+Send a second kill signal if
.Ar command
is still running after
.Ar time
-seconds after the first signal was sent
+after the first signal was sent.
+.El
+.Sh DURATION FORMAT
+.Ar duration
+and
+.Ar time
+can be integer or decimal numbers.
+Values without unit symbols are interpreted as seconds.
+.Pp
+Supported unit symbols are:
+.Bl -tag -width indent -compact
+.It s
+seconds
+.It m
+minutes
+.It h
+hours
+.It d
+days
+.El
+.Sh EXIT STATUS
+If the timeout was not reached, the exit status of
+.Ar command
+is returned.
+.Pp
+If the timeout was reached and
+.Fl -preserve-status
+is set, the exit status of
+.Ar command
+is returned.
+If
+.Fl -preserve-status
+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.
+.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 signal 3 ,
-.Xr kill 1
+.Xr kill 1 ,
+.Xr signal 3
Modified: stable/10/usr.bin/timeout/timeout.c
==============================================================================
--- head/usr.bin/timeout/timeout.c Wed Jul 16 09:55:36 2014 (r268745)
+++ stable/10/usr.bin/timeout/timeout.c Wed Sep 2 05:45:47 2015 (r287392)
@@ -2,7 +2,7 @@
* Copyright (c) 2014 Baptiste Daroussin <bapt at FreeBSD.org>
* Copyright (c) 2014 Vsevolod Stakhov <vsevolod at FreeBSD.org>
* All rights reserved.
- *~
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -12,7 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *~
+ *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
@@ -28,20 +28,20 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/procctl.h>
#include <sys/time.h>
#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <getopt.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
-#include <getopt.h>
-#include <err.h>
-#include <spawn.h>
-#include <errno.h>
-#include <stdbool.h>
#define EXIT_TIMEOUT 124
@@ -53,6 +53,7 @@ static sig_atomic_t sig_ign = 0;
static void
usage(void)
{
+
fprintf(stderr, "Usage: %s [--signal sig | -s sig] [--preserve-status]"
" [--kill-after time | -k time] [--foreground] <duration> <command>"
" <arg ...>\n", getprogname());
@@ -68,7 +69,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 +90,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);
}
@@ -102,11 +103,11 @@ static int
parse_signal(const char *str)
{
int sig, i;
- const char *err;
+ const char *errstr;
- sig = strtonum(str, 0, sys_nsig, &err);
+ sig = strtonum(str, 0, sys_nsig, &errstr);
- if (err == NULL)
+ if (errstr == NULL)
return (sig);
if (strncasecmp(str, "SIG", 3) == 0)
str += 3;
@@ -115,8 +116,8 @@ parse_signal(const char *str)
if (strcasecmp(str, sys_signame[i]) == 0)
return (i);
}
-
- errx(EX_USAGE, "invalid signal");
+
+ errx(125, "invalid signal");
}
static void
@@ -166,13 +167,15 @@ main(int argc, char **argv)
int foreground, preserve;
int error, pstat, status;
int killsig = SIGTERM;
- int killedwith;
- pid_t pgid, pid, cpid;
+ pid_t pid, cpid;
double first_kill;
double second_kill;
bool timedout = false;
bool do_second_kill = false;
+ bool child_done = false;
struct sigaction signals;
+ struct procctl_reaper_status info;
+ struct procctl_reaper_kill killemall;
int signums[] = {
-1,
SIGTERM,
@@ -185,9 +188,8 @@ main(int argc, char **argv)
foreground = preserve = 0;
second_kill = 0;
- cpid = -1;
- struct option longopts[] = {
+ const struct option longopts[] = {
{ "preserve-status", no_argument, &preserve, 1 },
{ "foreground", no_argument, &foreground, 1 },
{ "kill-after", required_argument, NULL, 'k'},
@@ -225,10 +227,9 @@ main(int argc, char **argv)
argv++;
if (!foreground) {
- pgid = setpgid(0,0);
-
- if (pgid == -1)
- err(EX_OSERR, "setpgid()");
+ /* Aquire a reaper */
+ if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1)
+ err(EX_OSERR, "Fail to acquire the reaper");
}
memset(&signals, 0, sizeof(signals));
@@ -260,8 +261,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)
@@ -270,29 +275,44 @@ main(int argc, char **argv)
/* parent continues here */
set_interval(first_kill);
- sigemptyset(&signals.sa_mask);
-
for (;;) {
- killedwith = killsig;
sigemptyset(&signals.sa_mask);
sigsuspend(&signals.sa_mask);
if (sig_chld) {
sig_chld = 0;
- while (((cpid = wait(&status)) < 0) && errno != EINTR)
- continue;
- if (cpid == pid) {
- pstat = status;
- break;
+ while ((cpid = waitpid(-1, &status, WNOHANG)) != 0) {
+ if (cpid < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ } else if (cpid == pid) {
+ pstat = status;
+ child_done = true;
+ }
+ }
+ if (child_done) {
+ if (foreground) {
+ break;
+ } else {
+ procctl(P_PID, getpid(),
+ PROC_REAP_STATUS, &info);
+ if (info.rs_children == 0)
+ break;
+ }
}
} else if (sig_alrm) {
sig_alrm = 0;
timedout = true;
- if (!foreground)
- killpg(pgid, killsig);
- else
+ if (!foreground) {
+ killemall.rk_sig = killsig;
+ killemall.rk_flags = 0;
+ procctl(P_PID, getpid(), PROC_REAP_KILL,
+ &killemall);
+ } else
kill(pid, killsig);
if (do_second_kill) {
@@ -304,9 +324,12 @@ main(int argc, char **argv)
break;
} else if (sig_term) {
- if (!foreground)
- killpg(pgid, killsig);
- else
+ if (!foreground) {
+ killemall.rk_sig = sig_term;
+ killemall.rk_flags = 0;
+ procctl(P_PID, getpid(), PROC_REAP_KILL,
+ &killemall);
+ } else
kill(pid, sig_term);
if (do_second_kill) {
@@ -319,18 +342,21 @@ main(int argc, char **argv)
}
}
- while (cpid != pid && wait(&pstat) == -1) {
+ while (!child_done && wait(&pstat) == -1) {
if (errno != EINTR)
err(EX_OSERR, "waitpid()");
}
+ if (!foreground)
+ procctl(P_PID, getpid(), PROC_REAP_RELEASE, NULL);
+
if (WEXITSTATUS(pstat))
pstat = WEXITSTATUS(pstat);
else if(WIFSIGNALED(pstat))
pstat = 128 + WTERMSIG(pstat);
if (timedout && !preserve)
- pstat = EXIT_TIMEOUT;
+ pstat = EXIT_TIMEOUT;
return (pstat);
}
More information about the svn-src-stable-10
mailing list