(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
fexecve.c
       1  /* Copyright (C) 1994-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <errno.h>
      19  #include <stddef.h>
      20  #include <stdio.h>
      21  #include <unistd.h>
      22  #include <fcntl.h>
      23  #include <sys/stat.h>
      24  
      25  #include <fd_to_filename.h>
      26  #include <sysdep.h>
      27  #include <sys/syscall.h>
      28  #include <kernel-features.h>
      29  
      30  
      31  /* Execute the file FD refers to, overlaying the running program image.
      32     ARGV and ENVP are passed to the new program, as for `execve'.  */
      33  int
      34  fexecve (int fd, char *const argv[], char *const envp[])
      35  {
      36    if (fd < 0 || argv == NULL || envp == NULL)
      37      {
      38        __set_errno (EINVAL);
      39        return -1;
      40      }
      41  
      42  #ifdef __NR_execveat
      43    /* Avoid implicit array coercion in syscall macros.  */
      44    INLINE_SYSCALL (execveat, 5, fd, "", &argv[0], &envp[0], AT_EMPTY_PATH);
      45  # ifndef __ASSUME_EXECVEAT
      46    if (errno != ENOSYS)
      47      return -1;
      48  # endif
      49  #endif
      50  
      51  #ifndef __ASSUME_EXECVEAT
      52    /* We use the /proc filesystem to get the information.  If it is not
      53       mounted we fail.  We do not need the return value.  */
      54    struct fd_to_filename filename;
      55    __execve (__fd_to_filename (fd, &filename), argv, envp);
      56  
      57    int save = errno;
      58  
      59    /* We come here only if the 'execve' call fails.  Determine whether
      60       /proc is mounted.  If not we return ENOSYS.  */
      61    struct __stat64_t64 st;
      62    if (__stat64_time64 ("/proc/self/fd", &st) != 0 && errno == ENOENT)
      63      save = ENOSYS;
      64  
      65    __set_errno (save);
      66  #endif
      67  
      68    return -1;
      69  }