mirror of
https://github.com/ksherlock/mpw-shell.git
synced 2024-06-09 02:29:30 +00:00
more file redirection.
This commit is contained in:
parent
e3ed9dec46
commit
0c96252d65
|
@ -22,18 +22,30 @@ T pop(std::vector<T> &v) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
### MPW Shell - Unable to open "nofile".
|
||||||
|
# File not found (OS error -43)
|
||||||
|
{status} = -4
|
||||||
|
*/
|
||||||
|
|
||||||
|
void open_error(const std::string &name) {
|
||||||
|
|
||||||
|
std::string error = "### MPW Shell - Unable to open ";
|
||||||
|
error.push_back('"');
|
||||||
|
error.append(name);
|
||||||
|
error.push_back('"');
|
||||||
|
error.push_back('.');
|
||||||
|
throw std::runtime_error(error);
|
||||||
|
}
|
||||||
|
|
||||||
int open(const std::string &name, int flags) {
|
int open(const std::string &name, int flags) {
|
||||||
|
|
||||||
// dup2 does not copy the O_CLOEXEC flag so it's safe to use.
|
// dup2 does not copy the O_CLOEXEC flag so it's safe to use.
|
||||||
|
|
||||||
int fd = ::open(name.c_str(), flags | O_CLOEXEC, 0666);
|
int fd = ::open(name.c_str(), flags | O_CLOEXEC, 0666);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
std::string error = "### MPW Shell - Unable to open ";
|
open_error(name);
|
||||||
error.push_back('"');
|
return -1;
|
||||||
error.append(name);
|
|
||||||
error.push_back('"');
|
|
||||||
error.push_back('.');
|
|
||||||
throw std::runtime_error(error);
|
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -55,39 +67,90 @@ void parse_tokens(std::vector<token> &&tokens, process &p) {
|
||||||
|
|
||||||
t = pop(tokens);
|
t = pop(tokens);
|
||||||
|
|
||||||
|
int flags;
|
||||||
|
unsigned fd_bits;
|
||||||
|
|
||||||
switch (t.type) {
|
switch (t.type) {
|
||||||
|
|
||||||
// >, >> -- redirect stdout.
|
// >, >> -- redirect stdout.
|
||||||
case '>':
|
case '>':
|
||||||
|
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||||
|
fd_bits = 1 << 1;
|
||||||
|
goto redir;
|
||||||
|
|
||||||
case '>>':
|
case '>>':
|
||||||
{
|
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||||
int flags;
|
fd_bits = 1 << 1;
|
||||||
if (t.type == '>') flags = O_WRONLY | O_CREAT | O_TRUNC;
|
goto redir;
|
||||||
else flags = O_WRONLY | O_CREAT | O_APPEND;
|
|
||||||
|
|
||||||
if (tokens.empty()) {
|
|
||||||
throw std::runtime_error("### MPW Shell - Missing file name.");
|
|
||||||
}
|
|
||||||
token name = pop(tokens);
|
|
||||||
int fd = open(name.string, flags);
|
|
||||||
fds.set(1, fd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// < -- redirect stdin.
|
|
||||||
case '<':
|
case '<':
|
||||||
{
|
flags = O_RDONLY;
|
||||||
int flags = O_RDONLY;
|
fd_bits = 1 << 0;
|
||||||
|
goto redir;
|
||||||
|
|
||||||
|
// ∑, ∑∑ - redirect stdout & stderr
|
||||||
|
case 0xb7: // ∑
|
||||||
|
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||||
|
fd_bits = (1 << 1) + (1 << 2);
|
||||||
|
goto redir;
|
||||||
|
|
||||||
|
case 0xb7b7: // ∑∑
|
||||||
|
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||||
|
fd_bits = (1 << 1) + (1 << 2);
|
||||||
|
goto redir;
|
||||||
|
|
||||||
|
// ≥, ≥≥ -- redirect stdout.
|
||||||
|
case 0xb3: // ≥
|
||||||
|
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||||
|
fd_bits = 1 << 2;
|
||||||
|
goto redir;
|
||||||
|
|
||||||
|
case 0xb3b3: // ≥≥
|
||||||
|
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||||
|
fd_bits = 1 << 2;
|
||||||
|
goto redir;
|
||||||
|
|
||||||
|
redir:
|
||||||
|
|
||||||
|
{
|
||||||
if (tokens.empty()) {
|
if (tokens.empty()) {
|
||||||
throw std::runtime_error("### MPW Shell - Missing file name.");
|
throw std::runtime_error("### MPW Shell - Missing file name.");
|
||||||
}
|
}
|
||||||
token name = pop(tokens);
|
token name = pop(tokens);
|
||||||
int fd = open(name.string, flags);
|
int fd = open(name.string, flags);
|
||||||
fds.set(0, fd);
|
|
||||||
|
|
||||||
|
// todo -- if multiple fd_bits (stdin+stderr, should dup the second fd?)
|
||||||
|
switch(fd_bits) {
|
||||||
|
case 1 << 0:
|
||||||
|
fds.set(0, fd);
|
||||||
|
break;
|
||||||
|
case 1 << 1:
|
||||||
|
fds.set(1, fd);
|
||||||
|
break;
|
||||||
|
case 1 << 2:
|
||||||
|
fds.set(2, fd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (1 << 1) + (1 << 2):
|
||||||
|
{
|
||||||
|
int newfd = fcntl(fd, F_DUPFD_CLOEXEC);
|
||||||
|
if (newfd < 1) {
|
||||||
|
close(fd);
|
||||||
|
open_error(name);
|
||||||
|
}
|
||||||
|
fds.set(1, fd);
|
||||||
|
fds.set(2, newfd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// ???
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
argv.emplace_back(std::move(t.string));
|
argv.emplace_back(std::move(t.string));
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user