blob: 494aa0e01266a45fa0aa672c0393dedcc433a3f9 [file] [log] [blame]
From 6c490ea6579a132fabb7dbd25387bb521f820371 Mon Sep 17 00:00:00 2001
From: Hongxu Jia <hongxu.jia@windriver.com>
Date: Wed, 24 Jul 2013 17:07:22 +0800
Subject: [PATCH] pidof: add -m option
When used with -o, will also omit any processes that have the same
argv[0] and argv[1] as any explicitly omitted process ids. This can be
used to avoid multiple shell scripts concurrently calling pidof returning
each other's pids.
https://bugzilla.redhat.com/show_bug.cgi?id=883856
Upstream-Status: backport
Imported patch from: https://bugzilla.redhat.com/attachment.cgi?id=658166
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
---
man/pidof.8 | 6 +++++
src/killall5.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/man/pidof.8 b/man/pidof.8
index ebe5f55..2fdc4d3 100644
--- a/man/pidof.8
+++ b/man/pidof.8
@@ -25,6 +25,7 @@ pidof -- find the process ID of a running program.
.RB [ \-n ]
.RB [ \-x ]
.RB [ \-z ]
+.RB [ \-m ]
.RB [ \-o
.IR omitpid[,omitpid...] ]
.RB [ \-o
@@ -76,6 +77,11 @@ is shown. The default separator is a space.
Tells \fIpidof\fP to omit processes with that process id. The special
pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP
program, in other words the calling shell or shell script.
+.IP -m
+When used with -o, will also omit any processes that have the same
+argv[0] and argv[1] as any explicitly omitted process ids. This can be
+used to avoid multiple shell scripts concurrently calling pidof returning
+each other's pids.
.SH "EXIT STATUS"
.TP
.B 0
diff --git a/src/killall5.c b/src/killall5.c
index 8b5cb38..a664954 100644
--- a/src/killall5.c
+++ b/src/killall5.c
@@ -126,6 +126,7 @@ typedef struct _s_nfs
/* List of processes. */
PROC *plist;
+PROC *olist;
/* List of processes to omit. */
OMIT *omit;
@@ -361,6 +362,20 @@ static void clear_mnt(void)
}
}
+static void clear_omit(void)
+{
+ OMIT *o;
+ PROC *p;
+ for (o = omit; o; o = omit) {
+ omit = omit->next;
+ free(o);
+ }
+ for (p = olist; p; p = olist) {
+ olist = olist->next;
+ free(p);
+ }
+}
+
/*
* Check if path is a shadow off a NFS partition.
*/
@@ -486,6 +501,7 @@ int readproc(int do_stat)
DIR *dir;
FILE *fp;
PROC *p, *n;
+ OMIT *o, *m;
struct dirent *d;
struct stat st;
char path[PATH_MAX+1];
@@ -733,6 +749,17 @@ int readproc(int do_stat)
p->next = plist;
plist = p;
p->pid = pid;
+ /* Could be smarter, but it's a small list. */
+ m = omit;
+ for (o = omit; m; o = m) {
+ m = o->next;
+ if (o->pid == p->pid) {
+ n = (PROC*)xmalloc(sizeof(PROC));
+ *n = *p;
+ n->next = olist;
+ olist = n;
+ }
+ }
}
closedir(dir);
@@ -944,6 +971,26 @@ PIDQ_HEAD *pidof(char *prog)
return q;
}
+int matches(PROC *o, PROC *p)
+{
+ int ret = 0;
+ char *oargv1, *pargv1;
+ if ((o->argv0 && p->argv0 && !strcmp(o->argv0,p->argv0))) {
+ if (o->argv1 && p->argv1) {
+ if ((oargv1 = canonicalize_file_name(o->argv1)) == NULL)
+ oargv1 = strdup(o->argv1);
+ if ((pargv1 = canonicalize_file_name(p->argv1)) == NULL)
+ pargv1 = strdup(p->argv1);
+ if (! strcmp(oargv1, pargv1)) {
+ ret = 1;
+ }
+ free(oargv1);
+ free(pargv1);
+ }
+ }
+ return ret;
+}
+
/* Give usage message and exit. */
void usage(void)
{
@@ -994,6 +1041,7 @@ void nsyslog(int pri, char *fmt, ...)
#define PIDOF_OMIT 0x02
#define PIDOF_NETFS 0x04
#define PIDOF_QUIET 0x08
+#define PIDOF_OMIT_OMIT_MATCHES 0x08
/*
* Pidof functionality.
@@ -1011,6 +1059,7 @@ int main_pidof(int argc, char **argv)
char tmp[512];
char sep = ' ';
+ olist = (PROC*)0;
omit = (OMIT*)0;
nlist = (NFS*)0;
opterr = 0;
@@ -1018,7 +1067,7 @@ int main_pidof(int argc, char **argv)
if ((token = getenv("PIDOF_NETFS")) && (strcmp(token,"no") != 0))
flags |= PIDOF_NETFS;
- while ((opt = getopt(argc,argv,"qhco:d:sxzn")) != EOF) switch (opt) {
+ while ((opt = getopt(argc,argv,"qhcmo:d:sxzn")) != EOF) switch (opt) {
case '?':
nsyslog(LOG_ERR,"invalid options on command line!\n");
closelog();
@@ -1069,6 +1118,9 @@ int main_pidof(int argc, char **argv)
case 'z':
list_dz_processes = TRUE;
break;
+ case 'm':
+ flags |= PIDOF_OMIT_OMIT_MATCHES;
+ break;
case 'n':
flags |= PIDOF_NETFS;
break;
@@ -1100,10 +1152,13 @@ int main_pidof(int argc, char **argv)
pid_t spid = 0;
while ((p = get_next_from_pid_q(q))) {
if ((flags & PIDOF_OMIT) && omit) {
- OMIT * optr;
- for (optr = omit; optr; optr = optr->next) {
+ PROC * optr;
+ for (optr = olist; optr; optr = optr->next) {
if (optr->pid == p->pid)
break;
+ if (flags & PIDOF_OMIT_OMIT_MATCHES)
+ if (matches(optr, p))
+ break;
}
/*
@@ -1145,6 +1200,7 @@ int main_pidof(int argc, char **argv)
printf("\n");
}
+ clear_omit();
clear_mnt();
closelog();