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