aboutsummaryrefslogtreecommitdiff
path: root/procps/pgrep.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-07-06 00:00:12 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-07-06 00:00:12 +0200
commit57dc5345e2f30eb990722be45449dcae1b15a1ad (patch)
treefb5c52bbf5f36ea7ae9c774122ee4065daf177d7 /procps/pgrep.c
parent666e1d3978ebd2b72b18333f4face0e10cc816ba (diff)
downloadbusybox-w32-57dc5345e2f30eb990722be45449dcae1b15a1ad.tar.gz
busybox-w32-57dc5345e2f30eb990722be45449dcae1b15a1ad.tar.bz2
busybox-w32-57dc5345e2f30eb990722be45449dcae1b15a1ad.zip
pgrep/pkill: support -s and -P options
function old new delta pgrep_main 510 580 +70 packed_usage 26575 26616 +41 act 234 236 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 113/0) Total: 113 bytes Signed-off-by: Rob Landley <rob@landley.net> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to '')
-rw-r--r--procps/pgrep.c118
1 files changed, 64 insertions, 54 deletions
diff --git a/procps/pgrep.c b/procps/pgrep.c
index 0e8e5294e..aef4f229a 100644
--- a/procps/pgrep.c
+++ b/procps/pgrep.c
@@ -6,7 +6,6 @@
6 * 6 *
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 */ 8 */
9
10#include "libbb.h" 9#include "libbb.h"
11#include "xregex.h" 10#include "xregex.h"
12 11
@@ -15,26 +14,30 @@
15#define pkill (ENABLE_PKILL && applet_name[1] == 'k') 14#define pkill (ENABLE_PKILL && applet_name[1] == 'k')
16 15
17enum { 16enum {
18 /* "vlfxon" */ 17 /* "vlfxons:P:" */
19 PGREPOPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */ 18 OPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
20 PGREPOPTBIT_L, 19 OPTBIT_L,
21 PGREPOPTBIT_F, 20 OPTBIT_F,
22 PGREPOPTBIT_X, 21 OPTBIT_X,
23 PGREPOPTBIT_O, 22 OPTBIT_O,
24 PGREPOPTBIT_N, 23 OPTBIT_N,
24 OPTBIT_S,
25 OPTBIT_P,
25}; 26};
26 27
27#define OPT_INVERT (opt & (1 << PGREPOPTBIT_V)) 28#define OPT_INVERT (opt & (1 << OPTBIT_V))
28#define OPT_LIST (opt & (1 << PGREPOPTBIT_L)) 29#define OPT_LIST (opt & (1 << OPTBIT_L))
29#define OPT_FULL (opt & (1 << PGREPOPTBIT_F)) 30#define OPT_FULL (opt & (1 << OPTBIT_F))
30#define OPT_ANCHOR (opt & (1 << PGREPOPTBIT_X)) 31#define OPT_ANCHOR (opt & (1 << OPTBIT_X))
31#define OPT_FIRST (opt & (1 << PGREPOPTBIT_O)) 32#define OPT_FIRST (opt & (1 << OPTBIT_O))
32#define OPT_LAST (opt & (1 << PGREPOPTBIT_N)) 33#define OPT_LAST (opt & (1 << OPTBIT_N))
34#define OPT_SID (opt & (1 << OPTBIT_S))
35#define OPT_PPID (opt & (1 << OPTBIT_P))
33 36
34static void act(unsigned pid, char *cmd, int signo, unsigned opt) 37static void act(unsigned pid, char *cmd, int signo)
35{ 38{
36 if (pgrep) { 39 if (pgrep) {
37 if (OPT_LIST) 40 if (option_mask32 & (1 << OPTBIT_L)) /* OPT_LIST */
38 printf("%d %s\n", pid, cmd); 41 printf("%d %s\n", pid, cmd);
39 else 42 else
40 printf("%d\n", pid); 43 printf("%d\n", pid);
@@ -45,13 +48,12 @@ static void act(unsigned pid, char *cmd, int signo, unsigned opt)
45int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 48int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
46int pgrep_main(int argc UNUSED_PARAM, char **argv) 49int pgrep_main(int argc UNUSED_PARAM, char **argv)
47{ 50{
48 unsigned pid = getpid(); 51 unsigned pid;
49 int signo = SIGTERM; 52 int signo;
50 unsigned opt; 53 unsigned opt;
51 int scan_mask = PSSCAN_COMM; 54 int scan_mask;
52 char *first_arg;
53 int first_arg_idx;
54 int matched_pid; 55 int matched_pid;
56 int sid2match, ppid2match;
55 char *cmd_last; 57 char *cmd_last;
56 procps_status_t *proc; 58 procps_status_t *proc;
57 /* These are initialized to 0 */ 59 /* These are initialized to 0 */
@@ -64,52 +66,52 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
64 66
65 memset(&Z, 0, sizeof(Z)); 67 memset(&Z, 0, sizeof(Z));
66 68
67 /* We must avoid interpreting -NUM (signal num) as an option */ 69 /* Parse -SIGNAL for pkill. Must be first option, if present */
68 first_arg_idx = 1; 70 signo = SIGTERM;
69 while (1) { 71 if (pkill && argv[1] && argv[1][0] == '-') {
70 first_arg = argv[first_arg_idx]; 72 int temp = get_signum(argv[1]+1);
71 if (!first_arg) 73 if (temp != -1) {
72 break; 74 signo = temp;
73 /* not "-<small_letter>..."? */ 75 argv++;
74 if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z') {
75 argv[first_arg_idx] = NULL; /* terminate argv here */
76 break;
77 } 76 }
78 first_arg_idx++;
79 } 77 }
80 opt = getopt32(argv, "vlfxon");
81 argv[first_arg_idx] = first_arg;
82 78
79 /* Parse remaining options */
80 ppid2match = -1;
81 sid2match = -1;
82 opt_complementary = "s+:P+"; /* numeric opts */
83 opt = getopt32(argv, "vlfxons:P:", &sid2match, &ppid2match);
83 argv += optind; 84 argv += optind;
84 //argc -= optind; - unused anyway
85 if (OPT_FULL)
86 scan_mask |= PSSCAN_ARGVN;
87 85
88 if (pkill) { 86 if (pkill && OPT_LIST) { /* -l: print the whole signal list */
89 if (OPT_LIST) { /* -l: print the whole signal list */ 87 print_signames();
90 print_signames(); 88 return 0;
91 return 0;
92 }
93 if (first_arg && first_arg[0] == '-') {
94 signo = get_signum(&first_arg[1]);
95 if (signo < 0) /* || signo > MAX_SIGNUM ? */
96 bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]);
97 argv++;
98 }
99 } 89 }
100 90
101 /* One pattern is required */ 91 pid = getpid();
102 if (!argv[0] || argv[1]) 92 if (sid2match == 0)
93 sid2match = getsid(pid);
94
95 scan_mask = PSSCAN_COMM;
96 if (OPT_FULL)
97 scan_mask |= PSSCAN_ARGVN;
98
99 /* One pattern is required, if no -s and no -P */
100 if ((sid2match & ppid2match) < 0 && (!argv[0] || argv[1]))
103 bb_show_usage(); 101 bb_show_usage();
104 102
105 xregcomp(&re_buffer, argv[0], 0); 103 if (argv[0])
104 xregcomp(&re_buffer, argv[0], 0);
105
106 matched_pid = 0; 106 matched_pid = 0;
107 cmd_last = NULL; 107 cmd_last = NULL;
108 proc = NULL; 108 proc = NULL;
109 while ((proc = procps_scan(proc, scan_mask)) != NULL) { 109 while ((proc = procps_scan(proc, scan_mask)) != NULL) {
110 char *cmd; 110 char *cmd;
111
111 if (proc->pid == pid) 112 if (proc->pid == pid)
112 continue; 113 continue;
114
113 cmd = proc->argv0; 115 cmd = proc->argv0;
114 if (!cmd) { 116 if (!cmd) {
115 cmd = proc->comm; 117 cmd = proc->comm;
@@ -120,8 +122,15 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
120 i--; 122 i--;
121 } 123 }
122 } 124 }
125
126 if (ppid2match >= 0 && ppid2match != proc->ppid)
127 continue;
128 if (sid2match >= 0 && sid2match != proc->sid)
129 continue;
130
123 /* NB: OPT_INVERT is always 0 or 1 */ 131 /* NB: OPT_INVERT is always 0 or 1 */
124 if ((regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */ 132 if (!argv[0] ||
133 (regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */
125 && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == (regoff_t)strlen(cmd)))) ^ OPT_INVERT 134 && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == (regoff_t)strlen(cmd)))) ^ OPT_INVERT
126 ) { 135 ) {
127 matched_pid = proc->pid; 136 matched_pid = proc->pid;
@@ -130,13 +139,14 @@ int pgrep_main(int argc UNUSED_PARAM, char **argv)
130 cmd_last = xstrdup(cmd); 139 cmd_last = xstrdup(cmd);
131 continue; 140 continue;
132 } 141 }
133 act(proc->pid, cmd, signo, opt); 142 act(proc->pid, cmd, signo);
134 if (OPT_FIRST) 143 if (OPT_FIRST)
135 break; 144 break;
136 } 145 }
137 } 146 }
147
138 if (cmd_last) { 148 if (cmd_last) {
139 act(matched_pid, cmd_last, signo, opt); 149 act(matched_pid, cmd_last, signo);
140 if (ENABLE_FEATURE_CLEAN_UP) 150 if (ENABLE_FEATURE_CLEAN_UP)
141 free(cmd_last); 151 free(cmd_last);
142 } 152 }