1From 96fb53ef2ccd2580cf0aa565ef1629cb05eae50a Mon Sep 17 00:00:00 2001 2From: Hongxu Jia <hongxu.jia@windriver.com> 3Date: Wed, 24 Jul 2013 17:07:22 +0800 4Subject: [PATCH] pidof: add -m option 5 6When used with -o, will also omit any processes that have the same 7argv[0] and argv[1] as any explicitly omitted process ids. This can be 8used to avoid multiple shell scripts concurrently calling pidof returning 9each other's pids. 10 11https://bugzilla.redhat.com/show_bug.cgi?id=883856 12 13Upstream-Status: Backport 14Imported patch from: https://bugzilla.redhat.com/attachment.cgi?id=658166 15 16Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> 17 18--- 19 man/pidof.8 | 6 +++++ 20 src/killall5.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--- 21 2 files changed, 65 insertions(+), 3 deletions(-) 22 23diff --git a/man/pidof.8 b/man/pidof.8 24index 84ed1e4..ac184da 100644 25--- a/man/pidof.8 26+++ b/man/pidof.8 27@@ -25,6 +25,7 @@ pidof -- find the process ID of a running program. 28 .RB [ \-n ] 29 .RB [ \-x ] 30 .RB [ \-z ] 31+.RB [ \-m ] 32 .RB [ \-o 33 .IR omitpid[,omitpid...] ] 34 .RB [ \-o 35@@ -79,6 +80,11 @@ is shown. The default separator is a space. 36 Tells \fIpidof\fP to omit processes with that process id. The special 37 pid \fB%PPID\fP can be used to name the parent process of the \fIpidof\fP 38 program, in other words the calling shell or shell script. 39+.IP -m 40+When used with -o, will also omit any processes that have the same 41+argv[0] and argv[1] as any explicitly omitted process ids. This can be 42+used to avoid multiple shell scripts concurrently calling pidof returning 43+each other's pids. 44 .SH "EXIT STATUS" 45 .TP 46 .B 0 47diff --git a/src/killall5.c b/src/killall5.c 48index b0728fa..72289e3 100644 49--- a/src/killall5.c 50+++ b/src/killall5.c 51@@ -121,6 +121,7 @@ typedef struct _s_nfs 52 53 /* List of processes. */ 54 PROC *plist; 55+PROC *olist; 56 57 /* List of processes to omit. */ 58 OMIT *omit; 59@@ -356,6 +357,20 @@ static void clear_mnt(void) 60 } 61 } 62 63+static void clear_omit(void) 64+{ 65+ OMIT *o; 66+ PROC *p; 67+ for (o = omit; o; o = omit) { 68+ omit = omit->next; 69+ free(o); 70+ } 71+ for (p = olist; p; p = olist) { 72+ olist = olist->next; 73+ free(p); 74+ } 75+} 76+ 77 /* 78 * Check if path is a shadow off a NFS partition. 79 */ 80@@ -481,6 +496,7 @@ int readproc() 81 DIR *dir; 82 FILE *fp; 83 PROC *p, *n; 84+ OMIT *o, *m; 85 struct dirent *d; 86 char path[PATH_MAX+1]; 87 char buf[PATH_MAX+1]; 88@@ -670,6 +686,17 @@ int readproc() 89 p->next = plist; 90 plist = p; 91 p->pid = pid; 92+ /* Could be smarter, but it's a small list. */ 93+ m = omit; 94+ for (o = omit; m; o = m) { 95+ m = o->next; 96+ if (o->pid == p->pid) { 97+ n = (PROC*)xmalloc(sizeof(PROC)); 98+ *n = *p; 99+ n->next = olist; 100+ olist = n; 101+ } 102+ } 103 } 104 closedir(dir); 105 106@@ -870,6 +897,26 @@ PIDQ_HEAD *pidof(char *prog) 107 return q; 108 } 109 110+int matches(PROC *o, PROC *p) 111+{ 112+ int ret = 0; 113+ char *oargv1, *pargv1; 114+ if ((o->argv0 && p->argv0 && !strcmp(o->argv0,p->argv0))) { 115+ if (o->argv1 && p->argv1) { 116+ if ((oargv1 = canonicalize_file_name(o->argv1)) == NULL) 117+ oargv1 = strdup(o->argv1); 118+ if ((pargv1 = canonicalize_file_name(p->argv1)) == NULL) 119+ pargv1 = strdup(p->argv1); 120+ if (! strcmp(oargv1, pargv1)) { 121+ ret = 1; 122+ } 123+ free(oargv1); 124+ free(pargv1); 125+ } 126+ } 127+ return ret; 128+} 129+ 130 /* Give usage message and exit. */ 131 void usage(void) 132 { 133@@ -920,6 +967,7 @@ void nsyslog(int pri, char *fmt, ...) 134 #define PIDOF_OMIT 0x02 135 #define PIDOF_NETFS 0x04 136 #define PIDOF_QUIET 0x08 137+#define PIDOF_OMIT_OMIT_MATCHES 0x08 138 139 /* 140 * Pidof functionality. 141@@ -937,6 +985,7 @@ int main_pidof(int argc, char **argv) 142 char tmp[512]; 143 char sep = ' '; 144 145+ olist = (PROC*)0; 146 omit = (OMIT*)0; 147 nlist = (NFS*)0; 148 opterr = 0; 149@@ -944,7 +993,7 @@ int main_pidof(int argc, char **argv) 150 if ((token = getenv("PIDOF_NETFS")) && (strcmp(token,"no") != 0)) 151 flags |= PIDOF_NETFS; 152 153- while ((opt = getopt(argc,argv,"qhco:d:sxzn")) != EOF) switch (opt) { 154+ while ((opt = getopt(argc,argv,"qhcmo:d:sxzn")) != EOF) switch (opt) { 155 case '?': 156 nsyslog(LOG_ERR,"invalid options on command line!\n"); 157 closelog(); 158@@ -995,6 +1044,9 @@ int main_pidof(int argc, char **argv) 159 case 'z': 160 list_dz_processes = TRUE; 161 break; 162+ case 'm': 163+ flags |= PIDOF_OMIT_OMIT_MATCHES; 164+ break; 165 case 'n': 166 flags |= PIDOF_NETFS; 167 break; 168@@ -1026,10 +1078,13 @@ int main_pidof(int argc, char **argv) 169 pid_t spid = 0; 170 while ((p = get_next_from_pid_q(q))) { 171 if ((flags & PIDOF_OMIT) && omit) { 172- OMIT * optr; 173- for (optr = omit; optr; optr = optr->next) { 174+ PROC * optr; 175+ for (optr = olist; optr; optr = optr->next) { 176 if (optr->pid == p->pid) 177 break; 178+ if (flags & PIDOF_OMIT_OMIT_MATCHES) 179+ if (matches(optr, p)) 180+ break; 181 } 182 183 /* 184@@ -1071,6 +1126,7 @@ int main_pidof(int argc, char **argv) 185 printf("\n"); 186 } 187 188+ clear_omit(); 189 clear_mnt(); 190 191 closelog(); 192