summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/sysvinit/sysvinit/pidof-add-m-option.patch
blob: 8ef292ed1296c0e3942d0e7e54e9ce2bce1093b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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();