diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-20 15:16:00 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-20 15:16:00 +0200 |
commit | 869994cf4f9647fdfb519a1945f8582e71d3df3d (patch) | |
tree | 30741b547421ab4c82e5bdf631afacec7665e3e0 /shell | |
parent | e9abe75fda82a986b0b40969ebdd4aa92bcb52e3 (diff) | |
download | busybox-w32-869994cf4f9647fdfb519a1945f8582e71d3df3d.tar.gz busybox-w32-869994cf4f9647fdfb519a1945f8582e71d3df3d.tar.bz2 busybox-w32-869994cf4f9647fdfb519a1945f8582e71d3df3d.zip |
hush: bit better comments in redirect code. No logic changes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/shell/hush.c b/shell/hush.c index b41d9d04b..9b45b312f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -6099,10 +6099,12 @@ static int setup_redirects(struct command *prog, int squirrel[]) | |||
6099 | 6099 | ||
6100 | for (redir = prog->redirects; redir; redir = redir->next) { | 6100 | for (redir = prog->redirects; redir; redir = redir->next) { |
6101 | if (redir->rd_type == REDIRECT_HEREDOC2) { | 6101 | if (redir->rd_type == REDIRECT_HEREDOC2) { |
6102 | /* rd_fd<<HERE case */ | 6102 | /* "rd_fd<<HERE" case */ |
6103 | if (squirrel && redir->rd_fd < 3 | 6103 | if (redir->rd_fd <= 2 |
6104 | && squirrel | ||
6104 | && squirrel[redir->rd_fd] < 0 | 6105 | && squirrel[redir->rd_fd] < 0 |
6105 | ) { | 6106 | ) { |
6107 | /* Save old fds 0..2 if redirect uses them */ | ||
6106 | squirrel[redir->rd_fd] = dup(redir->rd_fd); | 6108 | squirrel[redir->rd_fd] = dup(redir->rd_fd); |
6107 | } | 6109 | } |
6108 | /* for REDIRECT_HEREDOC2, rd_filename holds _contents_ | 6110 | /* for REDIRECT_HEREDOC2, rd_filename holds _contents_ |
@@ -6114,7 +6116,7 @@ static int setup_redirects(struct command *prog, int squirrel[]) | |||
6114 | } | 6116 | } |
6115 | 6117 | ||
6116 | if (redir->rd_dup == REDIRFD_TO_FILE) { | 6118 | if (redir->rd_dup == REDIRFD_TO_FILE) { |
6117 | /* rd_fd<*>file case (<*> is <,>,>>,<>) */ | 6119 | /* "rd_fd<*>file" case (<*> is <,>,>>,<>) */ |
6118 | char *p; | 6120 | char *p; |
6119 | if (redir->rd_filename == NULL) { | 6121 | if (redir->rd_filename == NULL) { |
6120 | /* Something went wrong in the parse. | 6122 | /* Something went wrong in the parse. |
@@ -6127,20 +6129,33 @@ static int setup_redirects(struct command *prog, int squirrel[]) | |||
6127 | openfd = open_or_warn(p, mode); | 6129 | openfd = open_or_warn(p, mode); |
6128 | free(p); | 6130 | free(p); |
6129 | if (openfd < 0) { | 6131 | if (openfd < 0) { |
6130 | /* this could get lost if stderr has been redirected, but | 6132 | /* Error message from open_or_warn can be lost |
6131 | * bash and ash both lose it as well (though zsh doesn't!) */ | 6133 | * if stderr has been redirected, but bash |
6132 | //what the above comment tries to say? | 6134 | * and ash both lose it as well |
6135 | * (though zsh doesn't!) | ||
6136 | */ | ||
6133 | return 1; | 6137 | return 1; |
6134 | } | 6138 | } |
6135 | } else { | 6139 | } else { |
6136 | /* rd_fd<*>rd_dup or rd_fd<*>- cases */ | 6140 | /* "rd_fd<*>rd_dup" or "rd_fd<*>-" cases */ |
6137 | openfd = redir->rd_dup; | 6141 | openfd = redir->rd_dup; |
6138 | } | 6142 | } |
6139 | 6143 | ||
6140 | if (openfd != redir->rd_fd) { | 6144 | if (openfd != redir->rd_fd) { |
6141 | if (squirrel && redir->rd_fd < 3 | 6145 | if (redir->rd_fd <= 2 |
6146 | && squirrel | ||
6142 | && squirrel[redir->rd_fd] < 0 | 6147 | && squirrel[redir->rd_fd] < 0 |
6143 | ) { | 6148 | ) { |
6149 | /* Save old fds 0..2 if redirect uses them */ | ||
6150 | //FIXME: script fd's also need this! "sh SCRIPT" and SCRIPT has "echo FOO 3>&-": | ||
6151 | // open("SCRIPT", O_RDONLY) = 3 | ||
6152 | // fcntl(3, F_SETFD, FD_CLOEXEC) = 0 | ||
6153 | // read(3, "echo FOO 3>&-\n....", 4096) = N | ||
6154 | // close(3) = 0 | ||
6155 | // write(1, "FOO\n", 4) = 4 | ||
6156 | // ... | ||
6157 | // read(3, 0x205f8e0, 4096) = -1 EBADF <== BUG | ||
6158 | // | ||
6144 | squirrel[redir->rd_fd] = dup(redir->rd_fd); | 6159 | squirrel[redir->rd_fd] = dup(redir->rd_fd); |
6145 | } | 6160 | } |
6146 | if (openfd == REDIRFD_CLOSE) { | 6161 | if (openfd == REDIRFD_CLOSE) { |
@@ -6159,7 +6174,7 @@ static int setup_redirects(struct command *prog, int squirrel[]) | |||
6159 | static void restore_redirects(int squirrel[]) | 6174 | static void restore_redirects(int squirrel[]) |
6160 | { | 6175 | { |
6161 | int i, fd; | 6176 | int i, fd; |
6162 | for (i = 0; i < 3; i++) { | 6177 | for (i = 0; i <= 2; i++) { |
6163 | fd = squirrel[i]; | 6178 | fd = squirrel[i]; |
6164 | if (fd != -1) { | 6179 | if (fd != -1) { |
6165 | /* We simply die on error */ | 6180 | /* We simply die on error */ |
@@ -7144,6 +7159,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
7144 | if (x->b_function == builtin_exec && argv_expanded[1] == NULL) { | 7159 | if (x->b_function == builtin_exec && argv_expanded[1] == NULL) { |
7145 | debug_printf("exec with redirects only\n"); | 7160 | debug_printf("exec with redirects only\n"); |
7146 | rcode = setup_redirects(command, NULL); | 7161 | rcode = setup_redirects(command, NULL); |
7162 | /* rcode=1 can be if redir file can't be opened */ | ||
7147 | goto clean_up_and_ret1; | 7163 | goto clean_up_and_ret1; |
7148 | } | 7164 | } |
7149 | } | 7165 | } |
@@ -7270,9 +7286,20 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
7270 | if (pipefds.rd > 1) | 7286 | if (pipefds.rd > 1) |
7271 | close(pipefds.rd); | 7287 | close(pipefds.rd); |
7272 | /* Like bash, explicit redirects override pipes, | 7288 | /* Like bash, explicit redirects override pipes, |
7273 | * and the pipe fd is available for dup'ing. */ | 7289 | * and the pipe fd (fd#1) is available for dup'ing: |
7274 | if (setup_redirects(command, NULL)) | 7290 | * "cmd1 2>&1 | cmd2": fd#1 is duped to fd#2, thus stderr |
7291 | * of cmd1 goes into pipe. | ||
7292 | */ | ||
7293 | if (setup_redirects(command, NULL)) { | ||
7294 | /* Happens when redir file can't be opened: | ||
7295 | * $ hush -c 'echo FOO >&2 | echo BAR 3>/qwe/rty; echo BAZ' | ||
7296 | * FOO | ||
7297 | * hush: can't open '/qwe/rty': No such file or directory | ||
7298 | * BAZ | ||
7299 | * (echo BAR is not executed, it hits _exit(1) below) | ||
7300 | */ | ||
7275 | _exit(1); | 7301 | _exit(1); |
7302 | } | ||
7276 | 7303 | ||
7277 | /* Stores to nommu_save list of env vars putenv'ed | 7304 | /* Stores to nommu_save list of env vars putenv'ed |
7278 | * (NOMMU, on MMU we don't need that) */ | 7305 | * (NOMMU, on MMU we don't need that) */ |