diff options
Diffstat (limited to '')
| -rw-r--r-- | src/unistd/execat.c | 3 | ||||
| -rw-r--r-- | src/unistd/fexec.c | 191 | 
2 files changed, 191 insertions, 3 deletions
| diff --git a/src/unistd/execat.c b/src/unistd/execat.c index d80d24b..5c42d79 100644 --- a/src/unistd/execat.c +++ b/src/unistd/execat.c @@ -450,9 +450,6 @@ int execvpeat(int dirfd, const char* file, char* const argv[], char* const envp[    if (strchr(file, '/') || !*file)      return execveat(dirfd, file, argv, envp, flags); -  if (!*file) -    return errno = ENOENT, -1; -      path = getenv(PATH);    if (path == NULL)      { diff --git a/src/unistd/fexec.c b/src/unistd/fexec.c new file mode 100644 index 0000000..bf022e4 --- /dev/null +++ b/src/unistd/fexec.c @@ -0,0 +1,191 @@ +/** + * slibc — Yet another C library + * Copyright © 2015  Mattias Andrée (maandree@member.fsf.org) + *  + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *  + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + *  + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ +#include <unistd.h> +#include <stdarg.h> +#include <errno.h> +#include <alloca.h> +#include <string.h> +#include <stdlib.h> + + + +/** + * The current environment variables. + */ +extern char** environ; + + + +/** + * Common code for the `fexecl*` functions. + *  + * @param   fd          The first argument of said functions. + * @param   argv        The rest of the arguments of said functions; + *                      may conclude `envp`. + * @param   fetch_envp  Whether `argv` includes `envp`. + *  + * @throws              Any error specified for execve(2). + */ +static void vexec(int fd, va_list argv, int fetch_envp) +{ +  char* const* envp = environ; +  size_t n = 0, i; +  va_list args; +  char** argv_; +   +  va_copy(args, argv); +  while (n++, va_arg(args, char*) != NULL) +    break; +   +  if (fetch_envp) +    envp = va_arg(args, char* const*); +   +  argv_ = alloca(n * sizeof(char*)); +  for (i = 0; i < n; i++) +    argv_[i] = va_arg(argv, char*); +   +  fexecve(fd, argv_, envp); +} + + + +/** + * Replace the current process image with a new process image. + *  + * This is a slibc extension. + *  + * @param   fd   File descriptor for the file to execute. + * @param   ...  The arguments with which to execute the file. + *               The arguments should have the type `const char*`. + *               As a slibc extension, it can be empty. + *               This list shall be terminated by a `NULL` sentinel. + * @return       This function does not return on success, + *               on error, -1 is returned and `errno` is + *               set to describe the error. + *  + * @throws       Any error specified for execve(2). + */ +int fexecl(int fd, ... /*, NULL */) +{ +  int saved_errno; +  va_list argv; +  va_start(argv, path); +  vfexec(fd, argv, 0); +  saved_errno = errno; +  va_end(argv); +  return errno = saved_errno, -1; +} + + +/** + * Replace the current process image with a new process image. + *  + * This is a slibc extension. + *  + * @param   fd    File descriptor for the file to execute. + * @param   ...   The arguments with which to execute the file. + *                The arguments should have the type `const char*`. + *                As a slibc extension, it can be empty. + *                This list shall be terminated by a `NULL` sentinel. + * @param   envp  The list of environment variables the new program shall + *                have set. Each element shall be formatted $name=$value. + *                This list shall be `NULL`-terminated. The behaviour + *                is system-dependant if this argument is `NULL`. + * @return        This function does not return on success, + *                on error, -1 is returned and `errno` is + *                set to describe the error. + *  + * @throws        Any error specified for execve(2). + */ +int fexecle(int fd, ... /*, NULL, char* const envp[] */) +{ +  int saved_errno; +  va_list argv; +  va_start(argv, path); +  vfexec(fd, argv, 1); +  saved_errno = errno; +  va_end(argv); +  return errno = saved_errno, -1; +} + + +/** + * Replace the current process image with a new process image. + *  + * This is a slibc extension. + *  + * @param   fd    File descriptor for the file to execute. + * @param   argv  The arguments with which to execute the file. + *                This parameter should really have the type + *                `const char* const[]`, but that probably not + *                so because compiles take issue with casts + *                adding const to any pointer in the type + *                except the outmost pointer. This list shall + *                be `NULL`-terminated. The behaviour is + *                system-dependant if this argument is `NULL`. + * @return        This function does not return on success, + *                on error, -1 is returned and `errno` is + *                set to describe the error. + *  + * @throws        Any error specified for execve(2). + */ +int fexecv(int fd, char* const argv[]) +{ +  return fexecve(fd, argv, environ); +} + + +/** + * Replace the current process image with a new process image. + *  + * @param   fd    File descriptor for the file to execute. + * @param   argv  The arguments with which to execute the file. + *                This parameter should really have the type + *                `const char* const[]`, but that probably not + *                so because compiles take issue with casts + *                adding const to any pointer in the type + *                except the outmost pointer. This list shall + *                be `NULL`-terminated. The behaviour is + *                system-dependant if this argument is `NULL`. + * @param   envp  The list of environment variables the new program shall + *                have set. Each element shall be formatted $name=$value. + *                This list shall be `NULL`-terminated. The behaviour + *                is system-dependant if this argument is `NULL`. + * @return        This function does not return on success, + *                on error, -1 is returned and `errno` is + *                set to describe the error. + *  + * @throws        Any error specified for execve(2). + */ +int fexecve(int fd, char* const argv[], char* const envp[]) +{ +  char pathname[sizeof("/proc/self/fd//") + 3 * sizeof(int)]; +  int saved_errno; +   +  sprintf(pathname, "/proc/self/fd/%i/", fd); +   +  execve(pathname, argv, envp); +  saved_errno = errno; +   +  if (access("/proc/", X_OK)) +    saved_errno = ENOSYS; +   +  errno = saved_errno == ENOENT ? EBADF : saved_errno; +  return -1; +} + | 
