pidof.c - ubase - suckless linux base utils
HTML git clone git://git.suckless.org/ubase
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
pidof.c (2054B)
---
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 if (oflag) {
59 for (p = strtok(arg, ","); p; p = strtok(NULL, ",")) {
60 pe = emalloc(sizeof(*pe));
61 if (strcmp(p, "%PPID") == 0)
62 pe->pid = getppid();
63 else
64 pe->pid = estrtol(p, 10);
65 SLIST_INSERT_HEAD(&omitpid_head, pe, entry);
66 }
67 }
68
69 if (!(dp = opendir("/proc")))
70 eprintf("opendir /proc:");
71
72 while ((entry = readdir(dp))) {
73 if (!pidfile(entry->d_name))
74 continue;
75 pid = estrtol(entry->d_name, 10);
76 if (oflag) {
77 SLIST_FOREACH(pe, &omitpid_head, entry)
78 if (pe->pid == pid)
79 break;
80 if (pe)
81 continue;
82 }
83 if (parsestat(pid, &ps) < 0)
84 continue;
85 if (parsecmdline(ps.pid, cmdline,
86 sizeof(cmdline)) < 0) {
87 cmd = ps.comm;
88 cmdbase = cmd;
89 } else {
90 if ((p = strchr(cmdline, ' ')))
91 *p = '\0';
92 cmd = cmdline;
93 cmdbase = basename(cmdline);
94 }
95 /* Workaround for login shells */
96 if (cmd[0] == '-')
97 cmd++;
98 for (i = 0; i < argc; i++) {
99 if (strcmp(cmd, argv[i]) == 0 ||
100 strcmp(cmdbase, argv[i]) == 0) {
101 putword(entry->d_name);
102 found++;
103 if (sflag)
104 goto out;
105 }
106 }
107 }
108
109 out:
110 if (found)
111 putchar('\n');
112
113 closedir(dp);
114
115 return found ? 0 : 1;
116 }