summaryrefslogtreecommitdiff
path: root/Shell/Parser.cpp
diff options
context:
space:
mode:
authorKarol Baraniecki <karol@baraniecki.eu>2019-12-04 13:31:53 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-05 17:08:37 +0100
commit431abc8846263a78002d6b5869dc76e6acdcb72c (patch)
tree0f9ab8762aa09693abdf5606681a270ef530a073 /Shell/Parser.cpp
parent7ed8a468ec9da8f03dc791926591ebaafd54b185 (diff)
downloadserenity-431abc8846263a78002d6b5869dc76e6acdcb72c.zip
Shell: Redirectiong from multiple-digit fds
Diffstat (limited to 'Shell/Parser.cpp')
-rw-r--r--Shell/Parser.cpp45
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];