This source file includes following definitions.
- get_progname_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_progname_of.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__ || defined __NetBSD__ || defined __FreeBSD__
28 # include <unistd.h>
29 # if defined __ANDROID__
30 # include <fcntl.h>
31 # endif
32 #endif
33
34 #if defined __minix || defined __sun
35 # include <fcntl.h>
36 # include <unistd.h>
37 #endif
38
39 #if defined __OpenBSD__
40 # include <sys/sysctl.h>
41 #endif
42
43 #if defined __APPLE__ && defined __MACH__
44 # include <libproc.h>
45 #endif
46
47 #if defined _AIX
48 # include <procinfo.h>
49 #endif
50
51 #if defined __hpux
52 # include <unistd.h>
53 # include <sys/param.h>
54 # include <sys/pstat.h>
55 #endif
56
57 #if defined __sgi
58 # include <unistd.h>
59 # include <fcntl.h>
60 # include <sys/procfs.h>
61 #endif
62
63 #if defined __CYGWIN__
64 # define WIN32_LEAN_AND_MEAN
65 # include <windows.h>
66 # include <sys/cygwin.h>
67 #endif
68
69 #if defined __BEOS__ || defined __HAIKU__
70 # include <OS.h>
71 #endif
72
73 char *
74 get_progname_of (pid_t pid)
75 {
76 #if defined __linux__ || defined __ANDROID__ || (defined __FreeBSD_kernel__ && !defined __FreeBSD__) || defined __GNU__ || defined __NetBSD__
77
78
79
80
81 {
82 char filename[6 + 10 + 4 + 1];
83 char linkbuf[1024 + 1];
84 ssize_t linklen;
85
86 sprintf (filename, "/proc/%u/exe", (unsigned int) pid);
87 linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
88 if (linklen > 0)
89 {
90 char *slash;
91
92
93 linkbuf[linklen] = '\0';
94
95 slash = strrchr (linkbuf, '/');
96 return strdup (slash != NULL ? slash + 1 : linkbuf);
97 }
98 }
99
100 # if defined __ANDROID__
101
102
103 {
104 char filename[6 + 10 + 8 + 1];
105 int fd;
106
107 sprintf (filename, "/proc/%u/cmdline", (unsigned int) pid);
108 fd = open (filename, O_RDONLY | O_CLOEXEC);
109 if (fd >= 0)
110 {
111 char buf[4096 + 1];
112 ssize_t nread = read (fd, buf, sizeof (buf) - 1);
113 close (fd);
114 if (nread >= 0)
115 {
116 char *slash;
117
118
119
120 buf[nread] = '\0';
121
122
123 slash = strrchr (buf, '/');
124 return strdup (slash != NULL ? slash + 1 : buf);
125 }
126 }
127 }
128 # endif
129
130 #endif
131
132 #if defined __FreeBSD__
133
134
135 char filename[6 + 10 + 5 + 1];
136 char linkbuf[1024 + 1];
137 ssize_t linklen;
138
139 sprintf (filename, "/proc/%u/file", (unsigned int) pid);
140 linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
141 if (linklen > 0)
142 {
143 char *slash;
144
145
146 linkbuf[linklen] = '\0';
147
148 slash = strrchr (linkbuf, '/');
149 return strdup (slash != NULL ? slash + 1 : linkbuf);
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 < 3; count++)
178 p = strchr (p + 1, ' ');
179 if (p != NULL)
180 {
181 char *start = p + 1;
182 char *end = strchr (p + 1, ' ');
183 if (end != NULL)
184 {
185 *end = '\0';
186 return strdup (start);
187 }
188 }
189 }
190 }
191
192 #endif
193
194 #if defined __sun
195
196
197
198 {
199 char filename[6 + 10 + 11 + 1];
200 char linkbuf[1024 + 1];
201 ssize_t linklen;
202
203 sprintf (filename, "/proc/%u/path/a.out", (unsigned int) pid);
204 linklen = readlink (filename, linkbuf, sizeof (linkbuf) - 1);
205 if (linklen > 0)
206 {
207 char *slash;
208
209
210 linkbuf[linklen] = '\0';
211
212 slash = strrchr (linkbuf, '/');
213 return strdup (slash != NULL ? slash + 1 : linkbuf);
214 }
215 }
216
217
218
219
220
221 {
222 char filename[6 + 10 + 7 + 1];
223 int fd;
224
225 sprintf (filename, "/proc/%u/psinfo", (unsigned int) pid);
226 fd = open (filename, O_RDONLY | O_CLOEXEC);
227 if (fd >= 0)
228 {
229
230
231
232
233 #if defined __LP64__
234 # define PSINFO_SIZE 416
235 # define PSINFO_FNAME_OFFSET 136
236 #else
237 # define PSINFO_SIZE 336
238 # define PSINFO_FNAME_OFFSET 88
239 #endif
240 char buf[PSINFO_SIZE];
241 ssize_t nread = read (fd, buf, sizeof (buf));
242 close (fd);
243 if (nread >= PSINFO_FNAME_OFFSET + 16)
244 {
245
246 buf[PSINFO_FNAME_OFFSET + 16] = '\0';
247 return strdup (&buf[PSINFO_FNAME_OFFSET]);
248 }
249 }
250 }
251
252 #endif
253
254 #if defined __OpenBSD__
255
256
257 int info_path[] =
258 { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid, sizeof (struct kinfo_proc), 1 };
259 struct kinfo_proc info;
260 size_t len;
261
262 len = sizeof (info);
263 if (sysctl (info_path, 6, &info, &len, NULL, 0) >= 0 && len == sizeof (info))
264 return strdup (info.p_comm);
265
266 #endif
267
268 #if defined __APPLE__ && defined __MACH__
269
270 # if defined PROC_PIDT_SHORTBSDINFO
271 struct proc_bsdshortinfo info;
272
273 if (proc_pidinfo (pid, PROC_PIDT_SHORTBSDINFO, 0, &info, sizeof (info))
274 == sizeof (info))
275 return strdup (info.pbsi_comm);
276 # else
277
278
279
280
281 struct proc_bsdinfo info;
282
283 if (proc_pidinfo (pid, PROC_PIDTBSDINFO, 0, &info, 128) == 128)
284 return strdup (info.pbi_comm);
285 # endif
286
287 #endif
288
289 #if defined _AIX
290
291
292
293 struct procentry64 procs;
294 if (getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1) > 0)
295 return strdup (procs.pi_comm);
296
297 #endif
298
299 #if defined __hpux
300
301 char *p;
302 struct pst_status status;
303 if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
304 {
305 char *ucomm = status.pst_ucomm;
306 char *cmd = status.pst_cmd;
307 if (strlen (ucomm) < PST_UCOMMLEN - 1)
308 p = ucomm;
309 else
310 {
311
312
313 char *space = strchr (cmd, ' ');
314 if (space != NULL)
315 *space = '\0';
316 p = strrchr (cmd, '/');
317 if (p != NULL)
318 p++;
319 else
320 p = cmd;
321 if (strlen (p) > PST_UCOMMLEN - 1
322 && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
323
324 ;
325 else
326 p = ucomm;
327 }
328 p = strdup (p);
329 }
330 else
331 {
332 # if !defined __LP64__
333
334
335
336
337
338 char status64[1216];
339 if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
340 {
341 char *ucomm = status64 + 288;
342 char *cmd = status64 + 168;
343 if (strlen (ucomm) < PST_UCOMMLEN - 1)
344 p = ucomm;
345 else
346 {
347
348
349 char *space = strchr (cmd, ' ');
350 if (space != NULL)
351 *space = '\0';
352 p = strrchr (cmd, '/');
353 if (p != NULL)
354 p++;
355 else
356 p = cmd;
357 if (strlen (p) > PST_UCOMMLEN - 1
358 && memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
359
360 ;
361 else
362 p = ucomm;
363 }
364 p = strdup (p);
365 }
366 else
367 # endif
368 p = NULL;
369 }
370 if (p != NULL)
371 return strdup (p);
372
373 #endif
374
375 #if defined __sgi
376
377 char filename[12 + 10 + 1];
378 int fd;
379
380 sprintf (filename, "/proc/pinfo/%u", pid);
381 fd = open (filename, O_RDONLY | O_CLOEXEC);
382 if (0 <= fd)
383 {
384 prpsinfo_t buf;
385 int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
386 close (fd);
387 if (ioctl_ok)
388 {
389 char *name = buf.pr_fname;
390 size_t namesize = sizeof buf.pr_fname;
391
392 char *namenul = memchr (name, '\0', namesize);
393 size_t namelen = namenul ? namenul - name : namesize;
394 char *namecopy = malloc (namelen + 1);
395 if (namecopy)
396 {
397 namecopy[namelen] = '\0';
398 return memcpy (namecopy, name, namelen);
399 }
400 }
401 }
402
403 #endif
404
405 #if defined __CYGWIN__
406
407 struct external_pinfo *info =
408 (struct external_pinfo *) cygwin_internal (CW_GETPINFO, pid);
409 if (info != NULL)
410 {
411 const char *name = info->progname;
412 size_t namesize = sizeof (info->progname);
413
414 const char *namenul = memchr (name, '\0', namesize);
415 size_t namelen = namenul ? namenul - name : namesize;
416
417
418
419 {
420 const char *backslash = memchr (name, '\\', namelen);
421 if (backslash != NULL)
422 {
423 const char *name_end = name + namelen;
424 for (;;)
425 {
426 const char *next_backslash =
427 memchr (backslash + 1, '\\', name_end - (backslash + 1));
428 if (next_backslash == NULL)
429 break;
430 backslash = next_backslash;
431 }
432 name = backslash + 1;
433 namelen = name_end - name;
434 }
435 }
436
437 {
438 char *namecopy = malloc (namelen + 1);
439 if (namecopy)
440 {
441 namecopy[namelen] = '\0';
442 return memcpy (namecopy, name, namelen);
443 }
444 }
445 }
446
447 #endif
448
449 #if defined __BEOS__ || defined __HAIKU__
450
451 team_info info;
452 if (_get_team_info (pid, &info, sizeof (info)) == B_OK)
453 {
454 const char *name = info.args;
455 size_t namesize = sizeof (info.args);
456
457 const char *namenul = memchr (name, '\0', namesize);
458 size_t namelen = namenul ? namenul - name : namesize;
459
460
461 {
462 const char *space = memchr (name, ' ', namelen);
463 if (space != NULL)
464 namelen = space - name;
465 }
466
467
468 {
469 const char *slash = memchr (name, '/', namelen);
470 if (slash != NULL)
471 {
472 const char *name_end = name + namelen;
473 for (;;)
474 {
475 const char *next_slash =
476 memchr (slash + 1, '/', name_end - (slash + 1));
477 if (next_slash == NULL)
478 break;
479 slash = next_slash;
480 }
481 name = slash + 1;
482 namelen = name_end - name;
483 }
484 }
485
486 {
487 char *namecopy = malloc (namelen + 1);
488 if (namecopy)
489 {
490 namecopy[namelen] = '\0';
491 return memcpy (namecopy, name, namelen);
492 }
493 }
494 }
495
496 #endif
497
498 return NULL;
499 }
500
501 #ifdef TEST
502
503 #include <stdlib.h>
504 #include <unistd.h>
505
506
507
508
509 int
510 main (int argc, char *argv[])
511 {
512 char *arg = argv[1];
513 pid_t pid = (arg != NULL ? atoi (arg) : getpid ());
514 char *progname = get_progname_of (pid);
515 printf ("PID=%lu COMMAND=%s\n",
516 (unsigned long) pid, progname != NULL ? progname : "(null)");
517 free (progname);
518 return 0;
519 }
520
521
522
523
524
525
526
527 #endif