Module Name: src
Committed By: kre
Date: Wed Sep 15 20:21:48 UTC 2021
Modified Files:
src/bin/sh: redir.c
Log Message:
Fix an ordering error in the previous (and even earlier, going back
a way, but made more serious with the recent changes).
The n>&n operation (more or less a no-op, except it clears CLOEXEC)
should precede almost everything else - and simply be made to fail if
an attempt is made to apply it to a sh internal fd.
We were renumbering the internal fd (the n> part considered first)
which was dumb, but OK, before, but now rejecting the operation
(the >&n) part when n should not be visible to the script. That
made something of a mess (and could lead to the shell believing its
job control tty was at a fd it never got moved to).
Do things in the correct order, and simply fail that case for internal
fds (for every other n>xxx for any xxx sh simply renumbers its internal fd
n to some other fd before attempting the operation, even n>&- ... those are
all fine).
[In all the above the '>' is used in place of any redirect operator].
To generate a diff of this commit:
cvs rdiff -u -r1.68 -r1.69 src/bin/sh/redir.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/bin/sh/redir.c
diff -u src/bin/sh/redir.c:1.68 src/bin/sh/redir.c:1.69
--- src/bin/sh/redir.c:1.68 Wed Sep 15 18:29:45 2021
+++ src/bin/sh/redir.c Wed Sep 15 20:21:47 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: redir.c,v 1.68 2021/09/15 18:29:45 kre Exp $ */
+/* $NetBSD: redir.c,v 1.69 2021/09/15 20:21:47 kre Exp $ */
/*-
* Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
#else
-__RCSID("$NetBSD: redir.c,v 1.68 2021/09/15 18:29:45 kre Exp $");
+__RCSID("$NetBSD: redir.c,v 1.69 2021/09/15 20:21:47 kre Exp $");
#endif
#endif /* not lint */
@@ -245,6 +245,18 @@ redirect(union node *redir, int flags)
fd, max_user_fd, user_fd_limit));
if (fd < user_fd_limit && fd > max_user_fd)
max_user_fd = fd;
+ if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
+ n->ndup.dupfd == fd) {
+ VTRACE(DBG_REDIR, ("!cloexec\n"));
+ if (sh_fd(fd) != NULL ||
+ saved_redirected_fd(fd) != NULL)
+ error("fd %d: %s", fd, strerror(EBADF));
+ /* redirect from/to same file descriptor */
+ /* make sure it stays open */
+ if (fcntl(fd, F_SETFD, 0) < 0)
+ error("fd %d: %s", fd, strerror(errno));
+ continue;
+ }
if ((renamed = saved_redirected_fd(fd)) != NULL) {
int to = pick_new_fd(fd);
@@ -255,15 +267,6 @@ redirect(union node *redir, int flags)
(void)close(fd);
}
renumber_sh_fd(sh_fd(fd));
- if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
- n->ndup.dupfd == fd) {
- /* redirect from/to same file descriptor */
- /* make sure it stays open */
- if (fcntl(fd, F_SETFD, 0) < 0)
- error("fd %d: %s", fd, strerror(errno));
- VTRACE(DBG_REDIR, ("!cloexec\n"));
- continue;
- }
if ((flags & REDIR_PUSH) && !is_renamed(sv->renamed, fd)) {
int bigfd;
@@ -421,6 +424,7 @@ openredirect(union node *redir, char mem
if (copyfd(f, fd, cloexec) < 0) {
int e = errno;
+ VTRACE(DBG_REDIR, (" failed: %s\n", strerror(e)));
close(f);
error("redirect reassignment (fd %d) failed: %s", fd,
strerror(e));