Skip to content

Commit

Permalink
Shell: Place Pipe redirections at the beginning of the redirection list
Browse files Browse the repository at this point in the history
This makes commands like `foo 2>&1 | bar` behave as expected (which is
to pipe both stdout and stderr of `foo` to stdin of `bar`).
Previously, this would've piped stderr of `foo` into stdout, and the
stdout of `foo` into the stdin of `bar`.
  • Loading branch information
alimpfard authored and awesomekling committed Mar 31, 2021
1 parent e8cfa43 commit c4cf4ef
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions Userland/Shell/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2220,8 +2220,27 @@ RefPtr<Value> Pipe::run(RefPtr<Shell> shell)

auto pipe_read_end = FdRedirection::create(-1, STDIN_FILENO, Rewiring::Close::Old);
auto pipe_write_end = FdRedirection::create(-1, STDOUT_FILENO, pipe_read_end, Rewiring::Close::RefreshOld);
first_in_right.redirections.append(pipe_read_end);
last_in_left.redirections.append(pipe_write_end);

auto insert_at_start_or_after_last_pipe = [&](auto& pipe, auto& command) {
size_t insert_index = 0;
auto& redirections = command.redirections;
for (ssize_t i = redirections.size() - 1; i >= 0; --i) {
auto& redirection = redirections[i];
if (!redirection.is_fd_redirection())
continue;
auto& fd_redirection = static_cast<FdRedirection&>(redirection);
if (fd_redirection.old_fd == -1) {
insert_index = i;
break;
}
}

redirections.insert(insert_index, pipe);
};

insert_at_start_or_after_last_pipe(pipe_read_end, first_in_right);
insert_at_start_or_after_last_pipe(pipe_write_end, last_in_left);

last_in_left.should_wait = false;
last_in_left.is_pipe_source = true;

Expand Down

0 comments on commit c4cf4ef

Please sign in to comment.