summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Libraries/LibGUI/ShellSyntaxHighlighter.cpp2
-rw-r--r--Shell/AST.cpp2
-rw-r--r--Shell/AST.h2
-rw-r--r--Shell/Builtin.cpp4
-rw-r--r--Shell/Execution.h4
-rw-r--r--Shell/Formatter.cpp4
-rw-r--r--Shell/Formatter.h4
-rw-r--r--Shell/Forward.h9
-rw-r--r--Shell/Job.cpp4
-rw-r--r--Shell/Job.h4
-rw-r--r--Shell/NodeVisitor.cpp2
-rw-r--r--Shell/NodeVisitor.h2
-rw-r--r--Shell/Parser.cpp4
-rw-r--r--Shell/Parser.h4
-rw-r--r--Shell/Shell.cpp62
-rw-r--r--Shell/Shell.h7
-rw-r--r--Shell/main.cpp12
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();
}