Use a template for the exec family.
This means that execle() doesn't have to drag in all the path code and
shell script special case code from its relatives, for branches that
will never be taken. Specifically, it means that they disappear from the
monstrously large linker binary after this change.
A drop in the ocean of bloat, yes, but you have to start somewhere.
Bug: http://b/25200716
Test: treehugger, objdump
Change-Id: I21126823d869cee07bf7320bc0a65ea2aaee65a1
diff --git a/libc/bionic/exec.cpp b/libc/bionic/exec.cpp
index 3309585..fd2c401 100644
--- a/libc/bionic/exec.cpp
+++ b/libc/bionic/exec.cpp
@@ -44,9 +44,10 @@
extern "C" char** environ;
-enum ExecVariant { kIsExecL, kIsExecLE, kIsExecLP };
+enum { ExecL, ExecLE, ExecLP };
-static int __execl(const char* name, const char* argv0, ExecVariant variant, va_list ap) {
+template <int variant>
+static int __execl(const char* name, const char* argv0, va_list ap) {
// Count the arguments.
va_list count_ap;
va_copy(count_ap, ap);
@@ -65,17 +66,17 @@
}
// Collect the argp too.
- char** argp = (variant == kIsExecLE) ? va_arg(ap, char**) : environ;
+ char** argp = (variant == ExecLE) ? va_arg(ap, char**) : environ;
va_end(ap);
- return (variant == kIsExecLP) ? execvp(name, argv) : execve(name, argv, argp);
+ return (variant == ExecLP) ? execvp(name, argv) : execve(name, argv, argp);
}
int execl(const char* name, const char* arg, ...) {
va_list ap;
va_start(ap, arg);
- int result = __execl(name, arg, kIsExecL, ap);
+ int result = __execl<ExecL>(name, arg, ap);
va_end(ap);
return result;
}
@@ -83,7 +84,7 @@
int execle(const char* name, const char* arg, ...) {
va_list ap;
va_start(ap, arg);
- int result = __execl(name, arg, kIsExecLE, ap);
+ int result = __execl<ExecLE>(name, arg, ap);
va_end(ap);
return result;
}
@@ -91,7 +92,7 @@
int execlp(const char* name, const char* arg, ...) {
va_list ap;
va_start(ap, arg);
- int result = __execl(name, arg, kIsExecLP, ap);
+ int result = __execl<ExecLP>(name, arg, ap);
va_end(ap);
return result;
}