Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/procps/pgrep.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 816 - (hide annotations) (download)
Fri Apr 24 18:33:46 2009 UTC (15 years, 1 month ago) by niro
File MIME type: text/plain
File size: 3418 byte(s)
-updated to busybox-1.13.4
1 niro 816 /* vi: set sw=4 ts=4: */
2     /*
3     * Mini pgrep/pkill implementation for busybox
4     *
5     * Copyright (C) 2007 Loic Grenie <loic.grenie@gmail.com>
6     *
7     * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8     */
9    
10     #include "libbb.h"
11     #include "xregex.h"
12    
13     /* Idea taken from kill.c */
14     #define pgrep (ENABLE_PGREP && applet_name[1] == 'g')
15     #define pkill (ENABLE_PKILL && applet_name[1] == 'k')
16    
17     enum {
18     /* "vlfxon" */
19     PGREPOPTBIT_V = 0, /* must be first, we need OPT_INVERT = 0/1 */
20     PGREPOPTBIT_L,
21     PGREPOPTBIT_F,
22     PGREPOPTBIT_X,
23     PGREPOPTBIT_O,
24     PGREPOPTBIT_N,
25     };
26    
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))
33    
34     static void act(unsigned pid, char *cmd, int signo, unsigned opt)
35     {
36     if (pgrep) {
37     if (OPT_LIST)
38     printf("%d %s\n", pid, cmd);
39     else
40     printf("%d\n", pid);
41     } else
42     kill(pid, signo);
43     }
44    
45     int pgrep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
46     int pgrep_main(int argc UNUSED_PARAM, char **argv)
47     {
48     unsigned pid = getpid();
49     int signo = SIGTERM;
50     unsigned opt;
51     int scan_mask = PSSCAN_COMM;
52     char *first_arg;
53     int first_arg_idx;
54     int matched_pid;
55     char *cmd_last;
56     procps_status_t *proc;
57     /* These are initialized to 0 */
58     struct {
59     regex_t re_buffer;
60     regmatch_t re_match[1];
61     } Z;
62     #define re_buffer (Z.re_buffer)
63     #define re_match (Z.re_match )
64    
65     memset(&Z, 0, sizeof(Z));
66    
67     /* We must avoid interpreting -NUM (signal num) as an option */
68     first_arg_idx = 1;
69     while (1) {
70     first_arg = argv[first_arg_idx];
71     if (!first_arg)
72     break;
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 */
76     break;
77     }
78     first_arg_idx++;
79     }
80     opt = getopt32(argv, "vlfxon");
81     argv[first_arg_idx] = first_arg;
82    
83     argv += optind;
84     //argc -= optind; - unused anyway
85     if (OPT_FULL)
86     scan_mask |= PSSCAN_ARGVN;
87    
88     if (pkill) {
89     if (OPT_LIST) { /* -l: print the whole signal list */
90     print_signames();
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     }
100    
101     /* One pattern is required */
102     if (!argv[0] || argv[1])
103     bb_show_usage();
104    
105     xregcomp(&re_buffer, argv[0], 0);
106     matched_pid = 0;
107     cmd_last = NULL;
108     proc = NULL;
109     while ((proc = procps_scan(proc, scan_mask)) != NULL) {
110     char *cmd;
111     if (proc->pid == pid)
112     continue;
113     cmd = proc->argv0;
114     if (!cmd) {
115     cmd = proc->comm;
116     } else {
117     int i = proc->argv_len;
118     while (i) {
119     if (!cmd[i]) cmd[i] = ' ';
120     i--;
121     }
122     }
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
126     ) {
127     matched_pid = proc->pid;
128     if (OPT_LAST) {
129     free(cmd_last);
130     cmd_last = xstrdup(cmd);
131     continue;
132     }
133     act(proc->pid, cmd, signo, opt);
134     if (OPT_FIRST)
135     break;
136     }
137     }
138     if (cmd_last) {
139     act(matched_pid, cmd_last, signo, opt);
140     if (ENABLE_FEATURE_CLEAN_UP)
141     free(cmd_last);
142     }
143     return matched_pid == 0; /* return 1 if no processes listed/signaled */
144     }