xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-core/sysvinit/sysvinit/pidof-add-m-option.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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