Skip to content

Commit

Permalink
Shell: Add append operator (>>)
Browse files Browse the repository at this point in the history
  • Loading branch information
rburchell committed May 25, 2019
1 parent 391f51f commit d49f0a8
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 37 deletions.
16 changes: 15 additions & 1 deletion Shell/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ Vector<Subcommand> Parser::parse()
if (ch == '>') {
commit_token();
begin_redirect_write(STDOUT_FILENO);
m_state = State::InRedirectionPath;

// Search for another > for append.
m_state = State::InWriteAppendOrRedirectionPath;
break;
}
if (ch == '<') {
Expand All @@ -79,6 +81,18 @@ Vector<Subcommand> Parser::parse()
}
m_token.append(ch);
break;
case State::InWriteAppendOrRedirectionPath:
if (ch == '>') {
commit_token();
m_state = State::InRedirectionPath;
ASSERT(m_redirections.size());
m_redirections[m_redirections.size() - 1].type = Redirection::FileWriteAppend;
break;
}

// Not another > means that it's probably a path.
m_state = InRedirectionPath;
[[fallthrough]];
case State::InRedirectionPath:
if (ch == '<') {
commit_token();
Expand Down
3 changes: 2 additions & 1 deletion Shell/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <AK/Vector.h>

struct Redirection {
enum Type { Pipe, FileWrite, FileRead, Rewire };
enum Type { Pipe, FileWrite, FileWriteAppend, FileRead, Rewire };
Type type;
int fd { -1 };
int rewire_fd { -1 };
Expand Down Expand Up @@ -33,6 +33,7 @@ class Parser {
Free,
InSingleQuotes,
InDoubleQuotes,
InWriteAppendOrRedirectionPath,
InRedirectionPath,
};
State m_state { Free };
Expand Down
90 changes: 55 additions & 35 deletions Shell/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,24 +233,27 @@ static int run_command(const String& cmd)
#ifdef SH_DEBUG
for (int i = 0; i < subcommands.size(); ++i) {
for (int j = 0; j < i; ++j)
printf(" ");
dbgprintf(" ");
for (auto& arg : subcommands[i].args) {
printf("<%s> ", arg.characters());
dbgprintf("<%s> ", arg.characters());
}
printf("\n");
dbgprintf("\n");
for (auto& redirecton : subcommands[i].redirections) {
for (int j = 0; j < i; ++j)
printf(" ");
printf(" ");
dbgprintf(" ");
dbgprintf(" ");
switch (redirecton.type) {
case Redirection::Pipe:
printf("Pipe\n");
dbgprintf("Pipe\n");
break;
case Redirection::FileRead:
printf("fd:%d = FileRead: %s\n", redirecton.fd, redirecton.path.characters());
dbgprintf("fd:%d = FileRead: %s\n", redirecton.fd, redirecton.path.characters());
break;
case Redirection::FileWrite:
printf("fd:%d = FileWrite: %s\n", redirecton.fd, redirecton.path.characters());
dbgprintf("fd:%d = FileWrite: %s\n", redirecton.fd, redirecton.path.characters());
break;
case Redirection::FileWriteAppend:
dbgprintf("fd:%d = FileWriteAppend: %s\n", redirecton.fd, redirecton.path.characters());
break;
default:
break;
Expand All @@ -267,36 +270,53 @@ static int run_command(const String& cmd)
for (int i = 0; i < subcommands.size(); ++i) {
auto& subcommand = subcommands[i];
for (auto& redirection : subcommand.redirections) {
if (redirection.type == Redirection::Pipe) {
int pipefd[2];
int rc = pipe(pipefd);
if (rc < 0) {
perror("pipe");
return 1;
switch (redirection.type) {
case Redirection::Pipe: {
int pipefd[2];
int rc = pipe(pipefd);
if (rc < 0) {
perror("pipe");
return 1;
}
subcommand.redirections.append({ Redirection::Rewire, STDOUT_FILENO, pipefd[1] });
auto& next_command = subcommands[i + 1];
next_command.redirections.append({ Redirection::Rewire, STDIN_FILENO, pipefd[0] });
fds.add(pipefd[0]);
fds.add(pipefd[1]);
break;
}
subcommand.redirections.append({ Redirection::Rewire, STDOUT_FILENO, pipefd[1] });
auto& next_command = subcommands[i + 1];
next_command.redirections.append({ Redirection::Rewire, STDIN_FILENO, pipefd[0] });
fds.add(pipefd[0]);
fds.add(pipefd[1]);
}
if (redirection.type == Redirection::FileWrite) {
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666);
if (fd < 0) {
perror("open");
return 1;
case Redirection::FileWriteAppend: {
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT | O_APPEND, 0666);
if (fd < 0) {
perror("open");
return 1;
}
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
fds.add(fd);
break;
}
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
fds.add(fd);
}
if (redirection.type == Redirection::FileRead) {
int fd = open(redirection.path.characters(), O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
case Redirection::FileWrite: {
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666);
if (fd < 0) {
perror("open");
return 1;
}
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
fds.add(fd);
break;
}
case Redirection::FileRead: {
int fd = open(redirection.path.characters(), O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
fds.add(fd);
break;
}
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
fds.add(fd);
case Redirection::Rewire:
break; // ignore
}
}
}
Expand Down

0 comments on commit d49f0a8

Please sign in to comment.