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 (6.3 kb)" 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/* can't be noexec: can find _itself_ under wrong name, since after fork only, 34 * /proc/PID/cmdline and comm are wrong! Can fix comm (prctl(PR_SET_NAME)), 35 * but cmdline? 36 */ 37 38//kbuild:lib-$(CONFIG_PIDOF) += pidof.o 39 40//usage:#if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT) 41//usage:#define pidof_trivial_usage 42//usage: IF_FEATURE_PIDOF_SINGLE("[-s] ")IF_FEATURE_PIDOF_OMIT("[-o PID] ")"[NAME]..." 43//usage:#define USAGE_PIDOF "\n" 44//usage:#else 45//usage:#define pidof_trivial_usage 46//usage: "[NAME]..." 47//usage:#define USAGE_PIDOF /* none */ 48//usage:#endif 49//usage:#define pidof_full_usage "\n\n" 50//usage: "List PIDs of all processes with names that match NAMEs" 51//usage: USAGE_PIDOF 52//usage: IF_FEATURE_PIDOF_SINGLE( 53//usage: "\n -s Show only one PID" 54//usage: ) 55//usage: IF_FEATURE_PIDOF_OMIT( 56//usage: "\n -o PID Omit given pid" 57//usage: "\n Use %PPID to omit pid of pidof's parent" 58//usage: ) 59//usage: 60//usage:#define pidof_example_usage 61//usage: "$ pidof init\n" 62//usage: "1\n" 63//usage: IF_FEATURE_PIDOF_OMIT( 64//usage: "$ pidof /bin/sh\n20351 5973 5950\n") 65//usage: IF_FEATURE_PIDOF_OMIT( 66//usage: "$ pidof /bin/sh -o %PPID\n20351 5950") 67 68#include "libbb.h" 69 70enum { 71 IF_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,) 72 IF_FEATURE_PIDOF_OMIT( OPTBIT_OMIT ,) 73 OPT_SINGLE = IF_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0, 74 OPT_OMIT = IF_FEATURE_PIDOF_OMIT( (1<<OPTBIT_OMIT )) + 0, 75}; 76 77int pidof_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 78int pidof_main(int argc UNUSED_PARAM, char **argv) 79{ 80 unsigned first = 1; 81 unsigned opt; 82#if ENABLE_FEATURE_PIDOF_OMIT 83 llist_t *omits = NULL; /* list of pids to omit */ 84#endif 85 86 /* do unconditional option parsing */ 87 opt = getopt32(argv, "" 88 IF_FEATURE_PIDOF_SINGLE ("s") 89 IF_FEATURE_PIDOF_OMIT("o:*", &omits)); 90 91#if ENABLE_FEATURE_PIDOF_OMIT 92 /* fill omit list. */ 93 { 94 llist_t *omits_p = omits; 95 while (1) { 96 omits_p = llist_find_str(omits_p, "%PPID"); 97 if (!omits_p) 98 break; 99 /* are we asked to exclude the parent's process ID? */ 100 omits_p->data = utoa((unsigned)getppid()); 101 } 102 } 103#endif 104 /* Looks like everything is set to go. */ 105 argv += optind; 106 while (*argv) { 107 pid_t *pidList; 108 pid_t *pl; 109 110 /* reverse the pidlist like GNU pidof does. */ 111 pidList = pidlist_reverse(find_pid_by_name(*argv)); 112 for (pl = pidList; *pl; pl++) { 113#if ENABLE_FEATURE_PIDOF_OMIT 114 if (opt & OPT_OMIT) { 115 llist_t *omits_p = omits; 116 while (omits_p) { 117 if (xatoul(omits_p->data) == (unsigned long)(*pl)) { 118 goto omitting; 119 } 120 omits_p = omits_p->link; 121 } 122 } 123#endif 124 printf(" %u" + first, (unsigned)*pl); 125 first = 0; 126 if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE)) 127 break; 128#if ENABLE_FEATURE_PIDOF_OMIT 129 omitting: ; 130#endif 131 } 132 free(pidList); 133 argv++; 134 } 135 if (!first) 136 bb_putchar('\n'); 137 138#if ENABLE_FEATURE_PIDOF_OMIT 139 if (ENABLE_FEATURE_CLEAN_UP) 140 llist_free(omits, NULL); 141#endif 142 return first; /* 1 (failure) - no processes found */ 143} 144