ash: ditch dupredirect(), it was only making code harder to read.

incorporate it in its single callsite.

function                                             old     new   delta
redirect                                            1054    1052      -2
changepath                                           196     194      -2
This commit is contained in:
Denis Vlasenko 2008-07-24 11:34:27 +00:00
parent 0b76964ae1
commit 8d924ecf38

View File

@ -4828,6 +4828,7 @@ openredirect(union node *redir)
abort(); abort();
#endif #endif
/* Fall through to eliminate warning. */ /* Fall through to eliminate warning. */
/* Our single caller does this itself */
// case NTOFD: // case NTOFD:
// case NFROMFD: // case NFROMFD:
// f = -1; // f = -1;
@ -4864,30 +4865,13 @@ copyfd(int from, int to)
return newfd; return newfd;
} }
static void /* Struct def and variable are moved down to the first usage site */
dupredirect(union node *redir, int f)
{
int fd = redir->nfile.fd;
if (f < 0) { /* redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD */
if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
copyfd(redir->ndup.dupfd, fd);
}
return;
}
if (f != fd) {
copyfd(f, fd);
close(f);
}
}
/**/
struct redirtab { struct redirtab {
struct redirtab *next; struct redirtab *next;
int renamed[10]; int renamed[10];
int nullredirs; int nullredirs;
}; };
#define redirlist (G_var.redirlist ) #define redirlist (G_var.redirlist)
/* /*
* Process a list of redirection commands. If the REDIR_PUSH flag is set, * Process a list of redirection commands. If the REDIR_PUSH flag is set,
@ -4918,10 +4902,11 @@ redirect(union node *redir, int flags)
sv->next = redirlist; sv->next = redirlist;
redirlist = sv; redirlist = sv;
sv->nullredirs = g_nullredirs - 1; sv->nullredirs = g_nullredirs - 1;
g_nullredirs = 0;
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
sv->renamed[i] = EMPTY; sv->renamed[i] = EMPTY;
g_nullredirs = 0;
} }
do { do {
fd = redir->nfile.fd; fd = redir->nfile.fd;
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
@ -4943,26 +4928,37 @@ redirect(union node *redir, int flags)
i = fcntl(fd, F_DUPFD, 10); i = fcntl(fd, F_DUPFD, 10);
if (i == -1) { if (i == -1) {
i = errno; i = errno;
if (i != EBADF) { /* strange error */ if (i != EBADF) {
close(newfd); /* Strange error (e.g. "too many files" EMFILE?) */
/*if (newfd >= 0)*/ close(newfd);
errno = i; errno = i;
ash_msg_and_raise_error("%d: %m", fd); ash_msg_and_raise_error("%d: %m", fd);
/* NOTREACHED */ /* NOTREACHED */
} }
/* it is not open - ok */ /* EBADF: it is not open - ok */
} else { } else {
/* it is open, save its copy */ /* fd is open, save its copy */
//TODO: CLOEXEC the copy? currently these extra "saved" fds are closed
// in popredir() in the child, preventing them from leaking into child.
// (popredir() also cleans up the mess in case of failures)
sv->renamed[fd] = i; sv->renamed[fd] = i;
close(fd); close(fd);
} }
} else { } else {
close(fd); close(fd);
} }
/* Here fd is closed */ /* At this point fd is closed */
/* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */ if (newfd < 0) {
/* else: move newfd to fd */ /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */
dupredirect(redir, newfd); if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
copyfd(redir->ndup.dupfd, fd);
}
} else { /* move newfd to fd */
copyfd(newfd, fd);
close(newfd);
}
} while ((redir = redir->nfile.next) != NULL); } while ((redir = redir->nfile.next) != NULL);
INT_ON; INT_ON;
if ((flags & REDIR_SAVEFD2) && sv && sv->renamed[2] >= 0) if ((flags & REDIR_SAVEFD2) && sv && sv->renamed[2] >= 0)
preverrout_fd = sv->renamed[2]; preverrout_fd = sv->renamed[2];