Magellan Linux

Annotation of /tags/mkinitrd-6_1_11/busybox/libbb/find_pid_by_name.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 928 - (hide annotations) (download)
Wed Oct 28 13:31:19 2009 UTC (14 years, 7 months ago) by niro
File MIME type: text/plain
File size: 3174 byte(s)
tagged 'mkinitrd-6_1_11'
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Utility routines.
4     *
5     * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6     *
7     * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8     */
9    
10     #include "libbb.h"
11    
12 niro 816 /*
13     In Linux we have three ways to determine "process name":
14     1. /proc/PID/stat has "...(name)...", among other things. It's so-called "comm" field.
15     2. /proc/PID/cmdline's first NUL-terminated string. It's argv[0] from exec syscall.
16     3. /proc/PID/exe symlink. Points to the running executable file.
17    
18     kernel threads:
19     comm: thread name
20     cmdline: empty
21     exe: <readlink fails>
22    
23     executable
24     comm: first 15 chars of base name
25     (if executable is a symlink, then first 15 chars of symlink name are used)
26     cmdline: argv[0] from exec syscall
27     exe: points to executable (resolves symlink, unlike comm)
28    
29     script (an executable with #!/path/to/interpreter):
30     comm: first 15 chars of script's base name (symlinks are not resolved)
31     cmdline: /path/to/interpreter (symlinks are not resolved)
32     (script name is in argv[1], args are pushed into argv[2] etc)
33     exe: points to interpreter's executable (symlinks are resolved)
34    
35     If FEATURE_PREFER_APPLETS=y (and more so if FEATURE_SH_STANDALONE=y),
36     some commands started from busybox shell, xargs or find are started by
37     execXXX("/proc/self/exe", applet_name, params....)
38     and therefore comm field contains "exe".
39     */
40    
41     static int comm_match(procps_status_t *p, const char *procName)
42     {
43     int argv1idx;
44    
45     /* comm does not match */
46     if (strncmp(p->comm, procName, 15) != 0)
47     return 0;
48    
49     /* in Linux, if comm is 15 chars, it may be a truncated */
50     if (p->comm[14] == '\0') /* comm is not truncated - match */
51     return 1;
52    
53     /* comm is truncated, but first 15 chars match.
54     * This can be crazily_long_script_name.sh!
55     * The telltale sign is basename(argv[1]) == procName. */
56    
57     if (!p->argv0)
58     return 0;
59    
60     argv1idx = strlen(p->argv0) + 1;
61     if (argv1idx >= p->argv_len)
62     return 0;
63    
64     if (strcmp(bb_basename(p->argv0 + argv1idx), procName) != 0)
65     return 0;
66    
67     return 1;
68     }
69    
70 niro 532 /* find_pid_by_name()
71     *
72     * Modified by Vladimir Oleynik for use with libbb/procps.c
73     * This finds the pid of the specified process.
74     * Currently, it's implemented by rummaging through
75     * the proc filesystem.
76     *
77     * Returns a list of all matching PIDs
78     * It is the caller's duty to free the returned pidlist.
79     */
80 niro 816 pid_t* FAST_FUNC find_pid_by_name(const char *procName)
81 niro 532 {
82     pid_t* pidList;
83     int i = 0;
84     procps_status_t* p = NULL;
85    
86 niro 816 pidList = xzalloc(sizeof(*pidList));
87     while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN))) {
88     if (comm_match(p, procName)
89     /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
90     || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
91     /* TODO: we can also try /proc/NUM/exe link, do we want that? */
92     ) {
93     pidList = xrealloc_vector(pidList, 2, i);
94 niro 532 pidList[i++] = p->pid;
95     }
96     }
97    
98     pidList[i] = 0;
99     return pidList;
100     }
101    
102 niro 816 pid_t* FAST_FUNC pidlist_reverse(pid_t *pidList)
103 niro 532 {
104     int i = 0;
105     while (pidList[i])
106     i++;
107     if (--i >= 0) {
108     pid_t k;
109     int j;
110     for (j = 0; i > j; i--, j++) {
111     k = pidList[i];
112     pidList[i] = pidList[j];
113     pidList[j] = k;
114     }
115     }
116     return pidList;
117     }