? lib/libc/ktrace.out ? lib/libc/new ? lib/libc/o ? lib/libc/cdb/cdbw.c.new ? lib/libc/gen/arc4random.c.diff ? lib/libc/gen/o ? lib/libc/gen/vis_test.pl ? lib/libc/gen/wvis.sh ? lib/libc/gen/x ? lib/libc/rpc/a.out ? lib/libc/rpc/x.c ? lib/libc/stdio/a.out ? lib/libc/stdio/flagstest.c ? lib/libc/stdio/ktrace.out ? lib/libc/stdio/testdir ? lib/libc/stdio/testfile.txt ? lib/libc/string/x Index: include/unistd.h =================================================================== RCS file: /cvsroot/src/include/unistd.h,v retrieving revision 1.142 diff -u -p -u -r1.142 unistd.h --- include/unistd.h 25 Jul 2014 08:30:47 -0000 1.142 +++ include/unistd.h 26 Sep 2014 18:36:27 -0000 @@ -328,6 +328,8 @@ int des_setkey(const char *); int dup3(int, int, int); void endusershell(void); int exect(const char *, char * const *, char * const *); +int execvpe(const char *, char * const *, char * const *); +int execlpe(const char *, const char *, ...); int fchroot(int); int fdiscard(int, off_t, off_t); int fsync_range(int, int, off_t, off_t); Index: lib/libc/shlib_version =================================================================== RCS file: /cvsroot/src/lib/libc/shlib_version,v retrieving revision 1.255 diff -u -p -u -r1.255 shlib_version --- lib/libc/shlib_version 24 Sep 2014 18:16:37 -0000 1.255 +++ lib/libc/shlib_version 26 Sep 2014 18:36:27 -0000 @@ -42,4 +42,4 @@ # - move gethostbyname to a compat library # - remove arc4random(3) API major=12 -minor=194 +minor=195 Index: lib/libc/gen/Makefile.inc =================================================================== RCS file: /cvsroot/src/lib/libc/gen/Makefile.inc,v retrieving revision 1.188 diff -u -p -u -r1.188 Makefile.inc --- lib/libc/gen/Makefile.inc 13 Jun 2014 15:45:05 -0000 1.188 +++ lib/libc/gen/Makefile.inc 26 Sep 2014 18:36:27 -0000 @@ -94,8 +94,8 @@ MLINKS+=endutxent.3 getutxent.3 endutxen MLINKS+=err.3 verr.3 err.3 errx.3 err.3 verrx.3 err.3 warn.3 err.3 vwarn.3 \ err.3 warnx.3 err.3 vwarnx.3 err.3 errc.3 err.3 verrc.3 err.3 warnc.3 \ err.3 vwarnc.3 -MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 execv.3 \ - exec.3 execvp.3 exec.3 exect.3 +MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 execlpe.3 \ + exec.3 execv.3 exec.3 execvp.3 exec.3 execvpe.3 exec.3 exect.3 MLINKS+=extattr_namespace_to_string.3 extattr_string_to_namespace.3 \ extattr_copy_file.3 extattr_copy_fd.3 \ extattr_copy_file.3 extattr_copy_link.3 \ Index: lib/libc/gen/exec.3 =================================================================== RCS file: /cvsroot/src/lib/libc/gen/exec.3,v retrieving revision 1.22 diff -u -p -u -r1.22 exec.3 --- lib/libc/gen/exec.3 22 Nov 2012 16:19:49 -0000 1.22 +++ lib/libc/gen/exec.3 26 Sep 2014 18:36:27 -0000 @@ -29,7 +29,7 @@ .\" .\" @(#)exec.3 8.3 (Berkeley) 1/24/94 .\" -.Dd May 6, 2005 +.Dd September 26, 2014 .Dt EXEC 3 .Os .Sh NAME @@ -50,6 +50,8 @@ .Ft int .Fn execlp "const char *file" "const char *arg" ... .Ft int +.Fn execlpe "const char *path" "const char *arg" ... "char *const envp[]" +.Ft int .Fn execle "const char *path" "const char *arg" ... "char *const envp[]" .Ft int .Fn exect "const char *path" "char *const argv[]" "char *const envp[]" @@ -57,6 +59,8 @@ .Fn execv "const char *path" "char *const argv[]" .Ft int .Fn execvp "const char *file" "char *const argv[]" +.Ft int +.Fn execvpe "const char *file" "char *const argv[], char *const envp[]" .Sh DESCRIPTION The .Fn exec @@ -80,6 +84,7 @@ The and subsequent ellipses in the .Fn execl , .Fn execlp , +.Fn execlpe , and .Fn execle functions can be thought of as @@ -100,8 +105,9 @@ pointer. The .Fn exect , .Fn execv , +.Fn execvp , and -.Fn execvp +.Fn execvpe functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the file name associated @@ -135,9 +141,11 @@ in the current process. Some of these functions have special semantics. .Pp The functions -.Fn execlp -and +.Fn execlp , +.Fn execlpe , .Fn execvp +and +.Fn execvpe will duplicate the actions of the shell in searching for an executable file if the specified file name does not contain a slash .Dq Li \&/ @@ -198,16 +206,20 @@ The shell. .Sh COMPATIBILITY Historically, the default path for the .Fn execlp +.Fn execlpe , +.Fn execvp , and -.Fn execvp +.Fn execvpe functions was .Dq Pa :/bin:/usr/bin . This was changed to improve security and behaviour. .Pp The behavior of -.Fn execlp +.Fn execlp , +.Fn execlpe , +.Fn execvp , and -.Fn execvp +.Fn execvpe when errors occur while attempting to execute the file is historic practice, but has not traditionally been documented and is not specified by the @@ -215,9 +227,11 @@ by the standard. .Pp Traditionally, the functions -.Fn execlp +.Fn execlp , +.Fn execlpe , +.Fn execvp , and -.Fn execvp +.Fn execvpe ignored all errors except for the ones described above and .Er ENOMEM and @@ -227,9 +241,11 @@ They now return if any error other than .Sh ERRORS .Fn execl , .Fn execle , -.Fn execlp -and +.Fn execlp , +.Fn execlpe , .Fn execvp +and +.Fn execvpe may fail and set .Va errno for any of the errors specified for the library functions @@ -260,3 +276,11 @@ and .Fn execvp conform to .St -p1003.1-90 . +.Pp +The +.Fn execlpe +function appeared first in QNX and the +.Fn execvpe +is on both +.Lx +and QNX. Index: lib/libc/gen/execlp.c =================================================================== RCS file: /cvsroot/src/lib/libc/gen/execlp.c,v retrieving revision 1.12 diff -u -p -u -r1.12 execlp.c --- lib/libc/gen/execlp.c 30 Jun 2011 19:46:07 -0000 1.12 +++ lib/libc/gen/execlp.c 26 Sep 2014 18:36:27 -0000 @@ -42,9 +42,11 @@ __RCSID("$NetBSD: execlp.c,v 1.12 2011/0 #include <stdarg.h> #include <stdlib.h> #include <unistd.h> +#include <errno.h> #ifdef __weak_alias __weak_alias(execlp,_execlp) +__weak_alias(execlpe,_execlpe) #endif int @@ -52,7 +54,7 @@ execlp(const char *name, const char *arg { va_list ap; char **argv; - int i; + size_t i; va_start(ap, arg); for (i = 2; va_arg(ap, char *) != NULL; i++) @@ -69,3 +71,27 @@ execlp(const char *name, const char *arg return execvp(name, argv); } + +int +execlpe(const char *name, const char *arg, ...) +{ + va_list ap; + char **argv, **envp; + size_t i; + + va_start(ap, arg); + for (i = 2; va_arg(ap, char *) != NULL; i++) + continue; + va_end(ap); + + argv = alloca(i * sizeof (char *)); + + va_start(ap, arg); + argv[0] = __UNCONST(arg); + for (i = 1; (argv[i] = va_arg(ap, char *)) != NULL; i++) + continue; + envp = va_arg(ap, char **); + va_end(ap); + + return execvpe(name, argv, envp); +} Index: lib/libc/gen/execvp.c =================================================================== RCS file: /cvsroot/src/lib/libc/gen/execvp.c,v retrieving revision 1.30 diff -u -p -u -r1.30 execvp.c --- lib/libc/gen/execvp.c 20 Jul 2007 12:41:07 -0000 1.30 +++ lib/libc/gen/execvp.c 26 Sep 2014 18:36:27 -0000 @@ -51,12 +51,11 @@ __RCSID("$NetBSD: execvp.c,v 1.30 2007/0 #ifdef __weak_alias __weak_alias(execvp,_execvp) +__weak_alias(execvpe,_execvpe) #endif -extern char **environ; - int -execvp(const char *name, char * const *argv) +execvpe(const char *name, char * const *argv, char * const * envp) { const char **memp; int cnt; @@ -116,7 +115,7 @@ execvp(const char *name, char * const *a memcpy(buf + lp + 1, name, ln); buf[lp + ln + 1] = '\0'; -retry: (void)execve(bp, argv, environ); +retry: (void)execve(bp, argv, envp); switch (errno) { case EACCES: eacces = 1; @@ -136,7 +135,7 @@ retry: (void)execve(bp, argv, environ); memp[0] = _PATH_BSHELL; memp[1] = bp; (void)memcpy(&memp[2], &argv[1], cnt * sizeof(*memp)); - (void)execve(_PATH_BSHELL, __UNCONST(memp), environ); + (void)execve(_PATH_BSHELL, __UNCONST(memp), envp); goto done; case ETXTBSY: if (etxtbsy < 3) @@ -153,3 +152,11 @@ retry: (void)execve(bp, argv, environ); done: return (-1); } + +extern char **environ; + +int +execvp(const char *name, char * const *argv) +{ + return execvpe(name, argv, environ); +}