blob: 6d7b591093e363222928895a270bd2731596fa9d
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 | |
10 | //usage:#if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT) |
11 | //usage:#define pidof_trivial_usage |
12 | //usage: "[OPTIONS] [NAME]..." |
13 | //usage:#define USAGE_PIDOF "\n" |
14 | //usage:#else |
15 | //usage:#define pidof_trivial_usage |
16 | //usage: "[NAME]..." |
17 | //usage:#define USAGE_PIDOF /* none */ |
18 | //usage:#endif |
19 | //usage:#define pidof_full_usage "\n\n" |
20 | //usage: "List PIDs of all processes with names that match NAMEs" |
21 | //usage: USAGE_PIDOF |
22 | //usage: IF_FEATURE_PIDOF_SINGLE( |
23 | //usage: "\n -s Show only one PID" |
24 | //usage: ) |
25 | //usage: IF_FEATURE_PIDOF_OMIT( |
26 | //usage: "\n -o PID Omit given pid" |
27 | //usage: "\n Use %PPID to omit pid of pidof's parent" |
28 | //usage: ) |
29 | //usage: |
30 | //usage:#define pidof_example_usage |
31 | //usage: "$ pidof init\n" |
32 | //usage: "1\n" |
33 | //usage: IF_FEATURE_PIDOF_OMIT( |
34 | //usage: "$ pidof /bin/sh\n20351 5973 5950\n") |
35 | //usage: IF_FEATURE_PIDOF_OMIT( |
36 | //usage: "$ pidof /bin/sh -o %PPID\n20351 5950") |
37 | |
38 | #include "libbb.h" |
39 | |
40 | enum { |
41 | IF_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,) |
42 | IF_FEATURE_PIDOF_OMIT( OPTBIT_OMIT ,) |
43 | OPT_SINGLE = IF_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0, |
44 | OPT_OMIT = IF_FEATURE_PIDOF_OMIT( (1<<OPTBIT_OMIT )) + 0, |
45 | }; |
46 | |
47 | int pidof_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
48 | int pidof_main(int argc UNUSED_PARAM, char **argv) |
49 | { |
50 | unsigned first = 1; |
51 | unsigned opt; |
52 | #if ENABLE_FEATURE_PIDOF_OMIT |
53 | llist_t *omits = NULL; /* list of pids to omit */ |
54 | opt_complementary = "o::"; |
55 | #endif |
56 | |
57 | /* do unconditional option parsing */ |
58 | opt = getopt32(argv, "" |
59 | IF_FEATURE_PIDOF_SINGLE ("s") |
60 | IF_FEATURE_PIDOF_OMIT("o:", &omits)); |
61 | |
62 | #if ENABLE_FEATURE_PIDOF_OMIT |
63 | /* fill omit list. */ |
64 | { |
65 | llist_t *omits_p = omits; |
66 | while (1) { |
67 | omits_p = llist_find_str(omits_p, "%PPID"); |
68 | if (!omits_p) |
69 | break; |
70 | /* are we asked to exclude the parent's process ID? */ |
71 | omits_p->data = utoa((unsigned)getppid()); |
72 | } |
73 | } |
74 | #endif |
75 | /* Looks like everything is set to go. */ |
76 | argv += optind; |
77 | while (*argv) { |
78 | pid_t *pidList; |
79 | pid_t *pl; |
80 | |
81 | /* reverse the pidlist like GNU pidof does. */ |
82 | pidList = pidlist_reverse(find_pid_by_name(*argv)); |
83 | for (pl = pidList; *pl; pl++) { |
84 | #if ENABLE_FEATURE_PIDOF_OMIT |
85 | if (opt & OPT_OMIT) { |
86 | llist_t *omits_p = omits; |
87 | while (omits_p) { |
88 | if (xatoul(omits_p->data) == (unsigned long)(*pl)) { |
89 | goto omitting; |
90 | } |
91 | omits_p = omits_p->link; |
92 | } |
93 | } |
94 | #endif |
95 | printf(" %u" + first, (unsigned)*pl); |
96 | first = 0; |
97 | if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE)) |
98 | break; |
99 | #if ENABLE_FEATURE_PIDOF_OMIT |
100 | omitting: ; |
101 | #endif |
102 | } |
103 | free(pidList); |
104 | argv++; |
105 | } |
106 | if (!first) |
107 | bb_putchar('\n'); |
108 | |
109 | #if ENABLE_FEATURE_PIDOF_OMIT |
110 | if (ENABLE_FEATURE_CLEAN_UP) |
111 | llist_free(omits, NULL); |
112 | #endif |
113 | return first; /* 1 (failure) - no processes found */ |
114 | } |
115 |