@@ -107,23 +107,17 @@ setup_std_handle_fork(int fd,
107
107
* errors. See #266.
108
108
*/
109
109
int 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 ;
127
121
}
128
122
129
123
/* Try spawning with fork. */
@@ -154,17 +148,6 @@ do_spawn_fork (char *const args[],
154
148
return -1 ;
155
149
}
156
150
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
-
168
151
// N.B. execvpe is not supposed on some platforms. In this case
169
152
// we emulate this using fork and exec. However, to safely do so
170
153
// we need to perform all allocations *prior* to forking. Consequently, we
@@ -181,6 +164,17 @@ do_spawn_fork (char *const args[],
181
164
}
182
165
#endif
183
166
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
+
184
178
int pid = fork ();
185
179
switch (pid )
186
180
{
0 commit comments