hush testsuite: add glob_dir.tests
[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
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 #endif
55
56         /* do unconditional option parsing */
57         opt = getopt32(argv, ""
58                         IF_FEATURE_PIDOF_SINGLE ("s")
59                         IF_FEATURE_PIDOF_OMIT("o:*", &omits));
60
61 #if ENABLE_FEATURE_PIDOF_OMIT
62         /* fill omit list.  */
63         {
64                 llist_t *omits_p = omits;
65                 while (1) {
66                         omits_p = llist_find_str(omits_p, "%PPID");
67                         if (!omits_p)
68                                 break;
69                         /* are we asked to exclude the parent's process ID?  */
70                         omits_p->data = utoa((unsigned)getppid());
71                 }
72         }
73 #endif
74         /* Looks like everything is set to go.  */
75         argv += optind;
76         while (*argv) {
77                 pid_t *pidList;
78                 pid_t *pl;
79
80                 /* reverse the pidlist like GNU pidof does.  */
81                 pidList = pidlist_reverse(find_pid_by_name(*argv));
82                 for (pl = pidList; *pl; pl++) {
83 #if ENABLE_FEATURE_PIDOF_OMIT
84                         if (opt & OPT_OMIT) {
85                                 llist_t *omits_p = omits;
86                                 while (omits_p) {
87                                         if (xatoul(omits_p->data) == (unsigned long)(*pl)) {
88                                                 goto omitting;
89                                         }
90                                         omits_p = omits_p->link;
91                                 }
92                         }
93 #endif
94                         printf(" %u" + first, (unsigned)*pl);
95                         first = 0;
96                         if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE))
97                                 break;
98 #if ENABLE_FEATURE_PIDOF_OMIT
99  omitting: ;
100 #endif
101                 }
102                 free(pidList);
103                 argv++;
104         }
105         if (!first)
106                 bb_putchar('\n');
107
108 #if ENABLE_FEATURE_PIDOF_OMIT
109         if (ENABLE_FEATURE_CLEAN_UP)
110                 llist_free(omits, NULL);
111 #endif
112         return first; /* 1 (failure) - no processes found */
113 }