Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Dec 1997 12:40:05 -0600 (CST)
From:      Dave Bodenstab <imdave@mcs.net>
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   bin/5322: enhancement for kill(1) to search for a file ``/var/run/*pid''
Message-ID:  <199712161840.MAA05349@base586.home.org>
Resent-Message-ID: <199712161840.KAA17100@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         5322
>Category:       bin
>Synopsis:       enhancement for kill(1) to search for a file ``/var/run/*pid''
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 16 10:40:00 PST 1997
>Last-Modified:
>Originator:     Dave Bodenstab
>Organization:
myself
>Release:        FreeBSD 2.2.5-RELEASE i386
>Environment:

	run kill(1) as root

>Description:

	It's really convenient to be able to name a process to be sent
	a signal by name rather than having to do a ``ps'' and search for
	the correct pid.  Since many of the system daemons write a file
	with a name that matches the pattern "/var/run/.*[-.]pid", why
	not make use of it?

	This patch modifies kill(1) to treat a non-numeric process-id argument
	as a partial pattern.  This partial pattern is used to construct the
	regular expression "<partial pattern>[-.]pid".  For instance, a ``kill
	-1 sendmail'' constructs the pattern "^\\s\\e\\n\\d\\m\\a\\i\\l[-.]pid"
	If the effective uid is root, and a file is found in /var/run that matches
	the pattern, and the first item read from the file is a positive
	number greater than zero, then that number is take to be a process-id.

	Thus, kill(1) will now allow the super-user to specify process-id's
	by name in addition to by number.
	
>How-To-Repeat:
>Fix:
	
--- kill.1	1997/11/22 00:54:34	225.0
+++ kill.1	1997/11/22 00:58:04	225.0.1.1
@@ -64,6 +64,16 @@
 .Pp
 Only the super-user may send signals to other users' processes.
 .Pp
+If the kill utility is run with an effective user id of zero (the
+super-user,) then a non-numeric pid operand with an initial alphabetic
+character will initiate
+a search of the \fB/var/run\fP directory for files matching the
+non case-sensitive regular expression "^\fIpid\fP[-.]pid$".
+If a matching file is found, and if the first item read from the file
+is a positive
+decimal integer greater than zero, then that number is taken to be the
+process-id of the process to receive the signal.
+.Pp
 The options are as follows:
 .Pp
 .Bl -tag -width Ds
@@ -137,6 +147,8 @@
 .Nm kill
 command appeared in
 .At v6 .
+.br
+Pid-file search enhancement by Dave Bodenstab <imdave@mcs.net>.
 .Sh BUGS
 A replacement for the command
 .Dq Li kill 0
--- kill.c	1997/11/22 00:54:34	225.0
+++ kill.c	1997/11/22 00:58:04	225.0.1.1
@@ -43,13 +43,18 @@
 static char const sccsid[] = "@(#)kill.c	8.4 (Berkeley) 4/28/95";
 #endif /* not lint */
 
+#include <sys/types.h>
 #include <ctype.h>
+#include <dirent.h>
 #include <err.h>
 #include <errno.h>
+#include <paths.h>
+#include <regex.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 
 void nosig __P((char *));
 void printsignals __P((FILE *));
@@ -124,7 +129,7 @@
 
 	for (errors = 0; argc; argc--, argv++) {
 		pid = strtol(*argv, &ep, 10);
-		if (!**argv || *ep) {
+ 		if ((!**argv || *ep) && !pidfile(*argv,&pid)) {
 			warnx("illegal process id: %s", *argv);
 			errors = 1;
 		} else if (kill(pid, numsig) == -1) {
@@ -134,6 +139,89 @@
 	}
 
 	exit(errors);
+}
+
+/*
+ * If ROOT, then look for a file _PATH_VARRUN file "[-.]pid"
+ * and, if found, extract the pid
+ */
+int
+pidfile(file, pidp)
+	char *file;
+	int *pidp;
+{
+	static char suffix[] = "[-.]pid$";
+	char *path, *pattern, *p;
+	int rc, c, length;
+	FILE *fp;
+	DIR *dirp;
+	struct dirent *dp;
+	regex_t re;
+	struct stat statbuf;
+
+	if (file == NULL || ! isalpha(*file) || geteuid() != 0)
+		return 0;
+
+				/* sizeof(suffix) includes the NUL */
+	length = 1 + 2 * strlen(file) + sizeof(suffix);
+
+	if ((pattern = malloc(length)) == NULL)
+		return 0;
+
+	pattern[0] = '^';
+	for(p = pattern + 1; (c = *file++) != '\0'; *p++ = c)
+		*p++ = '\\';
+	strcpy(p, suffix);
+
+	if (regcomp(&re,pattern, REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0) {
+		free(pattern);
+		return 0;
+	}
+
+	if ((dirp = opendir(_PATH_VARRUN)) == NULL) {
+		regfree(&re);
+		free(pattern);
+		return 0;
+	}
+
+	rc = 0;
+
+	while((dp = readdir(dirp)) != NULL) {
+		if (regexec(&re, dp->d_name, 0, NULL, 0) == 0) {
+			/*
+			 * A match...  (only the first match is considered)
+			 */
+			length = strlen(_PATH_VARRUN) + 1 + strlen(dp->d_name) + 1;
+
+			if ((path = malloc(length)) == NULL)
+				/* just quit */
+				break;
+
+			strcpy(path, _PATH_VARRUN);
+			strcat(path, "/");
+			strcat(path, dp->d_name);
+
+			if (stat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) {
+				if ((fp = fopen(path, "r")) != NULL) {
+					if (fscanf(fp, " %d", pidp) == 1 && *pidp > 0)
+						/*
+						 * ...and we have the pid!
+						 */
+						rc = 1;
+
+					fclose(fp);
+				}
+			}
+
+			free(path);
+			break;
+		}
+	}
+
+	closedir(dirp);
+	regfree(&re);
+	free(pattern);
+	return rc;
 }
 
 int

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199712161840.MAA05349>