Ctty:    int(slave.Fd()),
        }
 
+       // Test ctty management by sending enough child fd to overlap the
+       // parent's fd intended for child's ctty.
+       for 2+len(cmd.ExtraFiles) < cmd.SysProcAttr.Ctty {
+               dummy, err := os.Open(os.DevNull)
+               if err != nil {
+                       t.Fatal(err)
+               }
+               defer dummy.Close()
+               cmd.ExtraFiles = append(cmd.ExtraFiles, dummy)
+       }
+
        if err := cmd.Start(); err != nil {
                t.Fatal(err)
        }
 
                }
        }
 
+       // Detach fd 0 from tty
+       if sys.Noctty {
+               _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
+       // Set the controlling TTY to Ctty
+       if sys.Setctty {
+               _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
                RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
        }
 
-       // Detach fd 0 from tty
-       if sys.Noctty {
-               _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
-       // Set the controlling TTY to Ctty
-       if sys.Setctty {
-               _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
        // Time to exec.
        _, _, err1 = RawSyscall(SYS_EXECVE,
                uintptr(unsafe.Pointer(argv0)),
 
                }
        }
 
+       // Detach fd 0 from tty
+       if sys.Noctty {
+               _, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
+       // Set the controlling TTY to Ctty
+       if sys.Setctty {
+               _, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
                rawSyscall(funcPC(libc_close_trampoline), uintptr(i), 0, 0)
        }
 
-       // Detach fd 0 from tty
-       if sys.Noctty {
-               _, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
-       // Set the controlling TTY to Ctty
-       if sys.Setctty {
-               _, _, err1 = rawSyscall(funcPC(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
        // Time to exec.
        _, _, err1 = rawSyscall(funcPC(libc_execve_trampoline),
                uintptr(unsafe.Pointer(argv0)),
 
                }
        }
 
+       // Detach fd 0 from tty
+       if sys.Noctty {
+               err1 = ioctl(0, uintptr(TIOCNOTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
+       // Set the controlling TTY to Ctty
+       if sys.Setctty {
+               // On AIX, TIOCSCTTY is undefined
+               if TIOCSCTTY == 0 {
+                       err1 = ENOSYS
+                       goto childerror
+               }
+               err1 = ioctl(uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
                close(uintptr(i))
        }
 
-       // Detach fd 0 from tty
-       if sys.Noctty {
-               err1 = ioctl(0, uintptr(TIOCNOTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
-       // Set the controlling TTY to Ctty
-       if sys.Setctty {
-               // On AIX, TIOCSCTTY is undefined
-               if TIOCSCTTY == 0 {
-                       err1 = ENOSYS
-                       goto childerror
-               }
-               err1 = ioctl(uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
        // Time to exec.
        err1 = execve(
                uintptr(unsafe.Pointer(argv0)),
 
                }
        }
 
+       // Detach fd 0 from tty
+       if sys.Noctty {
+               _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
+       // Set the controlling TTY to Ctty
+       if sys.Setctty {
+               _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 1)
+               if err1 != 0 {
+                       goto childerror
+               }
+       }
+
        // Pass 1: look for fd[i] < i and move those up above len(fd)
        // so that pass 2 won't stomp on an fd it needs later.
        if pipe < nextfd {
                RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
        }
 
-       // Detach fd 0 from tty
-       if sys.Noctty {
-               _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
-       // Set the controlling TTY to Ctty
-       if sys.Setctty {
-               _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 1)
-               if err1 != 0 {
-                       goto childerror
-               }
-       }
-
        // Enable tracing if requested.
        // Do this right before exec so that we don't unnecessarily trace the runtime
        // setting up after the fork. See issue #21428.