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
This commit is contained in:
Elliott Hughes 2020-06-04 08:04:06 -07:00
parent 700f753c50
commit a1b1bfd1d1

View file

@ -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 @@ static int __execl(const char* name, const char* argv0, ExecVariant variant, va_
}
// 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 execl(const char* name, const char* arg, ...) {
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 execle(const char* name, const char* arg, ...) {
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;
}