Subject: pkill(1) a pid after timeout
To: None <tech-userlevel@netbsd.org>
From: Jan Schaumann <jschauma@netmeister.org>
List: tech-userlevel
Date: 07/26/2007 21:03:20
--K8nIJk4ghYZn606h
Content-Type: multipart/mixed; boundary="17pEHd4RhPHOinZp"
Content-Disposition: inline


--17pEHd4RhPHOinZp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Jan Schaumann <jschauma@netmeister.org> wrote:
=20
> 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).
>=20
> Does that seem useful to others as well?

So following our discussion, attached is a patch to pkill(1).  I've
named the option "-r runtime" to avoid the misunderstanding of
"timeout".

What say thee?

-Jan

--=20
"When it's fall in New York, the air smells as if someone's been frying
goats in it, and if you are keen to breathe the best plan is to open a
window and stick your head in a building."

--17pEHd4RhPHOinZp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
Content-Transfer-Encoding: quoted-printable

? pkill.cat1
Index: pkill.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/usr.bin/pkill/pkill.1,v
retrieving revision 1.14
diff -b -u -r1.14 pkill.1
--- pkill.1	13 Nov 2006 16:33:56 -0000	1.14
+++ pkill.1	27 Jul 2007 04:01:13 -0000
@@ -47,6 +47,7 @@
 .Op Fl G Ar gid
 .Op Fl g Ar pgrp
 .Op Fl P Ar ppid
+.Op Fl r Ar runtime
 .Op Fl s Ar sid
 .Op Fl t Ar tty
 .Op Fl U Ar uid
@@ -58,6 +59,7 @@
 .Op Fl G Ar gid
 .Op Fl g Ar pgrp
 .Op Fl P Ar ppid
+.Op Fl r Ar runtime
 .Op Fl s Ar sid
 .Op Fl t Ar tty
 .Op Fl U Ar uid
@@ -76,7 +78,7 @@
 processes that match the criteria given on the command line.
 .Pp
 The following options are available:
-.Bl -tag -width xxxxxxxx
+.Bl -tag -width xxxxxxxxxx
 .It Fl d Ar delim
 Specify a delimiter to be printed between each process ID.
 The default is a newline.
@@ -117,6 +119,9 @@
 Restrict matches to processes with a parent process ID in the
 comma-separated list
 .Ar ppid .
+.It Fl r Ar runtime
+Restrict matches to processes with a running time (ie wall clock) larger t=
han
+.Ar runtime .
 .It Fl s Ar sid
 Restrict matches to processes with a session ID in the comma-separated
 list
Index: pkill.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/usr.bin/pkill/pkill.c,v
retrieving revision 1.17
diff -b -u -r1.17 pkill.c
--- pkill.c	25 Feb 2006 01:13:55 -0000	1.17
+++ pkill.c	27 Jul 2007 04:01:13 -0000
@@ -93,6 +93,7 @@
 static int	newest;
 static int	inverse;
 static int	longfmt;
+static int	runtime;
 static int	matchargs;
 static int	fullmatch;
 static int	cflags =3D REG_EXTENDED;
@@ -159,7 +160,7 @@
=20
 	criteria =3D 0;
=20
-	while ((ch =3D getopt(argc, argv, "G:P:U:d:fg:ilns:t:u:vx")) !=3D -1)
+	while ((ch =3D getopt(argc, argv, "G:P:U:d:fg:ilnr:s:t:u:vx")) !=3D -1)
 		switch (ch) {
 		case 'G':
 			makelist(&rgidlist, LT_GROUP, optarg);
@@ -197,6 +198,15 @@
 			newest =3D 1;
 			criteria =3D 1;
 			break;
+		case 'r':
+			runtime =3D strtol(optarg, &q, 10);
+			if (*q) {
+				errx(EXIT_FAILURE, "illegal runtime: %s",
+				optarg);
+				/* NOTREACHED */
+			}
+			criteria =3D 1;
+			break;
 		case 's':
 			makelist(&sidlist, LT_SID, optarg);
 			criteria =3D 1;
@@ -288,12 +298,21 @@
 						selected[i] =3D 1;
 				} else
 					selected[i] =3D 1;
+
+				if (runtime) {
+					if (kp->p_ustart_sec < (time(NULL) - runtime)) {
+						selected[i] =3D 1;
+					} else {
+						selected[i] =3D 0;
+					}
+				}
 			} else if (rv !=3D REG_NOMATCH) {
 				(void)regerror(rv, &reg, buf, sizeof(buf));
 				errx(STATUS_ERROR,
 				    "Regular expression evaluation error (%s)",
 				    buf);
 			}
+
 		}
=20
 		regfree(&reg);
@@ -363,9 +382,15 @@
 			continue;
 		}
=20
-		if (argc =3D=3D 0)
+		if (argc =3D=3D 0) {
+			if (runtime) {
+				if (kp->p_ustart_sec < (time(NULL) - runtime)) {
+					selected[i] =3D 1;
+				}
+			} else
 			selected[i] =3D 1;
 	}
+	}
=20
 	if (newest) {
 		bestsec =3D 0;
@@ -390,6 +415,7 @@
 			selected[bestidx] =3D 1;
 	}
=20
+
 	/*
 	 * Take the appropriate action for each matched process, if any.
 	 */
@@ -422,9 +448,9 @@
 		ustr =3D "[-signal] [-finvx]";
=20
 	(void)fprintf(stderr,
-		"Usage: %s %s [-G gid] [-g pgrp] [-P ppid] [-s sid] [-t tty]\n"
-		"             [-U uid] [-u euid] pattern ...\n", getprogname(),
-		ustr);
+		"Usage: %s %s [-G gid] [-g pgrp] [-P ppid] [-r runtime]\n"
+		"             [-s sid] [-t tty] [-U uid] [-u euid] [pattern [...]]\n",
+		getprogname(), ustr);
=20
 	exit(STATUS_BADUSAGE);
 }

--17pEHd4RhPHOinZp--

--K8nIJk4ghYZn606h
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (NetBSD)

iD8DBQFGqW6HfFtkr68iakwRAsktAKDQHQvwj6+Fg7mz2fokWZKzYmq8fwCgrpAM
sQ7wZ4TJuahMmKrUGJs6yxI=
=eKLQ
-----END PGP SIGNATURE-----

--K8nIJk4ghYZn606h--