diff options
-rw-r--r-- | Libraries/LibGUI/ShellSyntaxHighlighter.cpp | 2 | ||||
-rw-r--r-- | Shell/AST.cpp | 2 | ||||
-rw-r--r-- | Shell/AST.h | 2 | ||||
-rw-r--r-- | Shell/Builtin.cpp | 4 | ||||
-rw-r--r-- | Shell/Execution.h | 4 | ||||
-rw-r--r-- | Shell/Formatter.cpp | 4 | ||||
-rw-r--r-- | Shell/Formatter.h | 4 | ||||
-rw-r--r-- | Shell/Forward.h | 9 | ||||
-rw-r--r-- | Shell/Job.cpp | 4 | ||||
-rw-r--r-- | Shell/Job.h | 4 | ||||
-rw-r--r-- | Shell/NodeVisitor.cpp | 2 | ||||
-rw-r--r-- | Shell/NodeVisitor.h | 2 | ||||
-rw-r--r-- | Shell/Parser.cpp | 4 | ||||
-rw-r--r-- | Shell/Parser.h | 4 | ||||
-rw-r--r-- | Shell/Shell.cpp | 62 | ||||
-rw-r--r-- | Shell/Shell.h | 7 | ||||
-rw-r--r-- | Shell/main.cpp | 12 |
17 files changed, 115 insertions, 17 deletions
diff --git a/Libraries/LibGUI/ShellSyntaxHighlighter.cpp b/Libraries/LibGUI/ShellSyntaxHighlighter.cpp index 9c8b72c289..cfbcf3ad9c 100644 --- a/Libraries/LibGUI/ShellSyntaxHighlighter.cpp +++ b/Libraries/LibGUI/ShellSyntaxHighlighter.cpp @@ -33,6 +33,8 @@ namespace GUI { +using namespace Shell; + enum class AugmentedTokenKind : u32 { __TokenTypeCount = (u32)AST::Node::Kind::__Count, OpenParen, diff --git a/Shell/AST.cpp b/Shell/AST.cpp index c66328e971..1ec8e1411f 100644 --- a/Shell/AST.cpp +++ b/Shell/AST.cpp @@ -37,7 +37,7 @@ //#define EXECUTE_DEBUG -namespace AST { +namespace Shell::AST { template<typename T, typename... Args> static inline NonnullRefPtr<T> create(Args... args) diff --git a/Shell/AST.h b/Shell/AST.h index 112eb39041..f9465f5980 100644 --- a/Shell/AST.h +++ b/Shell/AST.h @@ -38,7 +38,7 @@ #include <AK/Vector.h> #include <LibLine/Editor.h> -namespace AST { +namespace Shell::AST { struct HighlightMetadata { bool is_first_in_list { true }; diff --git a/Shell/Builtin.cpp b/Shell/Builtin.cpp index cae341ed4d..ee71a4e6db 100644 --- a/Shell/Builtin.cpp +++ b/Shell/Builtin.cpp @@ -35,6 +35,8 @@ extern char** environ; +namespace Shell { + int Shell::builtin_alias(int argc, const char** argv) { Vector<const char*> arguments; @@ -806,3 +808,5 @@ bool Shell::has_builtin(const StringView& name) const #undef __ENUMERATE_SHELL_BUILTIN return false; } + +} diff --git a/Shell/Execution.h b/Shell/Execution.h index 7e407df281..2d3bf0d12a 100644 --- a/Shell/Execution.h +++ b/Shell/Execution.h @@ -33,6 +33,8 @@ #include <AK/Vector.h> #include <LibCore/ElapsedTimer.h> +namespace Shell { + class FileDescriptionCollector { public: FileDescriptionCollector() { } @@ -59,3 +61,5 @@ private: Vector<SavedFileDescriptor> m_saves; FileDescriptionCollector m_collector; }; + +} diff --git a/Shell/Formatter.cpp b/Shell/Formatter.cpp index e1cb05c5d0..337468b22b 100644 --- a/Shell/Formatter.cpp +++ b/Shell/Formatter.cpp @@ -29,6 +29,8 @@ #include "Parser.h" #include <AK/TemporaryChange.h> +namespace Shell { + String Formatter::format() { auto node = Parser(m_source).parse(); @@ -595,3 +597,5 @@ void Formatter::visit(const AST::WriteRedirection* node) current_builder().append(" >"); NodeVisitor::visit(node); } + +} diff --git a/Shell/Formatter.h b/Shell/Formatter.h index 900246ae7f..7c0154f515 100644 --- a/Shell/Formatter.h +++ b/Shell/Formatter.h @@ -34,6 +34,8 @@ #include <AK/Vector.h> #include <ctype.h> +namespace Shell { + class Formatter final : public AST::NodeVisitor { public: Formatter(const StringView& source, ssize_t cursor = -1) @@ -119,3 +121,5 @@ private: StringView m_trivia; }; + +} diff --git a/Shell/Forward.h b/Shell/Forward.h index 597a1f76d1..e769910ba0 100644 --- a/Shell/Forward.h +++ b/Shell/Forward.h @@ -26,8 +26,7 @@ #pragma once -class Shell; -namespace AST { +namespace Shell::AST { struct Command; class Node; @@ -75,3 +74,9 @@ class WriteAppendRedirection; class WriteRedirection; } + +namespace Shell { + +class Shell; + +} diff --git a/Shell/Job.cpp b/Shell/Job.cpp index 8584695099..91b5c07b8c 100644 --- a/Shell/Job.cpp +++ b/Shell/Job.cpp @@ -31,6 +31,8 @@ #include <stdio.h> #include <sys/wait.h> +namespace Shell { + bool Job::print_status(PrintStatusMode mode) { int wstatus; @@ -110,3 +112,5 @@ void Job::unblock() const if (!m_exited && on_exit) on_exit(*this); } + +} diff --git a/Shell/Job.h b/Shell/Job.h index b3ad9f6765..9a37ba976d 100644 --- a/Shell/Job.h +++ b/Shell/Job.h @@ -41,6 +41,8 @@ # undef JOB_TIME_INFO #endif +namespace Shell { + struct LocalFrame; class Job : public RefCounted<Job> { @@ -127,3 +129,5 @@ private: bool m_should_be_disowned { false }; OwnPtr<AST::Command> m_command; }; + +} diff --git a/Shell/NodeVisitor.cpp b/Shell/NodeVisitor.cpp index 2b58711cfb..22723d79a2 100644 --- a/Shell/NodeVisitor.cpp +++ b/Shell/NodeVisitor.cpp @@ -27,7 +27,7 @@ #include "NodeVisitor.h" #include "AST.h" -namespace AST { +namespace Shell::AST { void NodeVisitor::visit(const AST::PathRedirectionNode* node) { diff --git a/Shell/NodeVisitor.h b/Shell/NodeVisitor.h index 3b49332977..63e6dcb0c3 100644 --- a/Shell/NodeVisitor.h +++ b/Shell/NodeVisitor.h @@ -28,7 +28,7 @@ #include "Forward.h" -namespace AST { +namespace Shell::AST { class NodeVisitor { public: diff --git a/Shell/Parser.cpp b/Shell/Parser.cpp index 367c660a04..b0584b3275 100644 --- a/Shell/Parser.cpp +++ b/Shell/Parser.cpp @@ -29,6 +29,8 @@ #include <stdio.h> #include <unistd.h> +namespace Shell { + Parser::SavedOffset Parser::save_offset() const { return { m_offset, m_line }; @@ -1350,3 +1352,5 @@ StringView Parser::consume_while(Function<bool(char)> condition) return m_input.substring_view(start_offset, m_offset - start_offset); } + +} diff --git a/Shell/Parser.h b/Shell/Parser.h index caee819ef5..a189818014 100644 --- a/Shell/Parser.h +++ b/Shell/Parser.h @@ -33,6 +33,8 @@ #include <AK/StringBuilder.h> #include <AK/Vector.h> +namespace Shell { + class Parser { public: Parser(StringView input) @@ -232,3 +234,5 @@ glob :: [*?] bareword? | bareword [*?] )"; #endif + +} diff --git a/Shell/Shell.cpp b/Shell/Shell.cpp index 8f9cf8f330..e965645a93 100644 --- a/Shell/Shell.cpp +++ b/Shell/Shell.cpp @@ -57,6 +57,8 @@ extern char** environ; //#define SH_DEBUG +namespace Shell { + // FIXME: This should eventually be removed once we've established that // waitpid() is not passed the same job twice. #ifdef __serenity__ @@ -523,6 +525,10 @@ bool Shell::is_runnable(const StringView& name) int Shell::run_command(const StringView& cmd) { + // The default-constructed mode of the shell + // should not be used for execution! + ASSERT(!m_default_constructed); + if (cmd.is_empty()) return 0; @@ -1158,7 +1164,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_path(const String& base, cons // since we are not suggesting anything starting with // `/foo/', but rather just `bar...' auto token_length = escape_token(token).length(); - m_editor->suggest(token_length, original_token.length() - token_length); + if (m_editor) + m_editor->suggest(token_length, original_token.length() - token_length); // only suggest dot-files if path starts with a dot Core::DirIterator files(path, @@ -1195,7 +1202,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_program_name(const String& na return complete_path("", name, offset); String completion = *match; - m_editor->suggest(escape_token(name).length(), 0); + if (m_editor) + m_editor->suggest(escape_token(name).length(), 0); // Now that we have a program name starting with our token, we look at // other program names starting with our token and cut off any mismatching @@ -1220,7 +1228,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_variable(const String& name, Vector<Line::CompletionSuggestion> suggestions; auto pattern = offset ? name.substring_view(0, offset) : ""; - m_editor->suggest(offset); + if (m_editor) + m_editor->suggest(offset); // Look at local variables. for (auto& frame : m_local_frames) { @@ -1252,7 +1261,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_user(const String& name, size Vector<Line::CompletionSuggestion> suggestions; auto pattern = offset ? name.substring_view(0, offset) : ""; - m_editor->suggest(offset); + if (m_editor) + m_editor->suggest(offset); Core::DirIterator di("/home", Core::DirIterator::SkipParentAndBaseDir); @@ -1274,7 +1284,8 @@ Vector<Line::CompletionSuggestion> Shell::complete_option(const String& program_ while (start < option.length() && option[start] == '-' && start < 2) ++start; auto option_pattern = offset > start ? option.substring_view(start, offset - start) : ""; - m_editor->suggest(offset); + if (m_editor) + m_editor->suggest(offset); Vector<Line::CompletionSuggestion> suggestions; @@ -1459,6 +1470,42 @@ void Shell::notify_child_event() } while (!found_child); } +Shell::Shell() + : m_default_constructed(true) +{ + push_frame().leak_frame(); + + int rc = gethostname(hostname, Shell::HostNameSize); + if (rc < 0) + perror("gethostname"); + + { + auto* pw = getpwuid(getuid()); + if (pw) { + username = pw->pw_name; + home = pw->pw_dir; + setenv("HOME", pw->pw_dir, 1); + } + endpwent(); + } + + // For simplicity, start at the user's home directory. + this->cwd = home; + setenv("PWD", home.characters(), 1); + + // Add the default PATH vars. + { + StringBuilder path; + path.append(getenv("PATH")); + if (path.length()) + path.append(":"); + path.append("/bin:/usr/bin:/usr/local/bin"); + setenv("PATH", path.to_string().characters(), true); + } + + cache_path(); +} + Shell::Shell(Line::Editor& editor) : m_editor(editor) { @@ -1507,6 +1554,9 @@ Shell::Shell(Line::Editor& editor) Shell::~Shell() { + if (m_default_constructed) + return; + stop_all_jobs(); save_history(); } @@ -1641,3 +1691,5 @@ SavedFileDescriptors::~SavedFileDescriptors() } } } + +} diff --git a/Shell/Shell.h b/Shell/Shell.h index 8b11732db6..4f61942fe8 100644 --- a/Shell/Shell.h +++ b/Shell/Shell.h @@ -64,6 +64,8 @@ __ENUMERATE_SHELL_OPTION(inline_exec_keep_empty_segments, false, "Keep empty segments in inline execute $(...)") \ __ENUMERATE_SHELL_OPTION(verbose, false, "Announce every command that is about to be executed") +namespace Shell { + class Shell; class Shell : public Core::Object { @@ -199,6 +201,7 @@ public: private: Shell(Line::Editor&); + Shell(); virtual ~Shell() override; // FIXME: Port to Core::Property @@ -252,9 +255,13 @@ private: bool m_should_format_live { false }; RefPtr<Line::Editor> m_editor; + + bool m_default_constructed { false }; }; static constexpr bool is_word_character(char c) { return c == '_' || (c <= 'Z' && c >= 'A') || (c <= 'z' && c >= 'a'); } + +} diff --git a/Shell/main.cpp b/Shell/main.cpp index eb36de5c54..cf1dfddf1b 100644 --- a/Shell/main.cpp +++ b/Shell/main.cpp @@ -36,7 +36,7 @@ #include <string.h> RefPtr<Line::Editor> editor; -Shell* s_shell; +Shell::Shell* s_shell; int main(int argc, char** argv) { @@ -62,7 +62,7 @@ int main(int argc, char** argv) editor = Line::Editor::construct(); - auto shell = Shell::construct(*editor); + auto shell = Shell::Shell::construct(*editor); s_shell = shell.ptr(); s_shell->setup_signals(); @@ -163,15 +163,15 @@ int main(int argc, char** argv) shell->run_file(file_path, false); } }; - run_rc_file(Shell::global_init_file_path); - run_rc_file(Shell::local_init_file_path); + run_rc_file(Shell::Shell::global_init_file_path); + run_rc_file(Shell::Shell::local_init_file_path); } { Vector<String> args; for (auto* arg : script_args) args.empend(arg); - shell->set_local_variable("ARGV", adopt(*new AST::ListValue(move(args)))); + shell->set_local_variable("ARGV", adopt(*new Shell::AST::ListValue(move(args)))); } if (command_to_run) { @@ -188,7 +188,7 @@ int main(int argc, char** argv) shell->add_child(*editor); - Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::ShellEventType::ReadLine)); + Core::EventLoop::current().post_event(*shell, make<Core::CustomEvent>(Shell::Shell::ShellEventType::ReadLine)); return loop.exec(); } |