ash: explain redirect code a bit
function old new delta redirect 1059 1054 -5
This commit is contained in:
parent
2dc240c0d6
commit
0b76964ae1
54
shell/ash.c
54
shell/ash.c
@ -594,8 +594,8 @@ struct nfile {
|
|||||||
|
|
||||||
struct ndup {
|
struct ndup {
|
||||||
smallint type;
|
smallint type;
|
||||||
union node *next;
|
union node *next; /* must match nfile's layout */
|
||||||
int fd;
|
int fd; /* must match nfile's layout */
|
||||||
int dupfd;
|
int dupfd;
|
||||||
union node *vname;
|
union node *vname;
|
||||||
};
|
};
|
||||||
@ -1634,12 +1634,6 @@ nextopt(const char *optstring)
|
|||||||
* The parsefile structure pointed to by the global variable parsefile
|
* The parsefile structure pointed to by the global variable parsefile
|
||||||
* contains information about the current file being read.
|
* contains information about the current file being read.
|
||||||
*/
|
*/
|
||||||
struct redirtab {
|
|
||||||
struct redirtab *next;
|
|
||||||
int renamed[10];
|
|
||||||
int nullredirs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct shparam {
|
struct shparam {
|
||||||
int nparam; /* # of positional parameters (without $0) */
|
int nparam; /* # of positional parameters (without $0) */
|
||||||
#if ENABLE_ASH_GETOPTS
|
#if ENABLE_ASH_GETOPTS
|
||||||
@ -1765,6 +1759,7 @@ static const struct {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct redirtab;
|
||||||
|
|
||||||
struct globals_var {
|
struct globals_var {
|
||||||
struct shparam shellparam; /* $@ current positional parameters */
|
struct shparam shellparam; /* $@ current positional parameters */
|
||||||
@ -1777,7 +1772,7 @@ struct globals_var {
|
|||||||
extern struct globals_var *const ash_ptr_to_globals_var;
|
extern struct globals_var *const ash_ptr_to_globals_var;
|
||||||
#define G_var (*ash_ptr_to_globals_var)
|
#define G_var (*ash_ptr_to_globals_var)
|
||||||
#define shellparam (G_var.shellparam )
|
#define shellparam (G_var.shellparam )
|
||||||
#define redirlist (G_var.redirlist )
|
//#define redirlist (G_var.redirlist )
|
||||||
#define g_nullredirs (G_var.g_nullredirs )
|
#define g_nullredirs (G_var.g_nullredirs )
|
||||||
#define preverrout_fd (G_var.preverrout_fd)
|
#define preverrout_fd (G_var.preverrout_fd)
|
||||||
#define vartab (G_var.vartab )
|
#define vartab (G_var.vartab )
|
||||||
@ -4767,6 +4762,7 @@ openhere(union node *redir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
|
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
|
||||||
|
/* child */
|
||||||
close(pip[0]);
|
close(pip[0]);
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGQUIT, SIG_IGN);
|
signal(SIGQUIT, SIG_IGN);
|
||||||
@ -4777,7 +4773,7 @@ openhere(union node *redir)
|
|||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
if (redir->type == NHERE)
|
if (redir->type == NHERE)
|
||||||
full_write(pip[1], redir->nhere.doc->narg.text, len);
|
full_write(pip[1], redir->nhere.doc->narg.text, len);
|
||||||
else
|
else /* NXHERE */
|
||||||
expandhere(redir->nhere.doc, pip[1]);
|
expandhere(redir->nhere.doc, pip[1]);
|
||||||
_exit(EXIT_SUCCESS);
|
_exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -4832,10 +4828,10 @@ openredirect(union node *redir)
|
|||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
/* Fall through to eliminate warning. */
|
/* Fall through to eliminate warning. */
|
||||||
case NTOFD:
|
// case NTOFD:
|
||||||
case NFROMFD:
|
// case NFROMFD:
|
||||||
f = -1;
|
// f = -1;
|
||||||
break;
|
// break;
|
||||||
case NHERE:
|
case NHERE:
|
||||||
case NXHERE:
|
case NXHERE:
|
||||||
f = openhere(redir);
|
f = openhere(redir);
|
||||||
@ -4873,19 +4869,26 @@ dupredirect(union node *redir, int f)
|
|||||||
{
|
{
|
||||||
int fd = redir->nfile.fd;
|
int fd = redir->nfile.fd;
|
||||||
|
|
||||||
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
|
if (f < 0) { /* redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD */
|
||||||
if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
|
if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
|
||||||
copyfd(redir->ndup.dupfd, fd);
|
copyfd(redir->ndup.dupfd, fd);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f != fd) {
|
if (f != fd) {
|
||||||
copyfd(f, fd);
|
copyfd(f, fd);
|
||||||
close(f);
|
close(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
struct redirtab {
|
||||||
|
struct redirtab *next;
|
||||||
|
int renamed[10];
|
||||||
|
int nullredirs;
|
||||||
|
};
|
||||||
|
#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,
|
||||||
* old file descriptors are stashed away so that the redirection can be
|
* old file descriptors are stashed away so that the redirection can be
|
||||||
@ -4921,11 +4924,12 @@ redirect(union node *redir, int flags)
|
|||||||
}
|
}
|
||||||
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) {
|
||||||
&& redir->ndup.dupfd == fd)
|
if (redir->ndup.dupfd == fd)
|
||||||
continue; /* redirect from/to same file descriptor */
|
continue; /* redirect from/to same file descriptor */
|
||||||
|
newfd = -1;
|
||||||
newfd = openredirect(redir);
|
} else {
|
||||||
|
newfd = openredirect(redir); /* always >= 0 */
|
||||||
if (fd == newfd) {
|
if (fd == newfd) {
|
||||||
/* Descriptor wasn't open before redirect.
|
/* Descriptor wasn't open before redirect.
|
||||||
* Mark it for close in the future */
|
* Mark it for close in the future */
|
||||||
@ -4933,24 +4937,30 @@ redirect(union node *redir, int flags)
|
|||||||
sv->renamed[fd] = CLOSED;
|
sv->renamed[fd] = CLOSED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (sv && sv->renamed[fd] == EMPTY) {
|
if (sv && sv->renamed[fd] == EMPTY) {
|
||||||
|
/* Copy old descriptor */
|
||||||
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) {
|
if (i != EBADF) { /* strange error */
|
||||||
close(newfd);
|
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 */
|
||||||
} else {
|
} else {
|
||||||
|
/* it is open, save its copy */
|
||||||
sv->renamed[fd] = i;
|
sv->renamed[fd] = i;
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
/* Here fd is closed */
|
||||||
|
/* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */
|
||||||
|
/* else: move newfd to fd */
|
||||||
dupredirect(redir, newfd);
|
dupredirect(redir, newfd);
|
||||||
} while ((redir = redir->nfile.next) != NULL);
|
} while ((redir = redir->nfile.next) != NULL);
|
||||||
INT_ON;
|
INT_ON;
|
||||||
|
Loading…
Reference in New Issue
Block a user