aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-10-26 15:24:30 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-10-26 15:24:30 +0200
commit647746076a24a50670a7fab38917606e0ac98be7 (patch)
treec0ee8a55366985e62b15c330f0637dedc2c0ee9a
parent4135a75ab05f2546f4f9e9b3e69d71f477efc1e8 (diff)
downloadbusybox-w32-647746076a24a50670a7fab38917606e0ac98be7.tar.gz
busybox-w32-647746076a24a50670a7fab38917606e0ac98be7.tar.bz2
busybox-w32-647746076a24a50670a7fab38917606e0ac98be7.zip
ash: [REDIR] Replace copyfd by savefd and use dup2 elsewhere
Upstream commit: Date: Sat, 12 May 2007 18:00:57 +1000 [REDIR] Replace copyfd by savefd and use dup2 elsewhere There are two kinds of users to copyfd, those that want to copy an fd to an exact value and those that want to move an fd to a value >= 10. The former can simply use dup2 directly while the latter share a lot of common code that now constitutes savefd. This does not change much, just reducing our divergence from dash code. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 647fc81b4..0490f7f7d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3760,12 +3760,12 @@ setjobctl(int on)
3760 if (--fd < 0) 3760 if (--fd < 0)
3761 goto out; 3761 goto out;
3762 } 3762 }
3763 /* fd is a tty at this point */
3763 fd = fcntl(fd, F_DUPFD, 10); 3764 fd = fcntl(fd, F_DUPFD, 10);
3764 if (ofd >= 0) 3765 if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, dont */
3765 close(ofd); 3766 close(ofd);
3766 if (fd < 0) 3767 if (fd < 0)
3767 goto out; 3768 goto out; /* F_DUPFD failed */
3768 /* fd is a tty at this point */
3769 close_on_exec_on(fd); 3769 close_on_exec_on(fd);
3770 while (1) { /* while we are in the background */ 3770 while (1) { /* while we are in the background */
3771 pgrp = tcgetpgrp(fd); 3771 pgrp = tcgetpgrp(fd);
@@ -5181,26 +5181,31 @@ openredirect(union node *redir)
5181} 5181}
5182 5182
5183/* 5183/*
5184 * Copy a file descriptor to be >= to. Throws exception on error. 5184 * Copy a file descriptor to be >= 10. Throws exception on error.
5185 */ 5185 */
5186/* 0x800..00: bit to set in "to" to request dup2 instead of fcntl(F_DUPFD).
5187 * old code was doing close(to) prior to copyfd() to achieve the same */
5188enum {
5189 COPYFD_EXACT = (int)~(INT_MAX),
5190 COPYFD_RESTORE = (int)((unsigned)COPYFD_EXACT >> 1),
5191};
5192static int 5186static int
5193copyfd(int from, int to) 5187savefd(int from)
5194{ 5188{
5195 int newfd; 5189 int newfd;
5190 int err;
5196 5191
5197 if (to & COPYFD_EXACT) { 5192 newfd = fcntl(from, F_DUPFD, 10);
5198 to &= ~COPYFD_EXACT; 5193 err = newfd < 0 ? errno : 0;
5199 /*if (from != to)*/ 5194 if (err != EBADF) {
5200 newfd = dup2(from, to); 5195 if (err)
5201 } else { 5196 ash_msg_and_raise_error("%d: %m", from);
5202 newfd = fcntl(from, F_DUPFD, to); 5197 close(from);
5198 fcntl(newfd, F_SETFD, FD_CLOEXEC);
5203 } 5199 }
5200
5201 return newfd;
5202}
5203static int
5204dup2_or_raise(int from, int to)
5205{
5206 int newfd;
5207
5208 newfd = (from != to) ? dup2(from, to) : to;
5204 if (newfd < 0) { 5209 if (newfd < 0) {
5205 /* Happens when source fd is not open: try "echo >&99" */ 5210 /* Happens when source fd is not open: try "echo >&99" */
5206 ash_msg_and_raise_error("%d: %m", from); 5211 ash_msg_and_raise_error("%d: %m", from);
@@ -5218,6 +5223,9 @@ struct redirtab {
5218 struct two_fd_t two_fd[]; 5223 struct two_fd_t two_fd[];
5219}; 5224};
5220#define redirlist (G_var.redirlist) 5225#define redirlist (G_var.redirlist)
5226enum {
5227 COPYFD_RESTORE = (int)~(INT_MAX),
5228};
5221 5229
5222static int 5230static int
5223need_to_remember(struct redirtab *rp, int fd) 5231need_to_remember(struct redirtab *rp, int fd)
@@ -5391,10 +5399,10 @@ redirect(union node *redir, int flags)
5391 if (fd != -1) 5399 if (fd != -1)
5392 close(fd); 5400 close(fd);
5393 } else { 5401 } else {
5394 copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT); 5402 dup2_or_raise(redir->ndup.dupfd, fd);
5395 } 5403 }
5396 } else if (fd != newfd) { /* move newfd to fd */ 5404 } else if (fd != newfd) { /* move newfd to fd */
5397 copyfd(newfd, fd | COPYFD_EXACT); 5405 dup2_or_raise(newfd, fd);
5398#if ENABLE_ASH_BASH_COMPAT 5406#if ENABLE_ASH_BASH_COMPAT
5399 if (!(redir->nfile.type == NTO2 && fd == 2)) 5407 if (!(redir->nfile.type == NTO2 && fd == 2))
5400#endif 5408#endif
@@ -5440,7 +5448,7 @@ popredir(int drop, int restore)
5440 if (!drop || (restore && (copy & COPYFD_RESTORE))) { 5448 if (!drop || (restore && (copy & COPYFD_RESTORE))) {
5441 copy &= ~COPYFD_RESTORE; 5449 copy &= ~COPYFD_RESTORE;
5442 /*close(fd);*/ 5450 /*close(fd);*/
5443 copyfd(copy, fd | COPYFD_EXACT); 5451 dup2_or_raise(copy, fd);
5444 } 5452 }
5445 close(copy & ~COPYFD_RESTORE); 5453 close(copy & ~COPYFD_RESTORE);
5446 } 5454 }
@@ -5894,7 +5902,7 @@ evalbackcmd(union node *n, struct backcmd *result)
5894 close(pip[0]); 5902 close(pip[0]);
5895 if (pip[1] != 1) { 5903 if (pip[1] != 1) {
5896 /*close(1);*/ 5904 /*close(1);*/
5897 copyfd(pip[1], 1 | COPYFD_EXACT); 5905 dup2_or_raise(pip[1], 1);
5898 close(pip[1]); 5906 close(pip[1]);
5899 } 5907 }
5900/* TODO: eflag clearing makes the following not abort: 5908/* TODO: eflag clearing makes the following not abort:
@@ -10204,7 +10212,6 @@ static int
10204setinputfile(const char *fname, int flags) 10212setinputfile(const char *fname, int flags)
10205{ 10213{
10206 int fd; 10214 int fd;
10207 int fd2;
10208 10215
10209 INT_OFF; 10216 INT_OFF;
10210 fd = open(fname, O_RDONLY); 10217 fd = open(fname, O_RDONLY);
@@ -10214,11 +10221,8 @@ setinputfile(const char *fname, int flags)
10214 exitstatus = 127; 10221 exitstatus = 127;
10215 ash_msg_and_raise_error("can't open '%s'", fname); 10222 ash_msg_and_raise_error("can't open '%s'", fname);
10216 } 10223 }
10217 if (fd < 10) { 10224 if (fd < 10)
10218 fd2 = copyfd(fd, 10); 10225 fd = savefd(fd);
10219 close(fd);
10220 fd = fd2;
10221 }
10222 setinputfd(fd, flags & INPUT_PUSH_FILE); 10226 setinputfd(fd, flags & INPUT_PUSH_FILE);
10223 out: 10227 out:
10224 INT_ON; 10228 INT_ON;