summaryrefslogtreecommitdiff
path: root/procps/pidof.c (plain)
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
66enum {
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
73int pidof_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
74int 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