This source file includes following definitions.
- get_ppid_of
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <config.h>
19
20
21 #include "get_ppid_of.h"
22
23 #include <stdio.h>
24 #include <string.h>
25
26 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__ || defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__ || defined __minix || defined __sun
27 # include <fcntl.h>
28 # include <unistd.h>
29 #endif
30
31 #if defined __OpenBSD__
32 # include <sys/sysctl.h>
33 #endif
34
35 #if defined __APPLE__ && defined __MACH__
36
37
38
39 # include <AvailabilityMacros.h>
40 # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
41 # include <libproc.h>
42 # endif
43 #endif
44
45 #if defined _AIX
46 # include <procinfo.h>
47 #endif
48
49 #if defined __hpux
50 # include <unistd.h>
51 # include <sys/param.h>
52 # include <sys/pstat.h>
53 #endif
54
55 #if defined __sgi
56 # include <unistd.h>
57 # include <fcntl.h>
58 # include <sys/procfs.h>
59 #endif
60
61 #if defined __CYGWIN__
62 # define WIN32_LEAN_AND_MEAN
63 # include <windows.h>
64 # include <sys/cygwin.h>
65 #endif
66
67 #if defined __BEOS__ || defined __HAIKU__
68 # include <unistd.h>
69 #endif
70
71 pid_t
72 get_ppid_of (pid_t pid)
73 {
74 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__
75
76
77
78
79 char filename[6 + 10 + 7 + 1];
80 int fd;
81
82 sprintf (filename, "/proc/%u/status", (unsigned int) pid);
83 fd = open (filename, O_RDONLY | O_CLOEXEC);
84 if (fd >= 0)
85 {
86 char buf[4096 + 1];
87 ssize_t nread = read (fd, buf, sizeof (buf) - 1);
88 close (fd);
89 if (nread >= 0)
90 {
91 char *bufend = buf + nread;
92 char *p;
93
94
95 *bufend = '\0';
96
97
98 for (p = buf;;)
99 {
100 if (bufend - p >= 5 && memcmp (p, "PPid:", 5) == 0)
101 {
102 unsigned int ppid = 0;
103 if (sscanf (p + 5, "%u", &ppid) > 0)
104 return ppid;
105 }
106 p = strchr (p, '\n');
107 if (p != NULL)
108 p++;
109 else
110 break;
111 }
112 }
113 }
114
115 #endif
116
117 #if defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__
118
119
120 char filename[6 + 10 + 7 + 1];
121 int fd;
122
123 sprintf (filename, "/proc/%u/status", (unsigned int) pid);
124 fd = open (filename, O_RDONLY | O_CLOEXEC);
125 if (fd >= 0)
126 {
127 char buf[4096 + 1];
128 ssize_t nread = read (fd, buf, sizeof (buf) - 1);
129 close (fd);
130 if (nread >= 0)
131 {
132 char *p;
133
134
135 buf[nread] = '\0';
136
137
138 p = strchr (buf, ' ');
139 if (p != NULL)
140 {
141 p = strchr (p + 1, ' ');
142 if (p != NULL)
143 {
144 unsigned int ppid = 0;
145 if (sscanf (p + 1, "%u", &ppid) > 0)
146 return ppid;
147 }
148 }
149 }
150 }
151
152 #endif
153
154 #if defined __minix
155
156
157 char filename[6 + 10 + 7 + 1];
158 int fd;
159
160 sprintf (filename, "/proc/%u/psinfo", (unsigned int) pid);
161 fd = open (filename, O_RDONLY | O_CLOEXEC);
162 if (fd >= 0)
163 {
164 char buf[4096 + 1];
165 ssize_t nread = read (fd, buf, sizeof (buf) - 1);
166 close (fd);
167 if (nread >= 0)
168 {
169 char *p;
170 int count;
171
172
173 buf[nread] = '\0';
174
175
176 p = strchr (buf, ' ');
177 for (count = 1; p != NULL && count < 15; count++)
178 p = strchr (p + 1, ' ');
179 if (p != NULL)
180 {
181 unsigned int ppid = 0;
182 if (sscanf (p + 1, "%u", &ppid) > 0)
183 return ppid;
184 }
185 }
186 }
187
188 #endif
189
190 #if defined __sun
191
192
193
194
195 char filename[6 + 10 + 7 + 1];
196 int fd;
197
198 sprintf (filename, "/proc/%u/psinfo", (unsigned int) pid);
199 fd = open (filename, O_RDONLY | O_CLOEXEC);
200 if (fd >= 0)
201 {
202
203
204
205
206 #if defined __LP64__
207 # define PSINFO_SIZE 416
208 #else
209 # define PSINFO_SIZE 336
210 #endif
211 union { char all[PSINFO_SIZE]; unsigned int header[11]; } buf;
212 ssize_t nread = read (fd, buf.all, sizeof (buf.all));
213 close (fd);
214 if (nread >= (ssize_t) sizeof (buf.header))
215 return buf.header[3];
216 }
217
218 #endif
219
220 #if defined __OpenBSD__
221
222
223 int info_path[] =
224 { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, sizeof (struct kinfo_proc), 1 };
225 struct kinfo_proc info;
226 size_t len;
227
228 len = sizeof (info);
229 if (sysctl (info_path, 6, &info, &len, NULL, 0) >= 0 && len == sizeof (info))
230 return info.p_ppid;
231
232 #endif
233
234 #if defined __APPLE__ && defined __MACH__
235 # if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
236
237
238 # if defined PROC_PIDT_SHORTBSDINFO
239 struct proc_bsdshortinfo info;
240
241 if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info))
242 == sizeof (info))
243 return info.pbsi_ppid;
244 # endif
245
246 # if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
247
248
249
250
251
252 struct proc_bsdinfo info;
253
254 if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128)
255 return info.pbi_ppid;
256 # endif
257
258 # endif
259 #endif
260
261 #if defined _AIX
262
263
264
265 struct procentry64 procs;
266 if (getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1) > 0)
267 return procs.pi_ppid;
268
269 #endif
270
271 #if defined __hpux
272
273 struct pst_status status;
274 if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
275 return status.pst_ppid;
276 else
277 {
278 # if !defined __LP64__
279
280
281
282
283
284 char status64[1216];
285 if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
286 return *(unsigned long long *)(status64 + 24);
287 # endif
288 }
289
290 #endif
291
292 #if defined __sgi
293
294 char filename[12 + 10 + 1];
295 int fd;
296
297 sprintf (filename, "/proc/pinfo/%u", pid);
298 fd = open (filename, O_RDONLY | O_CLOEXEC);
299 if (0 <= fd)
300 {
301 prpsinfo_t buf;
302 int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
303 close (fd);
304 if (ioctl_ok)
305 return buf.pr_ppid;
306 }
307
308 #endif
309
310 #if defined __CYGWIN__
311
312 struct external_pinfo *info =
313 (struct external_pinfo *) cygwin_internal (CW_GETPINFO, pid);
314 if (info != NULL)
315 return info->ppid;
316
317 #endif
318
319 #if defined __BEOS__ || defined __HAIKU__
320
321 if (pid == getpid ())
322 return getppid ();
323
324 #endif
325
326 return 0;
327 }
328
329 #ifdef TEST
330
331 #include <stdlib.h>
332 #include <unistd.h>
333
334
335
336
337 int
338 main (int argc, char *argv[])
339 {
340 char *arg = argv[1];
341 pid_t pid = (arg != NULL ? atoi (arg) : getpid ());
342 pid_t parent = get_ppid_of (pid);
343 printf ("PID=%lu PPID=%lu\n", (unsigned long) pid, (unsigned long) parent);
344 return 0;
345 }
346
347
348
349
350
351
352
353 #endif