In redirection operations, map fds 0/1/2 to 1/2/3 so they work as stdin/stdout/stderr, preserving compatibility with Unix shell scripts.

Also do a similar mapping for fds passed to "read -u" and "test -t".
This commit is contained in:
Stephen Heumann 2014-11-20 23:12:01 -06:00
parent 432950e315
commit 72634b98b9
3 changed files with 35 additions and 8 deletions

View File

@ -782,8 +782,18 @@ static number_t primary(enum token n)
unnest_msg_and_return(args[0][0] == '\0', ("<primary"));
if (n == STRNZ)
unnest_msg_and_return(args[0][0] != '\0', ("<primary"));
if (n == FILTT)
unnest_msg_and_return(isatty(getn(*args)), ("<primary: isatty(%s)", *args));
if (n == FILTT) {
/* Map fds for stdin/stdout/stderr from the Unix fds to GNO ones.
* Existing GNO /bin/test doesn't map fds here, but we prioritize
* compatibility with Unix scripts and do the remapping.
*/
number_t fd = getn(*args);
#ifdef __GNO__
if (fd >= 0 && fd <= 2)
fd++;
#endif
unnest_msg_and_return(isatty(fd), ("<primary: isatty(%s)", *args));
}
unnest_msg_and_return(filstat(*args, n), ("<primary: filstat(%s)", *args));
}

View File

@ -495,11 +495,11 @@ static const struct {
signed char default_fd;
char descrip[3];
} redir_table[] = {
{ O_RDONLY, 0, "<" },
{ O_CREAT|O_TRUNC|O_WRONLY, 1, ">" },
{ O_CREAT|O_APPEND|O_WRONLY, 1, ">>" },
{ O_CREAT|O_RDWR, 1, "<>" },
{ O_RDONLY, 0, "<<" },
{ O_RDONLY, STDIN_FILENO, "<" },
{ O_CREAT|O_TRUNC|O_WRONLY, STDOUT_FILENO, ">" },
{ O_CREAT|O_APPEND|O_WRONLY, STDOUT_FILENO, ">>" },
{ O_CREAT|O_RDWR, STDOUT_FILENO, "<>" },
{ O_RDONLY, STDIN_FILENO, "<<" },
/* Should not be needed. Bogus default_fd helps in debugging */
/* { O_RDONLY, 77, "<<" }, */
};
@ -3603,7 +3603,15 @@ static int parse_redirect(struct parse_context *ctx,
/* redir->next = NULL; */
/* redir->rd_filename = NULL; */
redir->rd_type = style;
redir->rd_fd = (fd == -1) ? redir_table[style].default_fd : fd;
/* On GNO, we map fd 0/1/2 in scripts to stdin/stdout/stderr
* to preserve compatibility with Unix shell scripts. */
redir->rd_fd = (fd == -1) ? redir_table[style].default_fd :
#ifndef __GNO__
fd;
#else
(fd < 3 ? fd + 1 : fd);
#endif
debug_printf_parse(("redirect type %d %s\n", redir->rd_fd,
redir_table[style].descrip));
@ -3613,6 +3621,10 @@ static int parse_redirect(struct parse_context *ctx,
/* Erik had a check here that the file descriptor in question
* is legit; I postpone that to "run time"
* A "-" representation of "close me" shows up as a -3 here */
#ifdef __GNO__
if (redir->rd_dup >= 0 && redir->rd_dup <= 2)
redir->rd_dup++;
#endif
debug_printf_parse(("duplicating redirect '%d>&%d'\n",
redir->rd_fd, redir->rd_dup));
} else {

View File

@ -127,6 +127,11 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val),
fd = bb_strtou(opt_u, NULL, 10);
if (fd < 0 || errno)
return "invalid file descriptor";
#ifdef __GNO__
/* Map Unix standard stdin/stdout/stderr fds to GNO ones */
if (fd < 3)
fd++;
#endif
}
if (opt_p && isatty(fd)) {