pidof: size optimizations (-50 bytes)
No binary (build failed)
—
(log yok)
| @@ -2544,7 +2544,7 @@ | |
| 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 \ | |
| @@ -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 | |
| @@ -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 */ |
| } | |