diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-28 18:35:07 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-28 18:35:07 +0200 |
commit | 9acd63c92cbc4bd0a3ddbb6a61e512eadc29239d (patch) | |
tree | 9bf53c82f5fccd4a5ed13915b8039080c563ce07 /shell/ash.c | |
parent | e4defe826be49b8ef19912ba4cb291bfe9166e0f (diff) | |
download | busybox-w32-9acd63c92cbc4bd0a3ddbb6a61e512eadc29239d.tar.gz busybox-w32-9acd63c92cbc4bd0a3ddbb6a61e512eadc29239d.tar.bz2 busybox-w32-9acd63c92cbc4bd0a3ddbb6a61e512eadc29239d.zip |
ash,hush: fix "saved" redirected fds still visible in children
Based on a patch by Mark Marshall <mark.marshall@omicronenergy.com>
function old new delta
dup_CLOEXEC - 49 +49
fcntl_F_DUPFD 46 - -46
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/shell/ash.c b/shell/ash.c index 5e281b5ce..85690e555 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -255,6 +255,9 @@ typedef long arith_t; | |||
255 | # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ | 255 | # define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ |
256 | #endif | 256 | #endif |
257 | 257 | ||
258 | #ifndef F_DUPFD_CLOEXEC | ||
259 | # define F_DUPFD_CLOEXEC F_DUPFD | ||
260 | #endif | ||
258 | #ifndef PIPE_BUF | 261 | #ifndef PIPE_BUF |
259 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | 262 | # define PIPE_BUF 4096 /* amount of buffering in a pipe */ |
260 | #endif | 263 | #endif |
@@ -5448,12 +5451,15 @@ dup2_or_raise(int from, int to) | |||
5448 | return newfd; | 5451 | return newfd; |
5449 | } | 5452 | } |
5450 | static int | 5453 | static int |
5451 | fcntl_F_DUPFD(int fd, int avoid_fd) | 5454 | dup_CLOEXEC(int fd, int avoid_fd) |
5452 | { | 5455 | { |
5453 | int newfd; | 5456 | int newfd; |
5454 | repeat: | 5457 | repeat: |
5455 | newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); | 5458 | newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1); |
5456 | if (newfd < 0) { | 5459 | if (newfd >= 0) { |
5460 | if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */ | ||
5461 | fcntl(newfd, F_SETFD, FD_CLOEXEC); | ||
5462 | } else { /* newfd < 0 */ | ||
5457 | if (errno == EBUSY) | 5463 | if (errno == EBUSY) |
5458 | goto repeat; | 5464 | goto repeat; |
5459 | if (errno == EINTR) | 5465 | if (errno == EINTR) |
@@ -5569,7 +5575,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq) | |||
5569 | for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) { | 5575 | for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) { |
5570 | /* If we collide with an already moved fd... */ | 5576 | /* If we collide with an already moved fd... */ |
5571 | if (fd == sq->two_fd[i].moved_to) { | 5577 | if (fd == sq->two_fd[i].moved_to) { |
5572 | new_fd = fcntl_F_DUPFD(fd, avoid_fd); | 5578 | new_fd = dup_CLOEXEC(fd, avoid_fd); |
5573 | sq->two_fd[i].moved_to = new_fd; | 5579 | sq->two_fd[i].moved_to = new_fd; |
5574 | TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd)); | 5580 | TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd)); |
5575 | if (new_fd < 0) /* what? */ | 5581 | if (new_fd < 0) /* what? */ |
@@ -5584,7 +5590,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq) | |||
5584 | } | 5590 | } |
5585 | 5591 | ||
5586 | /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */ | 5592 | /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */ |
5587 | new_fd = fcntl_F_DUPFD(fd, avoid_fd); | 5593 | new_fd = dup_CLOEXEC(fd, avoid_fd); |
5588 | TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd)); | 5594 | TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd)); |
5589 | if (new_fd < 0) { | 5595 | if (new_fd < 0) { |
5590 | if (errno != EBADF) | 5596 | if (errno != EBADF) |