pidof: size optimizations (-50 bytes)
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 23 Jun 2007 14:56:43 +0000 (14:56 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 23 Jun 2007 14:56:43 +0000 (14:56 -0000)
include/usage.h
libbb/find_pid_by_name.c
procps/pidof.c

index 2baa495ac3bbc40387b8f9da92e4690f6f3b304a..6d02c8bbfcd9881837ba24cfd76e52ce5e11b1fd 100644 (file)
        USE_FEATURE_PIDOF_SINGLE( \
        "\n     -s      Display only a single PID") \
        USE_FEATURE_PIDOF_OMIT( \
-       "\n     -o      Omit given pid") \
+       "\n     -o PID  Omit given pid") \
        USE_FEATURE_PIDOF_OMIT( \
        "\n             Use %PPID to omit the parent pid of pidof itself")
 #define pidof_example_usage \
index e98616940c061ce28b9a62d74203ae7ac13fd590..13ccb545d08ab3e06cb819689eebff2287d4187e 100644 (file)
@@ -9,6 +9,35 @@
 
 #include "libbb.h"
 
+/*
+In Linux we have three ways to determine "process name":
+1. /proc/PID/stat has "...(name)...", among other things. It's so-called "comm" field.
+2. /proc/PID/cmdline's first NUL-terminated string. It's argv[0] from exec syscall.
+3. /proc/PID/exe symlink. Points to the running executable file.
+
+kernel threads:
+ comm: thread name
+ cmdline: empty
+ exe: <readlink fails>
+
+executable
+ comm: first 15 chars of base name
+ (if executable is a symlink, then first 15 chars of symlink name are used)
+ cmdline: argv[0] from exec syscall
+ exe: points to executable (resolves symlink, unlike comm)
+
+script (an executable with #!/path/to/interpreter):
+ comm: first 15 chars of script's base name (symlinks are not resolved)
+ cmdline: /path/to/interpreter (symlinks are not resolved)
+ (script name is in argv[1], args are pushed into argv[2] etc)
+ exe: points to interpreter's executable (symlinks are resolved)
+
+If FEATURE_PREFER_APPLETS=y (and more so if FEATURE_SH_STANDALONE=y),
+some commands started from busybox shell, xargs or find are started by
+execXXX("/proc/self/exe", applet_name, params....)
+and therefore comm field contains "exe".
+*/
+
 /* find_pid_by_name()
  *
  *  Modified by Vladimir Oleynik for use with libbb/procps.c
index 3541aeee0d8944e40faa1a765aafe93fa6182bbf..01e587cbfea1f34bc48893e909ee26689661af09 100644 (file)
@@ -20,9 +20,9 @@ int pidof_main(int argc, char **argv);
 int pidof_main(int argc, char **argv)
 {
        unsigned first = 1;
-       unsigned fail = 1;
        unsigned opt;
 #if ENABLE_FEATURE_PIDOF_OMIT
+       char ppid_str[sizeof(int)*3 + 1];
        llist_t *omits = NULL; /* list of pids to omit */
        opt_complementary = "o::";
 #endif
@@ -35,14 +35,12 @@ int pidof_main(int argc, char **argv)
 #if ENABLE_FEATURE_PIDOF_OMIT
        /* fill omit list.  */
        {
-               char getppid_str[sizeof(int)*3 + 1];
-               llist_t * omits_p = omits;
+               llist_t *omits_p = omits;
                while (omits_p) {
                        /* are we asked to exclude the parent's process ID?  */
-                       if (!strncmp(omits_p->data, "%PPID", 5)) {
-                               llist_pop(&omits_p);
-                               snprintf(getppid_str, sizeof(getppid_str), "%u", (unsigned)getppid());
-                               llist_add_to(&omits_p, getppid_str);
+                       if (strcmp(omits_p->data, "%PPID") == 0) {
+                               sprintf(ppid_str, "%u", (unsigned)getppid());
+                               omits_p->data = ppid_str;
                        }
                        omits_p = omits_p->link;
                }
@@ -56,27 +54,24 @@ int pidof_main(int argc, char **argv)
                /* reverse the pidlist like GNU pidof does.  */
                pidList = pidlist_reverse(find_pid_by_name(argv[optind]));
                for (pl = pidList; *pl; pl++) {
-                       SKIP_FEATURE_PIDOF_OMIT(const) unsigned omitted = 0;
 #if ENABLE_FEATURE_PIDOF_OMIT
                        if (opt & OPT_OMIT) {
                                llist_t *omits_p = omits;
                                while (omits_p) {
                                        if (xatoul(omits_p->data) == *pl) {
-                                               omitted = 1;
-                                               break;
-                                       } else
-                                               omits_p = omits_p->link;
+                                               goto omitting;
+                                       }
+                                       omits_p = omits_p->link;
                                }
                        }
 #endif
-                       if (!omitted) {
-                               printf(" %u" + first, (unsigned)*pl);
-                               first = 0;
-                       }
-                       fail = (!ENABLE_FEATURE_PIDOF_OMIT && omitted);
-
+                       printf(" %u" + first, (unsigned)*pl);
+                       first = 0;
                        if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE))
                                break;
+#if ENABLE_FEATURE_PIDOF_OMIT
+ omitting: ;
+#endif
                }
                free(pidList);
                optind++;
@@ -87,5 +82,5 @@ int pidof_main(int argc, char **argv)
        if (ENABLE_FEATURE_CLEAN_UP)
                llist_free(omits, NULL);
 #endif
-       return fail ? EXIT_FAILURE : EXIT_SUCCESS;
+       return first; /* 1 (failure) - no processes found */
 }