blob: 069adb7a444d4ef4902fd7f3b779dd8e61afcc50
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * pidof implementation for busybox |
4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
8 | */ |
9 | //config:config PIDOF |
10 | //config: bool "pidof" |
11 | //config: default y |
12 | //config: help |
13 | //config: Pidof finds the process id's (pids) of the named programs. It prints |
14 | //config: those id's on the standard output. |
15 | //config: |
16 | //config:config FEATURE_PIDOF_SINGLE |
17 | //config: bool "Enable argument for single shot (-s)" |
18 | //config: default y |
19 | //config: depends on PIDOF |
20 | //config: help |
21 | //config: Support argument '-s' for returning only the first pid found. |
22 | //config: |
23 | //config:config FEATURE_PIDOF_OMIT |
24 | //config: bool "Enable argument for omitting pids (-o)" |
25 | //config: default y |
26 | //config: depends on PIDOF |
27 | //config: help |
28 | //config: Support argument '-o' for omitting the given pids in output. |
29 | //config: The special pid %PPID can be used to name the parent process |
30 | //config: of the pidof, in other words the calling shell or shell script. |
31 | |
32 | //applet:IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) |
33 | |
34 | //kbuild:lib-$(CONFIG_PIDOF) += pidof.o |
35 | |
36 | //usage:#if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT) |
37 | //usage:#define pidof_trivial_usage |
38 | //usage: "[OPTIONS] [NAME]..." |
39 | //usage:#define USAGE_PIDOF "\n" |
40 | //usage:#else |
41 | //usage:#define pidof_trivial_usage |
42 | //usage: "[NAME]..." |
43 | //usage:#define USAGE_PIDOF /* none */ |
44 | //usage:#endif |
45 | //usage:#define pidof_full_usage "\n\n" |
46 | //usage: "List PIDs of all processes with names that match NAMEs" |
47 | //usage: USAGE_PIDOF |
48 | //usage: IF_FEATURE_PIDOF_SINGLE( |
49 | //usage: "\n -s Show only one PID" |
50 | //usage: ) |
51 | //usage: IF_FEATURE_PIDOF_OMIT( |
52 | //usage: "\n -o PID Omit given pid" |
53 | //usage: "\n Use %PPID to omit pid of pidof's parent" |
54 | //usage: ) |
55 | //usage: |
56 | //usage:#define pidof_example_usage |
57 | //usage: "$ pidof init\n" |
58 | //usage: "1\n" |
59 | //usage: IF_FEATURE_PIDOF_OMIT( |
60 | //usage: "$ pidof /bin/sh\n20351 5973 5950\n") |
61 | //usage: IF_FEATURE_PIDOF_OMIT( |
62 | //usage: "$ pidof /bin/sh -o %PPID\n20351 5950") |
63 | |
64 | #include "libbb.h" |
65 | |
66 | enum { |
67 | IF_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,) |
68 | IF_FEATURE_PIDOF_OMIT( OPTBIT_OMIT ,) |
69 | OPT_SINGLE = IF_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0, |
70 | OPT_OMIT = IF_FEATURE_PIDOF_OMIT( (1<<OPTBIT_OMIT )) + 0, |
71 | }; |
72 | |
73 | int pidof_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
74 | int pidof_main(int argc UNUSED_PARAM, char **argv) |
75 | { |
76 | unsigned first = 1; |
77 | unsigned opt; |
78 | #if ENABLE_FEATURE_PIDOF_OMIT |
79 | llist_t *omits = NULL; /* list of pids to omit */ |
80 | #endif |
81 | |
82 | /* do unconditional option parsing */ |
83 | opt = getopt32(argv, "" |
84 | IF_FEATURE_PIDOF_SINGLE ("s") |
85 | IF_FEATURE_PIDOF_OMIT("o:*", &omits)); |
86 | |
87 | #if ENABLE_FEATURE_PIDOF_OMIT |
88 | /* fill omit list. */ |
89 | { |
90 | llist_t *omits_p = omits; |
91 | while (1) { |
92 | omits_p = llist_find_str(omits_p, "%PPID"); |
93 | if (!omits_p) |
94 | break; |
95 | /* are we asked to exclude the parent's process ID? */ |
96 | omits_p->data = utoa((unsigned)getppid()); |
97 | } |
98 | } |
99 | #endif |
100 | /* Looks like everything is set to go. */ |
101 | argv += optind; |
102 | while (*argv) { |
103 | pid_t *pidList; |
104 | pid_t *pl; |
105 | |
106 | /* reverse the pidlist like GNU pidof does. */ |
107 | pidList = pidlist_reverse(find_pid_by_name(*argv)); |
108 | for (pl = pidList; *pl; pl++) { |
109 | #if ENABLE_FEATURE_PIDOF_OMIT |
110 | if (opt & OPT_OMIT) { |
111 | llist_t *omits_p = omits; |
112 | while (omits_p) { |
113 | if (xatoul(omits_p->data) == (unsigned long)(*pl)) { |
114 | goto omitting; |
115 | } |
116 | omits_p = omits_p->link; |
117 | } |
118 | } |
119 | #endif |
120 | printf(" %u" + first, (unsigned)*pl); |
121 | first = 0; |
122 | if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE)) |
123 | break; |
124 | #if ENABLE_FEATURE_PIDOF_OMIT |
125 | omitting: ; |
126 | #endif |
127 | } |
128 | free(pidList); |
129 | argv++; |
130 | } |
131 | if (!first) |
132 | bb_putchar('\n'); |
133 | |
134 | #if ENABLE_FEATURE_PIDOF_OMIT |
135 | if (ENABLE_FEATURE_CLEAN_UP) |
136 | llist_free(omits, NULL); |
137 | #endif |
138 | return first; /* 1 (failure) - no processes found */ |
139 | } |
140 |