mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 22:25:07 +00:00
parent
0dac7af6c5
commit
c589625418
6 changed files with 81 additions and 13 deletions
|
@ -757,23 +757,41 @@ int Shell::builtin_unset(int argc, const char** argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shell::run_builtin(int argc, const char** argv, int& retval)
|
bool Shell::run_builtin(const AST::Command& command, const NonnullRefPtrVector<AST::Rewiring>& rewirings, int& retval)
|
||||||
{
|
{
|
||||||
if (argc == 0)
|
if (command.argv.is_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
StringView name { argv[0] };
|
if (!has_builtin(command.argv.first()))
|
||||||
|
return false;
|
||||||
|
|
||||||
#define __ENUMERATE_SHELL_BUILTIN(builtin) \
|
Vector<const char*> argv;
|
||||||
if (name == #builtin) { \
|
for (auto& arg : command.argv)
|
||||||
retval = builtin_##builtin(argc, argv); \
|
argv.append(arg.characters());
|
||||||
return true; \
|
|
||||||
|
argv.append(nullptr);
|
||||||
|
|
||||||
|
StringView name = command.argv.first();
|
||||||
|
|
||||||
|
SavedFileDescriptors fds { rewirings };
|
||||||
|
|
||||||
|
for (auto& rewiring : rewirings) {
|
||||||
|
int rc = dup2(rewiring.dest_fd, rewiring.source_fd);
|
||||||
|
if (rc < 0) {
|
||||||
|
perror("dup2(run)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __ENUMERATE_SHELL_BUILTIN(builtin) \
|
||||||
|
if (name == #builtin) { \
|
||||||
|
retval = builtin_##builtin(argv.size() - 1, argv.data()); \
|
||||||
|
return true; \
|
||||||
}
|
}
|
||||||
|
|
||||||
ENUMERATE_SHELL_BUILTINS();
|
ENUMERATE_SHELL_BUILTINS();
|
||||||
|
|
||||||
#undef __ENUMERATE_SHELL_BUILTIN
|
#undef __ENUMERATE_SHELL_BUILTIN
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Forward.h"
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
#include <AK/NonnullRefPtrVector.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibCore/ElapsedTimer.h>
|
#include <LibCore/ElapsedTimer.h>
|
||||||
|
@ -42,3 +44,18 @@ public:
|
||||||
private:
|
private:
|
||||||
Vector<int, 32> m_fds;
|
Vector<int, 32> m_fds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SavedFileDescriptors {
|
||||||
|
public:
|
||||||
|
SavedFileDescriptors(const NonnullRefPtrVector<AST::Rewiring>&);
|
||||||
|
~SavedFileDescriptors();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct SavedFileDescriptor {
|
||||||
|
int original { -1 };
|
||||||
|
int saved { -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<SavedFileDescriptor> m_saves;
|
||||||
|
FileDescriptionCollector m_collector;
|
||||||
|
};
|
||||||
|
|
|
@ -33,5 +33,6 @@ class Node;
|
||||||
class Value;
|
class Value;
|
||||||
class SyntaxError;
|
class SyntaxError;
|
||||||
class Pipeline;
|
class Pipeline;
|
||||||
|
class Rewiring;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,6 +500,10 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
if (run_builtin(command, rewirings, retval))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
Vector<const char*> argv;
|
Vector<const char*> argv;
|
||||||
Vector<String> copy_argv = command.argv;
|
Vector<String> copy_argv = command.argv;
|
||||||
argv.ensure_capacity(command.argv.size() + 1);
|
argv.ensure_capacity(command.argv.size() + 1);
|
||||||
|
@ -509,10 +513,6 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
|
||||||
|
|
||||||
argv.append(nullptr);
|
argv.append(nullptr);
|
||||||
|
|
||||||
int retval = 0;
|
|
||||||
if (run_builtin(argv.size() - 1, argv.data(), retval))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
int sync_pipe[2];
|
int sync_pipe[2];
|
||||||
if (pipe(sync_pipe) < 0) {
|
if (pipe(sync_pipe) < 0) {
|
||||||
perror("pipe");
|
perror("pipe");
|
||||||
|
|
|
@ -78,7 +78,7 @@ public:
|
||||||
RefPtr<Job> run_command(const AST::Command&);
|
RefPtr<Job> run_command(const AST::Command&);
|
||||||
NonnullRefPtrVector<Job> run_commands(Vector<AST::Command>&);
|
NonnullRefPtrVector<Job> run_commands(Vector<AST::Command>&);
|
||||||
bool run_file(const String&, bool explicitly_invoked = true);
|
bool run_file(const String&, bool explicitly_invoked = true);
|
||||||
bool run_builtin(int argc, const char** argv, int& retval);
|
bool run_builtin(const AST::Command&, const NonnullRefPtrVector<AST::Rewiring>&, int& retval);
|
||||||
bool has_builtin(const StringView&) const;
|
bool has_builtin(const StringView&) const;
|
||||||
void block_on_job(RefPtr<Job>);
|
void block_on_job(RefPtr<Job>);
|
||||||
String prompt() const;
|
String prompt() const;
|
||||||
|
|
|
@ -56,6 +56,38 @@ void FileDescriptionCollector::add(int fd)
|
||||||
m_fds.append(fd);
|
m_fds.append(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SavedFileDescriptors::SavedFileDescriptors(const NonnullRefPtrVector<AST::Rewiring>& intended_rewirings)
|
||||||
|
{
|
||||||
|
for (auto& rewiring : intended_rewirings) {
|
||||||
|
int new_fd = dup(rewiring.source_fd);
|
||||||
|
if (new_fd < 0) {
|
||||||
|
if (errno != EBADF)
|
||||||
|
perror("dup");
|
||||||
|
// The fd that will be overwritten isn't open right now,
|
||||||
|
// it will be cleaned up by the exec()-side collector
|
||||||
|
// and we have nothing to do here, so just ignore this error.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto flags = fcntl(new_fd, F_GETFL);
|
||||||
|
auto rc = fcntl(new_fd, F_SETFL, flags | FD_CLOEXEC);
|
||||||
|
ASSERT(rc == 0);
|
||||||
|
|
||||||
|
m_saves.append({ rewiring.source_fd, new_fd });
|
||||||
|
m_collector.add(new_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedFileDescriptors::~SavedFileDescriptors()
|
||||||
|
{
|
||||||
|
for (auto& save : m_saves) {
|
||||||
|
if (dup2(save.saved, save.original) < 0) {
|
||||||
|
perror("dup2(~SavedFileDescriptors)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
Core::EventLoop loop;
|
Core::EventLoop loop;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue