| From 0e441712d0e366a0384ff3fa879f5a2d2607c24f 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 6866cb3..a87d878 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 |
| @@ -77,6 +78,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 \fBpidof\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 b0728fa..72289e3 100644 |
| --- a/src/killall5.c |
| +++ b/src/killall5.c |
| @@ -121,6 +121,7 @@ typedef struct _s_nfs |
| |
| /* List of processes. */ |
| PROC *plist; |
| +PROC *olist; |
| |
| /* List of processes to omit. */ |
| OMIT *omit; |
| @@ -356,6 +357,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. |
| */ |
| @@ -481,6 +496,7 @@ int readproc() |
| DIR *dir; |
| FILE *fp; |
| PROC *p, *n; |
| + OMIT *o, *m; |
| struct dirent *d; |
| char path[PATH_MAX+1]; |
| char buf[PATH_MAX+1]; |
| @@ -670,6 +686,17 @@ int readproc() |
| 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); |
| |
| @@ -870,6 +897,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) |
| { |
| @@ -920,6 +967,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. |
| @@ -937,6 +985,7 @@ int main_pidof(int argc, char **argv) |
| char tmp[512]; |
| char sep = ' '; |
| |
| + olist = (PROC*)0; |
| omit = (OMIT*)0; |
| nlist = (NFS*)0; |
| opterr = 0; |
| @@ -944,7 +993,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(); |
| @@ -995,6 +1044,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; |
| @@ -1026,10 +1078,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; |
| } |
| |
| /* |
| @@ -1071,6 +1126,7 @@ int main_pidof(int argc, char **argv) |
| printf("\n"); |
| } |
| |
| + clear_omit(); |
| clear_mnt(); |
| |
| closelog(); |