Magellan Linux

Diff of /tags/mkinitrd-6_1_12/busybox/libbb/find_pid_by_name.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 532 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 9  Line 9 
9    
10  #include "libbb.h"  #include "libbb.h"
11    
12    /*
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  /* find_pid_by_name()  /* find_pid_by_name()
71   *   *
72   *  Modified by Vladimir Oleynik for use with libbb/procps.c   *  Modified by Vladimir Oleynik for use with libbb/procps.c
# Line 19  Line 77 
77   *  Returns a list of all matching PIDs   *  Returns a list of all matching PIDs
78   *  It is the caller's duty to free the returned pidlist.   *  It is the caller's duty to free the returned pidlist.
79   */   */
80  pid_t* find_pid_by_name(const char* procName)  pid_t* FAST_FUNC find_pid_by_name(const char *procName)
81  {  {
82   pid_t* pidList;   pid_t* pidList;
83   int i = 0;   int i = 0;
84   procps_status_t* p = NULL;   procps_status_t* p = NULL;
85    
86   pidList = xmalloc(sizeof(*pidList));   pidList = xzalloc(sizeof(*pidList));
87   while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM))) {   while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGVN))) {
88   if (strncmp(p->comm, procName, sizeof(p->comm)-1) == 0) {   if (comm_match(p, procName)
89   pidList = xrealloc(pidList, sizeof(*pidList) * (i+2));   /* 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   pidList[i++] = p->pid;   pidList[i++] = p->pid;
95   }   }
96   }   }
# Line 37  pid_t* find_pid_by_name(const char* proc Line 99  pid_t* find_pid_by_name(const char* proc
99   return pidList;   return pidList;
100  }  }
101    
102  pid_t *pidlist_reverse(pid_t *pidList)  pid_t* FAST_FUNC pidlist_reverse(pid_t *pidList)
103  {  {
104   int i = 0;   int i = 0;
105   while (pidList[i])   while (pidList[i])

Legend:
Removed from v.532  
changed lines
  Added in v.816