From 72634b98b9d78dbebec868b3e6fd0d5227162343 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 20 Nov 2014 23:12:01 -0600 Subject: [PATCH] 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". --- coreutils/test.c | 14 ++++++++++++-- shell/hush.c | 24 ++++++++++++++++++------ shell/shell.common.c | 5 +++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/coreutils/test.c b/coreutils/test.c index 4dc36e8a9..7ffd8132b 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -782,8 +782,18 @@ static number_t primary(enum token n) unnest_msg_and_return(args[0][0] == '\0', ("= 0 && fd <= 2) + fd++; +#endif + unnest_msg_and_return(isatty(fd), ("" }, - { 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 { diff --git a/shell/shell.common.c b/shell/shell.common.c index 16cb397d0..b75a9685d 100644 --- a/shell/shell.common.c +++ b/shell/shell.common.c @@ -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)) {