@@ -107,23 +107,17 @@ setup_std_handle_fork(int fd,
107107 * errors. See #266.
108108 */
109109int unshadow_pipe_fd (int fd , char * * failed_doing ) {
110- int i = 0 ;
111- int fds [3 ] = {0 };
112- for (i = 0 ; fd < 3 && i < 3 ; ++ i ) {
113- fds [i ] = fd ;
114- fd = dup (fd );
115- if (fd == -1 ) {
116- * failed_doing = "dup(unshadow)" ;
117- return -1 ;
118- }
119- }
120- for (int j = 0 ; j < i ; ++ j ) {
121- if (close (fds [j ]) == -1 ) {
122- * failed_doing = "close(unshadow)" ;
123- return -1 ;
124- }
125- }
126- return fd ;
110+ if (fd > 2 ) {
111+ return fd ;
112+ }
113+
114+ int new_fd = fcntl (fd , F_DUPFD , 3 );
115+ if (new_fd == -1 ) {
116+ * failed_doing = "fcntl(F_DUP_FD)" ;
117+ return -1 ;
118+ }
119+ close (fd );
120+ return new_fd ;
127121}
128122
129123/* Try spawning with fork. */
@@ -154,17 +148,6 @@ do_spawn_fork (char *const args[],
154148 return -1 ;
155149 }
156150
157- // Block signals with Haskell handlers. The danger here is that
158- // with the threaded RTS, a signal arrives in the child process,
159- // the RTS writes the signal information into the pipe (which is
160- // shared between parent and child), and the parent behaves as if
161- // the signal had been raised.
162- blockUserSignals ();
163-
164- // See #4074. Sometimes fork() gets interrupted by the timer
165- // signal and keeps restarting indefinitely.
166- stopTimer ();
167-
168151 // N.B. execvpe is not supposed on some platforms. In this case
169152 // we emulate this using fork and exec. However, to safely do so
170153 // we need to perform all allocations *prior* to forking. Consequently, we
@@ -181,6 +164,17 @@ do_spawn_fork (char *const args[],
181164 }
182165#endif
183166
167+ // Block signals with Haskell handlers. The danger here is that
168+ // with the threaded RTS, a signal arrives in the child process,
169+ // the RTS writes the signal information into the pipe (which is
170+ // shared between parent and child), and the parent behaves as if
171+ // the signal had been raised.
172+ blockUserSignals ();
173+
174+ // See #4074. Sometimes fork() gets interrupted by the timer
175+ // signal and keeps restarting indefinitely.
176+ stopTimer ();
177+
184178 int pid = fork ();
185179 switch (pid )
186180 {
0 commit comments