1 /* vi: set sw=4 ts=4: */
3 * Mini pgrep/pkill implementation for busybox
5 * Copyright (C) 2007 Loic Grenie <loic.grenie@gmail.com>
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
13 /* Idea taken from kill.c */
14 #define pgrep (ENABLE_PGREP && applet_name[1] == 'g')
15 #define pkill (ENABLE_PKILL && applet_name[1] == 'k')
19 PGREPOPTBIT_V
= 0, /* must be first, we need OPT_INVERT = 0/1 */
27 #define OPT_INVERT (opt & (1 << PGREPOPTBIT_V))
28 #define OPT_LIST (opt & (1 << PGREPOPTBIT_L))
29 #define OPT_FULL (opt & (1 << PGREPOPTBIT_F))
30 #define OPT_ANCHOR (opt & (1 << PGREPOPTBIT_X))
31 #define OPT_FIRST (opt & (1 << PGREPOPTBIT_O))
32 #define OPT_LAST (opt & (1 << PGREPOPTBIT_N))
34 static void act(unsigned pid
, char *cmd
, int signo
, unsigned opt
)
38 printf("%d %s\n", pid
, cmd
);
45 int pgrep_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
46 int pgrep_main(int argc UNUSED_PARAM
, char **argv
)
48 unsigned pid
= getpid();
51 int scan_mask
= PSSCAN_COMM
;
56 procps_status_t
*proc
;
57 /* These are initialized to 0 */
60 regmatch_t re_match
[1];
62 #define re_buffer (Z.re_buffer)
63 #define re_match (Z.re_match )
65 memset(&Z
, 0, sizeof(Z
));
67 /* We must avoid interpreting -NUM (signal num) as an option */
70 first_arg
= argv
[first_arg_idx
];
73 /* not "-<small_letter>..."? */
74 if (first_arg
[0] != '-' || first_arg
[1] < 'a' || first_arg
[1] > 'z') {
75 argv
[first_arg_idx
] = NULL
; /* terminate argv here */
80 opt
= getopt32(argv
, "vlfxon");
81 argv
[first_arg_idx
] = first_arg
;
84 //argc -= optind; - unused anyway
86 scan_mask
|= PSSCAN_ARGVN
;
89 if (OPT_LIST
) { /* -l: print the whole signal list */
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]);
101 /* One pattern is required */
102 if (!argv
[0] || argv
[1])
105 xregcomp(&re_buffer
, argv
[0], 0);
109 while ((proc
= procps_scan(proc
, scan_mask
)) != NULL
) {
111 if (proc
->pid
== pid
)
117 int i
= proc
->argv_len
;
119 if (!cmd
[i
]) cmd
[i
] = ' ';
123 /* NB: OPT_INVERT is always 0 or 1 */
124 if ((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
127 matched_pid
= proc
->pid
;
130 cmd_last
= xstrdup(cmd
);
133 act(proc
->pid
, cmd
, signo
, opt
);
139 act(matched_pid
, cmd_last
, signo
, opt
);
140 if (ENABLE_FEATURE_CLEAN_UP
)
143 return matched_pid
== 0; /* return 1 if no processes listed/signaled */