Subject: kill(1) a pid after timeout
To: None <tech-userlevel@netbsd.org>
From: Jan Schaumann <jschauma@netmeister.org>
List: tech-userlevel
Date: 07/24/2007 10:47:46
--ghzN8eJ9Qlbqn3iT
Content-Type: multipart/mixed; boundary="oC1+HKm2/end4ao3"
Content-Disposition: inline
--oC1+HKm2/end4ao3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
Hi,
I occasionally have the need to kill a process iff it has been running
for longer than N seconds. Instead of parsing the output of ps(1) and
then calling kill(1) myself, I have attached a patch to add the "-t
timeout" flag to kill(1).
Does that seem useful to others as well?
-Jan
--=20
Defending Freedom in the Digital World:
--- Electronic Frontier Foundation -- http://www.eff.org ---
--oC1+HKm2/end4ao3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
Content-Transfer-Encoding: quoted-printable
Index: Makefile
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/bin/kill/Makefile,v
retrieving revision 1.8
diff -b -u -r1.8 Makefile
--- Makefile 20 Jul 1997 22:37:09 -0000 1.8
+++ Makefile 21 Jul 2007 18:23:01 -0000
@@ -2,5 +2,7 @@
# @(#)Makefile 8.1 (Berkeley) 5/31/93
=20
PROG=3D kill
+DPADD=3D ${LIBKVM}
+LDADD=3D -lkvm
=20
.include <bsd.prog.mk>
Index: kill.1
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/bin/kill/kill.1,v
retrieving revision 1.18
diff -b -u -r1.18 kill.1
--- kill.1 7 Aug 2003 09:05:13 -0000 1.18
+++ kill.1 21 Jul 2007 18:23:01 -0000
@@ -41,6 +41,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl s Ar signal_name
+.Op Fl t Ar timeout
.Ar pid
\&...
.Nm
@@ -48,10 +49,12 @@
.Op Ar signal_number
.Nm
.Fl signal_name
+.Op Fl t Ar timeout
.Ar pid
\&...
.Nm
.Fl signal_number
+.Op Fl t Ar timeout
.Ar pid
\&...
.Sh DESCRIPTION
@@ -69,6 +72,10 @@
A symbolic signal name specifying the signal to be sent instead of the
default
.Dv TERM .
+.It Fl t Ar timeout
+Only kill the given process(es) if they have been running for longer than
+Ar timeout
+seconds.
.It Fl l Op Ar signal_number
If no operand is given, list the signal names; otherwise, write
the signal name corresponding to
Index: kill.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/bin/kill/kill.c,v
retrieving revision 1.24
diff -b -u -r1.24 kill.c
--- kill.c 17 Mar 2006 22:30:11 -0000 1.24
+++ kill.c 21 Jul 2007 18:23:01 -0000
@@ -46,6 +46,8 @@
#include <ctype.h>
#include <err.h>
#include <errno.h>
+#include <kvm.h>
+#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -53,7 +55,9 @@
#include <termios.h>
#include <unistd.h>
#include <locale.h>
+#include <sys/param.h>
#include <sys/ioctl.h>
+#include <sys/sysctl.h>
=20
#ifdef SHELL /* sh (aka ash) builtin */
#define main killcmd
@@ -69,8 +73,9 @@
int
main(int argc, char *argv[])
{
- int errors, numsig, pid;
+ int errors, numsig, pid, timeout;
char *ep;
+ kvm_t *kd;
=20
setprogname(argv[0]);
setlocale(LC_ALL, "");
@@ -78,6 +83,8 @@
usage();
=20
numsig =3D SIGTERM;
+ timeout =3D 0;
+ kd =3D NULL;
=20
argc--, argv++;
if (strcmp(*argv, "-l") =3D=3D 0) {
@@ -104,6 +111,21 @@
exit(0);
}
=20
+ if (!strcmp(*argv, "-t")) {
+ argc--, argv++;
+ if (argc < 1) {
+ warnx("option requires an argument -- t");
+ usage();
+ }
+ timeout =3D strtol(*argv, &ep, 10);
+ if (*ep) {
+ errx(EXIT_FAILURE, "illegal signal number: %s",
+ *argv);
+ /* NOTREACHED */
+ }
+ argc--, argv++;
+ }
+
if (!strcmp(*argv, "-s")) {
argc--, argv++;
if (argc < 1) {
@@ -138,7 +160,16 @@
if (argc =3D=3D 0)
usage();
=20
+ if (timeout) {
+ char errbuf[_POSIX2_LINE_MAX];
+ kd =3D kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
+ if (kd =3D=3D 0)
+ errx(1, "%s", errbuf);
+ /* NOTREACHED */
+ }
+
for (errors =3D 0; argc; argc--, argv++) {
+ int do_kill =3D 1;
#ifdef SHELL
extern int getjobpgrp(const char *);
if (*argv[0] =3D=3D '%') {
@@ -158,10 +189,29 @@
continue;
}
}
+
+ if (timeout) {
+ struct kinfo_proc2 *kinfo;
+ int nentries;
+
+ do_kill =3D 0;
+
+ if (!(kinfo =3D kvm_getproc2(kd, KERN_PROC_PID, pid,
+ sizeof(struct kinfo_proc2), &nentries)))
+ err(1, "%s", kvm_geterr(kd));
+ /* NOTREACHED */
+
+ if (kinfo->p_ustart_sec < (time(NULL) - timeout)) {
+ do_kill =3D 1;
+ }
+ }
+
+ if (do_kill) {
if (kill(pid, numsig) =3D=3D -1) {
warn("%s", *argv);
errors =3D 1;
}
+ }
#ifdef SHELL
/* Wakeup the process if it was suspended, so it can
exit without an explicit 'fg'. */
@@ -233,10 +283,10 @@
usage(void)
{
=20
- fprintf(stderr, "usage: %s [-s signal_name] pid ...\n"
+ fprintf(stderr, "usage: %s [-s signal_name] [-t timeout] pid ...\n"
" %s -l [exit_status]\n"
- " %s -signal_name pid ...\n"
- " %s -signal_number pid ...\n",
+ " %s -signal_name [-t timeout] pid ...\n"
+ " %s -signal_number [-t timeout] pid ...\n",
getprogname(), getprogname(), getprogname(), getprogname());
exit(1);
/* NOTREACHED */
--oC1+HKm2/end4ao3--
--ghzN8eJ9Qlbqn3iT
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (NetBSD)
iD8DBQFGpjtCfFtkr68iakwRAhrPAKDpbnOrdBlFsnR+zGFh+j1LI1spLwCgo2+e
bdAzPuCGPZ0hXJYU9so8gO0=
=Tt+f
-----END PGP SIGNATURE-----
--ghzN8eJ9Qlbqn3iT--