pidof.c - ubase - suckless linux base utils
(HTM) git clone git://git.suckless.org/ubase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
pidof.c (2017B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <sys/types.h>
3
4 #include <dirent.h>
5 #include <libgen.h>
6 #include <limits.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11
12 #include "proc.h"
13 #include "queue.h"
14 #include "util.h"
15
16 struct pidentry {
17 pid_t pid;
18 SLIST_ENTRY(pidentry) entry;
19 };
20
21 static SLIST_HEAD(, pidentry) omitpid_head;
22
23 static void
24 usage(void)
25 {
26 eprintf("usage: %s [-o pid1,pid2,...pidN] [-s] [program...]\n", argv0);
27 }
28
29 int
30 main(int argc, char *argv[])
31 {
32 DIR *dp;
33 struct dirent *entry;
34 pid_t pid;
35 struct procstat ps;
36 char cmdline[BUFSIZ], *cmd, *cmdbase = NULL, *p, *arg = NULL;
37 int i, found = 0;
38 int sflag = 0, oflag = 0;
39 struct pidentry *pe;
40
41 ARGBEGIN {
42 case 's':
43 sflag = 1;
44 break;
45 case 'o':
46 oflag = 1;
47 arg = EARGF(usage());
48 break;
49 default:
50 usage();
51 } ARGEND;
52
53 if (!argc)
54 return 1;
55
56 SLIST_INIT(&omitpid_head);
57
58 for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
59 pe = emalloc(sizeof(*pe));
60 if (strcmp(p, "%PPID") == 0)
61 pe->pid = getppid();
62 else
63 pe->pid = estrtol(p, 10);
64 SLIST_INSERT_HEAD(&omitpid_head, pe, entry);
65 }
66
67 if (!(dp = opendir("/proc")))
68 eprintf("opendir /proc:");
69
70 while ((entry = readdir(dp))) {
71 if (!pidfile(entry->d_name))
72 continue;
73 pid = estrtol(entry->d_name, 10);
74 if (oflag) {
75 SLIST_FOREACH(pe, &omitpid_head, entry)
76 if (pe->pid == pid)
77 break;
78 if (pe)
79 continue;
80 }
81 if (parsestat(pid, &ps) < 0)
82 continue;
83 if (parsecmdline(ps.pid, cmdline,
84 sizeof(cmdline)) < 0) {
85 cmd = ps.comm;
86 cmdbase = cmd;
87 } else {
88 if ((p = strchr(cmdline, ' ')))
89 *p = '\0';
90 cmd = cmdline;
91 cmdbase = basename(cmdline);
92 }
93 /* Workaround for login shells */
94 if (cmd[0] == '-')
95 cmd++;
96 for (i = 0; i < argc; i++) {
97 if (strcmp(cmd, argv[i]) == 0 ||
98 strcmp(cmdbase, argv[i]) == 0) {
99 putword(entry->d_name);
100 found++;
101 if (sflag)
102 goto out;
103 }
104 }
105 }
106
107 out:
108 if (found)
109 putchar('\n');
110
111 closedir(dp);
112
113 return 0;
114 }