PATCH: replacing exec*p with BB_EXEC*P

Gabriel L. Somlo somlo at cmu.edu
Sun Feb 4 15:22:17 PST 2007


Denis, Bernhard,

Here's the patch that adds bb_execvp(). I compiled it
with static and dynamic linking (against glibc, I know static there is
buggy, but I just wanted to see how the binary size was affected :) ).
Here's the results (I'm building all but maybe two of the applets that
call execvp()):

arch.   linking         standalone      macro calls     bytes   
                        macro           bb_execvp()     saved


        static          1257820         1257820         0 
i386
        dynamic          512136          512136         0 


        static          1677276         1676860         416 
ppc
        dynamic          659600          659600         0 

No clue how much (if anything) we'd save on other architectures. Also,
not clear why dynamically linked binaries aren't affected (maybe
there's some padding/alignment thing, but I'm not an expert on the ELF
format :)

Also, if you *want* a bb_execlp(), we could do the following,
(shamelessly ripped from glibc):

int bb_execlp (const char *file, const char *arg, ...)
{
#define INITIAL_ARGV_MAX 1024
  size_t argv_max = INITIAL_ARGV_MAX;
  const char *initial_argv[INITIAL_ARGV_MAX];
  const char **argv = initial_argv;
  va_list args;

  argv[0] = arg;

  va_start (args, arg);
  unsigned int i = 0;
  while (argv[i++] != NULL)
    {
      if (i == argv_max)
        {
          argv_max *= 2;
          const char **nptr = xrealloc (argv == initial_argv ? NULL : argv,
                                       argv_max * sizeof (const char *));
          if (nptr == NULL)
            {
              if (argv != initial_argv)
                free (argv);
              return -1;
            }
          if (argv == initial_argv)
            /* We have to copy the already filled-in data ourselves.  */
            memcpy (nptr, argv, i * sizeof (const char *));

          argv = nptr;
        }

      argv[i] = va_arg (args, const char *);
    }
  va_end (args);

  int ret = bb_execvp (file, (char *const *) argv);
  if (argv != initial_argv)
    free (argv);

  return ret;
}

But given how few the places it's being called from, we'd end up maybe
increasing the size slightly instead of saving a few bytes.

(now, I don't know how many places call execl() with hardcoded paths
that should really be calling BB_EXECLP(), but that's something I'll
be looking into next :) )

OK, so given the meager space savings, do you guys still want this, or
should we stick with standalone macros ?

Here goes the patch.
Cheers,
--Gabriel

diff -NarU5 busybox-svn-17770.orig/libbb/execable.c busybox-svn-17770/libbb/execable.c
--- busybox-svn-17770.orig/libbb/execable.c	2007-02-04 16:25:51.000000000 -0500
+++ busybox-svn-17770/libbb/execable.c	2007-02-04 17:43:13.000000000 -0500
@@ -57,5 +57,15 @@
 		free(ret);
 		return 1;
 	}
 	return 0;
 }
+
+#ifdef ENABLE_FEATURE_EXEC_PREFER_APPLETS
+/* just like the real execvp, but try to launch an applet named 'file' first
+ */
+int bb_execvp(const char *file, char *const argv[])
+{
+	return execvp(find_applet_by_name(file) ? CONFIG_BUSYBOX_EXEC_PATH : file,
+					argv);
+}
+#endif
diff -NarU5 busybox-svn-17770.orig/include/libbb.h busybox-svn-17770/include/libbb.h
--- busybox-svn-17770.orig/include/libbb.h	2007-02-04 16:25:53.000000000 -0500
+++ busybox-svn-17770/include/libbb.h	2007-02-04 17:42:54.000000000 -0500
@@ -560,12 +560,12 @@
 int execable_file(const char *name);
 char *find_execable(const char *filename);
 int exists_execable(const char *filename);
 
 #ifdef ENABLE_FEATURE_EXEC_PREFER_APPLETS
-#define BB_EXECVP(prog,cmd) \
-	execvp((find_applet_by_name(prog)) ? CONFIG_BUSYBOX_EXEC_PATH : prog, cmd)
+int bb_execvp(const char *file, char *const argv[]);
+#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
 #define BB_EXECLP(prog,cmd,...) \
 	execlp((find_applet_by_name(prog)) ? CONFIG_BUSYBOX_EXEC_PATH : prog, cmd, __VA_ARGS__)
 #else
 #define BB_EXECVP(prog,cmd) execvp(prog,cmd)
 #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) 


More information about the busybox mailing list