Big cleanup in config help and description
[oweals/busybox.git] / procps / pidof.c
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 single shot (-s)"
18 //config:       default y
19 //config:       depends on PIDOF
20 //config:       help
21 //config:         Support '-s' for returning only the first pid found.
22 //config:
23 //config:config FEATURE_PIDOF_OMIT
24 //config:       bool "Enable omitting pids (-o PID)"
25 //config:       default y
26 //config:       depends on PIDOF
27 //config:       help
28 //config:         Support '-o PID' for omitting the given pid(s) 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 }