Skip to content

Commit e8a2fbc

Browse files
authored
Merge pull request #285 from haskell/wip/T284
Address #284 and #283
2 parents c956562 + c25afa9 commit e8a2fbc

File tree

1 file changed

+22
-28
lines changed

1 file changed

+22
-28
lines changed

cbits/posix/fork_exec.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -107,23 +107,17 @@ setup_std_handle_fork(int fd,
107107
* errors. See #266.
108108
*/
109109
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;
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

Comments
 (0)