]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/posix/spawni.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / posix / spawni.c
index b5732714ae5ff821149b02b92e9a971e64461a71..55950501ac7a30f7047e821961d3f8657d326029 100644 (file)
@@ -1,5 +1,5 @@
 /* Guts of POSIX spawn interface.  Generic POSIX.1 version.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -14,7 +14,7 @@
 
    You should have received a copy of the GNU Lesser General Public
    License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
+   <https://www.gnu.org/licenses/>.  */
 
 #include <spawn.h>
 #include <assert.h>
@@ -68,11 +68,11 @@ maybe_script_execute (struct posix_spawn_args *args)
       ptrdiff_t argc = args->argc;
 
       /* Construct an argument list for the shell.  */
-      char *new_argv[argc + 1];
+      char *new_argv[argc + 2];
       new_argv[0] = (char *) _PATH_BSHELL;
       new_argv[1] = (char *) args->file;
       if (argc > 1)
-       memcpy (new_argv + 2, argv + 1, argc * sizeof(char *));
+       memcpy (new_argv + 2, argv + 1, argc * sizeof (char *));
       else
        new_argv[2] = NULL;
 
@@ -157,7 +157,7 @@ __spawni_child (void *arguments)
          switch (action->tag)
            {
            case spawn_do_close:
-             if (close_not_cancel (action->action.close_action.fd) != 0)
+             if (__close_nocancel (action->action.close_action.fd) != 0)
                {
                  if (have_fdlimit == 0)
                    {
@@ -180,7 +180,7 @@ __spawni_child (void *arguments)
                   with the process already at maximum number of file descriptor
                   opened and also for multiple actions on single-open special
                   paths (like /dev/watchdog).  */
-               close_not_cancel (action->action.open_action.fd);
+               __close_nocancel (action->action.open_action.fd);
 
                int new_fd = __open_nocancel (action->action.open_action.path,
                                              action->action.open_action.oflag
@@ -197,16 +197,38 @@ __spawni_child (void *arguments)
                        != action->action.open_action.fd)
                      goto fail;
 
-                   if (close_not_cancel (new_fd) != 0)
+                   if (__close_nocancel (new_fd) != 0)
                      goto fail;
                  }
              }
              break;
 
            case spawn_do_dup2:
-             if (__dup2 (action->action.dup2_action.fd,
-                         action->action.dup2_action.newfd)
-                 != action->action.dup2_action.newfd)
+             /* Austin Group issue #411 requires adddup2 action with source
+                and destination being equal to remove close-on-exec flag.  */
+             if (action->action.dup2_action.fd
+                 == action->action.dup2_action.newfd)
+               {
+                 int fd = action->action.dup2_action.newfd;
+                 int flags = __fcntl (fd, F_GETFD, 0);
+                 if (flags == -1)
+                   goto fail;
+                 if (__fcntl (fd, F_SETFD, flags & ~FD_CLOEXEC) == -1)
+                   goto fail;
+               }
+             else if (__dup2 (action->action.dup2_action.fd,
+                              action->action.dup2_action.newfd)
+                      != action->action.dup2_action.newfd)
+               goto fail;
+             break;
+
+           case spawn_do_chdir:
+             if (__chdir (action->action.chdir_action.path) != 0)
+               goto fail;
+             break;
+
+           case spawn_do_fchdir:
+             if (__fchdir (action->action.fchdir_action.fd) != 0)
                goto fail;
              break;
            }
@@ -310,6 +332,8 @@ __spawni (pid_t * pid, const char *file,
          const posix_spawnattr_t * attrp, char *const argv[],
          char *const envp[], int xflags)
 {
+  /* It uses __execvpex to avoid run ENOEXEC in non compatibility mode (it
+     will be handled by maybe_script_execute).  */
   return __spawnix (pid, file, acts, attrp, argv, envp, xflags,
-                   xflags & SPAWN_XFLAGS_USE_PATH ? __execvpe : __execve);
+                   xflags & SPAWN_XFLAGS_USE_PATH ? __execvpex : __execve);
 }