diff options
author | Karol Baraniecki <karol@baraniecki.eu> | 2019-12-04 13:31:53 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-12-05 17:08:37 +0100 |
commit | 431abc8846263a78002d6b5869dc76e6acdcb72c (patch) | |
tree | 0f9ab8762aa09693abdf5606681a270ef530a073 /Shell/Parser.cpp | |
parent | 7ed8a468ec9da8f03dc791926591ebaafd54b185 (diff) | |
download | serenity-431abc8846263a78002d6b5869dc76e6acdcb72c.zip |
Shell: Redirectiong from multiple-digit fds
Diffstat (limited to 'Shell/Parser.cpp')
-rw-r--r-- | Shell/Parser.cpp | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index 2280ef4057..8cf09e5c9d 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -103,6 +103,51 @@ Vector<Command> Parser::parse() m_state = State::InDoubleQuotes; break; } + + // redirection from zsh-style multi-digit fd, such as {10}>file + if (ch == '{') { + bool is_multi_fd_redirection = false; + int redir_end = i + 1; + + while (redir_end < m_input.length()) { + char lookahead_ch = m_input.characters()[redir_end]; + if (isdigit(lookahead_ch)) { + ++redir_end; + continue; + } + if (lookahead_ch == '}' && redir_end + 1 != m_input.length()) { + // Disallow {}> and {}< + if (redir_end == i + 1) + break; + + ++redir_end; + if (m_input.characters()[redir_end] == '>' || m_input.characters()[redir_end] == '<') + is_multi_fd_redirection = true; + break; + } + break; + } + + if (is_multi_fd_redirection) { + commit_token(); + + int fd = atoi(&m_input.characters()[i + 1]); + + if (m_input.characters()[redir_end] == '>') { + begin_redirect_write(fd); + // Search for another > for append. + m_state = State::InWriteAppendOrRedirectionPath; + } + if (m_input.characters()[redir_end] == '<') { + begin_redirect_read(fd); + m_state = State::InRedirectionPath; + } + + i = redir_end; + + break; + } + } if (isdigit(ch)) { if (i != m_input.length() - 1) { char next_ch = m_input.characters()[i + 1]; |