mirror of
https://github.com/sheumann/hush.git
synced 2025-02-07 04:31:22 +00:00
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:
parent
432950e315
commit
72634b98b9
@ -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));
|
||||
}
|
||||
|
||||
|
24
shell/hush.c
24
shell/hush.c
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user