diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-06 00:00:12 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-07-06 00:00:12 +0200 |
commit | 57dc5345e2f30eb990722be45449dcae1b15a1ad (patch) | |
tree | fb5c52bbf5f36ea7ae9c774122ee4065daf177d7 /procps/pgrep.c | |
parent | 666e1d3978ebd2b72b18333f4face0e10cc816ba (diff) | |
download | busybox-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.c | 118 |
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 | ||
17 | enum { | 16 | enum { |
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 | ||
34 | static void act(unsigned pid, char *cmd, int signo, unsigned opt) | 37 | static 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) | |||
45 | int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 48 | int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
46 | int pgrep_main(int argc UNUSED_PARAM, char **argv) | 49 | int 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 | } |