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.
15 /* Idea taken from kill.c */
16 #define pgrep (ENABLE_PGREP && applet_name[1] == 'g')
17 #define pkill (ENABLE_PKILL && applet_name[1] == 'k')
21 PGREPOPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
29 #define OPT_INVERT (opt & (1 << PGREPOPTBIT_V))
30 #define OPT_LIST (opt & (1 << PGREPOPTBIT_L))
31 #define OPT_FULL (opt & (1 << PGREPOPTBIT_F))
32 #define OPT_ANCHOR (opt & (1 << PGREPOPTBIT_X))
33 #define OPT_FIRST (opt & (1 << PGREPOPTBIT_O))
34 #define OPT_LAST (opt & (1 << PGREPOPTBIT_N))
36 static void act(unsigned pid, char *cmd, int signo, unsigned opt)
40 printf("%d %s\n", pid, cmd);
47 int pgrep_main(int argc, char **argv);
48 int pgrep_main(int argc, char **argv)
50 unsigned pid = getpid();
53 int scan_mask = PSSCAN_COMM;
58 procps_status_t *proc;
59 /* These are initialized to 0 */
62 regmatch_t re_match[1];
64 #define re_buffer (Z.re_buffer)
65 #define re_match (Z.re_match )
67 memset(&Z, 0, sizeof(Z));
69 /* We must avoid interpreting -NUM (signal num) as an option */
72 first_arg = argv[first_arg_idx];
75 if (first_arg[0] != '-' || first_arg[1] < 'a' || first_arg[1] > 'z') {
76 argv[first_arg_idx] = NULL;
81 opt = getopt32(argv, "vlfxon");
82 argv[first_arg_idx] = first_arg;
85 //argc -= optind; - unused anyway
87 scan_mask |= PSSCAN_ARGVN;
90 if (OPT_LIST) /* -l: print the whole signal list */
91 print_signames_and_exit();
92 if (first_arg && first_arg[0] == '-') {
93 signo = get_signum(&first_arg[1]);
94 if (signo < 0) /* || signo > MAX_SIGNUM ? */
95 bb_error_msg_and_die("bad signal name '%s'", &first_arg[1]);
100 /* One pattern is required */
101 if (!argv[0] || argv[1])
104 xregcomp(&re_buffer, argv[0], 0);
108 while ((proc = procps_scan(proc, scan_mask)) != NULL) {
110 if (proc->pid == pid)
115 /* NB: OPT_INVERT is always 0 or 1 */
116 if ((regexec(&re_buffer, cmd, 1, re_match, 0) == 0 /* match found */
117 && (!OPT_ANCHOR || (re_match[0].rm_so == 0 && re_match[0].rm_eo == strlen(cmd)))) ^ OPT_INVERT
119 matched_pid = proc->pid;
122 cmd_last = xstrdup(cmd_last);
125 act(proc->pid, cmd, signo, opt);
131 act(matched_pid, cmd_last, signo, opt);
132 if (ENABLE_FEATURE_CLEAN_UP)
135 return matched_pid == 0; /* return 1 if no processes listed/signaled */