Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Enable execl, execle, execlp, execv, and execvp wrappers

We wrap all of the execs so that we can ensure the environment is
properly configured prior to the exec running.

handle ... for the new execl* wrappers

Add a test for the new execl* ... handling.
  • Loading branch information...
commit a3075407e06a000a931874af57c33341b6a13da9 1 parent 34dce53
Mark Hatle authored Peter Seebach committed
View
4 ChangeLog.txt
@@ -1,3 +1,7 @@
+2010-08-10:
+ * (mhatle) add execl, execle, execlp, execv, and execvp wrappers
+ * (seebs) handle ... for execl, etc.
+
2010-08-06:
* (mhatle) Fix an exec program with an empty environment
View
30 guts/execl.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_execl(const char *path, const char *arg, va_list ap) {
+ * int rc = -1;
+ */
+
+ size_t i = 0;
+ size_t alloc_size = 256;
+ const char **argv = malloc(sizeof (const char *) * alloc_size);
+
+ argv[i++] = arg;
+
+ while (argv[i-1]) {
+ argv[i++] = va_arg (ap, const char *);
+ if ( i > alloc_size - 1 ) {
+ alloc_size = alloc_size + 256;
+ argv = realloc(argv, sizeof (const char *) * alloc_size);
+ }
+ }
+
+ rc = wrap_execv (path, (char *const *) argv);
+
+ free (argv);
+
+/* return rc;
+ * }
+ */
View
32 guts/execle.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_execle(const char *path, const char *arg, va_list ap) {
+ * int rc = -1;
+ */
+
+ size_t i = 0;
+ size_t alloc_size = 256;
+ const char **argv = malloc(sizeof (const char *) * alloc_size);
+ char *const *envp;
+
+ argv[i++] = arg;
+
+ while (argv[i-1]) {
+ argv[i++] = va_arg (ap, const char *);
+ if ( i > alloc_size - 1 ) {
+ alloc_size = alloc_size + 256;
+ argv = realloc(argv, sizeof (const char *) * alloc_size);
+ }
+ }
+ envp = va_arg (ap, char *const *);
+
+ rc = wrap_execve (path, (char *const *) argv, envp);
+
+ free (argv);
+
+/* return rc;
+ * }
+ */
View
30 guts/execlp.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_execlp(const char *file, const char *arg, va_list ap) {
+ * int rc = -1;
+ */
+
+ size_t i = 0;
+ size_t alloc_size = 256;
+ const char **argv = malloc(sizeof (const char *) * alloc_size);
+
+ argv[i++] = arg;
+
+ while (argv[i-1]) {
+ argv[i++] = va_arg (ap, const char *);
+ if ( i > alloc_size - 1 ) {
+ alloc_size = alloc_size + 256;
+ argv = realloc(argv, sizeof (const char *) * alloc_size);
+ }
+ }
+
+ rc = wrap_execvp (file, (char *const *) argv);
+
+ free (argv);
+
+/* return rc;
+ * }
+ */
View
15 guts/execv.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_execv(const char *path, char *const *argv) {
+ * int rc = -1;
+ */
+ environ = pseudo_setupenv(environ, getenv("PSEUDO_OPTS"));
+
+ rc = real_execv(path, argv);
+
+/* return rc;
+ * }
+ */
View
15 guts/execvp.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2008-2010 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * static int
+ * wrap_execvp(const char *file, char *const *argv) {
+ * int rc = -1;
+ */
+ environ = pseudo_setupenv(environ, getenv("PSEUDO_OPTS"));
+
+ rc = real_execvp(file, argv);
+
+/* return rc;
+ * }
+ */
View
47 makewrappers
@@ -97,7 +97,11 @@ do
IFS=$save_IFS
args=''
dummy_args=''
+ wrap_args=''
+ va_list_abort_on_real=''
optional_arg=false
+ make_va_list=false
+ maybe_va_end=''
prepend=''
depth=0
for arg
@@ -138,9 +142,24 @@ do
arg=${arg% }
prepend=''
case $arg in
+ ...)
+ make_va_list=true
+ maybe_va_end='va_end(ap);'
+ va_list_abort_on_real='assert(!"cannot chain to real versions of variadic functions");'
+ args="$args${args+, }..."
+ dummy_args="$dummy_args${dummy_args:+, }..."
+ wrap_args="$wrap_args${wrap_args:+, }va_list ap"
+ arg="..."
+ argname="ap"
+ argnames="$argnames${argnames:+, }ap"
+ wrapargnames="$wrapargnames${wrapargnames:+, }ap"
+ # used for creating a va_list
+ optional_prev=$prev_argname
+ ;;
...*)
optional_arg=true
args="$args${args:+, }..."
+ wrap_args="$wrap_args${wrap_args:+, }..."
dummy_args="$dummy_args${dummy_args:+, }..."
arg=`expr "$arg" : '\.\.\.{\(.*\)}'`
argname=`expr "$arg" : '.*[^a-zA-Z0-9_]\([a-zA-Z0-9_]*\)$'`
@@ -156,6 +175,7 @@ do
*\(*) # function pointer
argname=`expr "$arg" : '[^(]*(\*\([a-zA-Z0-9_]*\).*'`
args="$args${args:+, }$arg"
+ wrap_args="$wrap_args${wrap_args:+, }$arg"
dummy_args="$dummy_args${dummy_args:+, }$arg __attribute__((unused))"
wrapargnames="$wrapargnames${wrapargnames:+, }$argname"
argnames="$argnames${argnames:+, }$argname"
@@ -164,6 +184,7 @@ do
*)
argname=`expr "$arg" : '.*[^a-zA-Z0-9_](*\([a-zA-Z0-9_]*\))*(*)*$'`
args="$args${args:+, }$arg"
+ wrap_args="$wrap_args${wrap_args:+, }$arg"
dummy_args="$dummy_args${dummy_args:+, }$arg __attribute__((unused))"
# special handling for canonicalization
# set this before changing path -> rpath, for guts files
@@ -268,9 +289,16 @@ $type
$name($args) {
EOF
fi
+ if $make_va_list; then
+ cat >&5 <<EOF
+ va_list ap;
+ va_start(ap, $optional_prev);
+EOF
+ fi
# and now the body of the wrapper:
cat >&5 <<EOF
sigset_t blocked, saved;
+ $(write_decl "$type" "rc" "$default_value")
pseudo_debug(4, "called: $name\n");
/* these are signals for which the handlers often
@@ -292,10 +320,14 @@ EOF
}
$decl_paths
if (pseudo_populate_wrappers()) {
- $(write_decl "$type" "rc" "$default_value")
int save_errno;
if (antimagic > 0) {
if (real_$name) {
+ /* if this function takes ..., there is
+ * no way to pass the real argument list
+ * to it...
+ */
+ $va_list_abort_on_real
$(write_assign rc) (*real_$name)($argnames);
} else {
$(write_assign rc) dummy_$name($argnames);
@@ -305,6 +337,7 @@ $alloc_paths
$(write_assign rc) wrap_$name($argnames);
$free_paths
}
+ $maybe_va_end
save_errno = errno;
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
@@ -315,7 +348,9 @@ $free_paths
pseudo_droplock();
sigprocmask(SIG_SETMASK, &saved, NULL);
pseudo_debug(4, "completed: $name\n");
- $(write_return "dummy_$name($argnames)");
+ $(write_assign rc) dummy_$name($argnames);
+ $maybe_va_end
+ $(write_return rc);
}
}
@@ -332,7 +367,7 @@ EOF
if $optional_arg; then
cat >&5 << EOF
static $type
-wrap_$name($args) {
+wrap_$name($wrap_args) {
$(write_decl "$type" "rc" "$default_value")
$optional_decl;
@@ -349,7 +384,7 @@ EOF
else
cat >&5 << EOF
static $type
-wrap_$name($args) {
+wrap_$name($wrap_args) {
$(write_decl "$type" "rc" "$default_value")
#include "$guts"
@@ -385,7 +420,7 @@ EOF
* guts/COPYRIGHT for information.
*
* static $type
- * wrap_$name($args) {
+ * wrap_$name($wrap_args) {
* $(write_decl "$type" "rc" "$default_value")
*/
@@ -401,7 +436,7 @@ EOF
cat >&6 <<EOF
/* $type $name($args); */
static $type dummy_$name($args);
-static $type wrap_$name($args);
+static $type wrap_$name($wrap_args);
static $type (*real_$name)($args);
EOF
View
2  run_tests.sh
@@ -42,7 +42,7 @@ do
else
echo "${filename/%.sh}: Failed."
fi
- rm -rf var
+ rm -rf var/pseudo/*
done
echo "${num_passed_tests}/${num_tests} test(s) passed."
View
21 test/test-execl.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+cat > execl_test.c << EOF
+#include <unistd.h>
+int main() {
+ return execl("/usr/bin/env", "/usr/bin/env", "A=A", "B=B", "C=C", NULL);
+}
+EOF
+
+gcc -o execl_test execl_test.c
+
+./execl_test | grep -q "C=C"
+
+if [ "$?" = "0" ]
+then
+ #echo "Passed."
+ rm -f execl_test execl_test.c
+ exit 0
+fi
+#echo "Failed"
+rm -f execl_test execl_test.c
+exit 1
View
5 wrapfuncs.in
@@ -88,7 +88,12 @@ char *tmpnam(char *s);
int truncate(const char *path, off_t length);
int utime(const char *path, const struct utimbuf *buf);
int utimes(const char *path, const struct timeval *times);
+int execl(const char *path, const char *arg, ...);
+int execlp(const char *file, const char *arg, ...);
+int execle(const char *path, const char *arg, ...);
+int execv(const char *path, char *const *argv);
int execve(const char *filename, char *const *argv, char *const *envp);
+int execvp(const char *file, char *const *argv);
# for emulation of passwd utilities
struct passwd *getpwnam(const char *name);
struct passwd *getpwuid(uid_t uid);

0 comments on commit a307540

Please sign in to comment.
Something went wrong with that request. Please try again.