mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-27 14:58:46 +00:00
parent
c6e79bd53a
commit
aee99b05a6
Notes:
sideshowbarker
2024-07-19 13:56:58 +09:00
Author: https://github.com/rburchell
Commit: aee99b05a6
Pull-request: https://github.com/SerenityOS/serenity/pull/96
3 changed files with 72 additions and 37 deletions
|
@ -60,7 +60,9 @@ Vector<Subcommand> Parser::parse()
|
||||||
if (ch == '>') {
|
if (ch == '>') {
|
||||||
commit_token();
|
commit_token();
|
||||||
begin_redirect_write(STDOUT_FILENO);
|
begin_redirect_write(STDOUT_FILENO);
|
||||||
m_state = State::InRedirectionPath;
|
|
||||||
|
// Search for another > for append.
|
||||||
|
m_state = State::InWriteAppendOrRedirectionPath;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
|
@ -79,6 +81,18 @@ Vector<Subcommand> Parser::parse()
|
||||||
}
|
}
|
||||||
m_token.append(ch);
|
m_token.append(ch);
|
||||||
break;
|
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:
|
case State::InRedirectionPath:
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
commit_token();
|
commit_token();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
struct Redirection {
|
struct Redirection {
|
||||||
enum Type { Pipe, FileWrite, FileRead, Rewire };
|
enum Type { Pipe, FileWrite, FileWriteAppend, FileRead, Rewire };
|
||||||
Type type;
|
Type type;
|
||||||
int fd { -1 };
|
int fd { -1 };
|
||||||
int rewire_fd { -1 };
|
int rewire_fd { -1 };
|
||||||
|
@ -33,6 +33,7 @@ private:
|
||||||
Free,
|
Free,
|
||||||
InSingleQuotes,
|
InSingleQuotes,
|
||||||
InDoubleQuotes,
|
InDoubleQuotes,
|
||||||
|
InWriteAppendOrRedirectionPath,
|
||||||
InRedirectionPath,
|
InRedirectionPath,
|
||||||
};
|
};
|
||||||
State m_state { Free };
|
State m_state { Free };
|
||||||
|
|
|
@ -233,24 +233,27 @@ static int run_command(const String& cmd)
|
||||||
#ifdef SH_DEBUG
|
#ifdef SH_DEBUG
|
||||||
for (int i = 0; i < subcommands.size(); ++i) {
|
for (int i = 0; i < subcommands.size(); ++i) {
|
||||||
for (int j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j)
|
||||||
printf(" ");
|
dbgprintf(" ");
|
||||||
for (auto& arg : subcommands[i].args) {
|
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 (auto& redirecton : subcommands[i].redirections) {
|
||||||
for (int j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j)
|
||||||
printf(" ");
|
dbgprintf(" ");
|
||||||
printf(" ");
|
dbgprintf(" ");
|
||||||
switch (redirecton.type) {
|
switch (redirecton.type) {
|
||||||
case Redirection::Pipe:
|
case Redirection::Pipe:
|
||||||
printf("Pipe\n");
|
dbgprintf("Pipe\n");
|
||||||
break;
|
break;
|
||||||
case Redirection::FileRead:
|
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;
|
break;
|
||||||
case Redirection::FileWrite:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -267,36 +270,53 @@ static int run_command(const String& cmd)
|
||||||
for (int i = 0; i < subcommands.size(); ++i) {
|
for (int i = 0; i < subcommands.size(); ++i) {
|
||||||
auto& subcommand = subcommands[i];
|
auto& subcommand = subcommands[i];
|
||||||
for (auto& redirection : subcommand.redirections) {
|
for (auto& redirection : subcommand.redirections) {
|
||||||
if (redirection.type == Redirection::Pipe) {
|
switch (redirection.type) {
|
||||||
int pipefd[2];
|
case Redirection::Pipe: {
|
||||||
int rc = pipe(pipefd);
|
int pipefd[2];
|
||||||
if (rc < 0) {
|
int rc = pipe(pipefd);
|
||||||
perror("pipe");
|
if (rc < 0) {
|
||||||
return 1;
|
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] });
|
case Redirection::FileWriteAppend: {
|
||||||
auto& next_command = subcommands[i + 1];
|
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT | O_APPEND, 0666);
|
||||||
next_command.redirections.append({ Redirection::Rewire, STDIN_FILENO, pipefd[0] });
|
if (fd < 0) {
|
||||||
fds.add(pipefd[0]);
|
perror("open");
|
||||||
fds.add(pipefd[1]);
|
return 1;
|
||||||
}
|
}
|
||||||
if (redirection.type == Redirection::FileWrite) {
|
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
|
||||||
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666);
|
fds.add(fd);
|
||||||
if (fd < 0) {
|
break;
|
||||||
perror("open");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
|
case Redirection::FileWrite: {
|
||||||
fds.add(fd);
|
int fd = open(redirection.path.characters(), O_WRONLY | O_CREAT, 0666);
|
||||||
}
|
if (fd < 0) {
|
||||||
if (redirection.type == Redirection::FileRead) {
|
perror("open");
|
||||||
int fd = open(redirection.path.characters(), O_RDONLY);
|
return 1;
|
||||||
if (fd < 0) {
|
}
|
||||||
perror("open");
|
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
|
||||||
return 1;
|
fds.add(fd);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
subcommand.redirections.append({ Redirection::Rewire, redirection.fd, fd });
|
case Redirection::FileRead: {
|
||||||
fds.add(fd);
|
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;
|
||||||
|
}
|
||||||
|
case Redirection::Rewire:
|
||||||
|
break; // ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue