瀏覽代碼

Shell: Run builtins that cannot be run in the main process in a new child

e.g. `$(jobs | wc -l)` would blow up horribly otherwise.
(it still does)
AnotherTest 4 年之前
父節點
當前提交
0bc758d34a
共有 1 個文件被更改,包括 9 次插入9 次删除
  1. 9 9
      Shell/Shell.cpp

+ 9 - 9
Shell/Shell.cpp

@@ -562,13 +562,8 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
 {
 {
     FileDescriptionCollector fds;
     FileDescriptionCollector fds;
 
 
-    if (options.verbose) {
-        fprintf(stderr, "+ ");
-        for (auto& arg : command.argv)
-            fprintf(stderr, "%s ", escape_token(arg).characters());
-        fprintf(stderr, "\n");
-        fflush(stderr);
-    }
+    if (options.verbose)
+        warnln("+ {}", m_pid, command);
 
 
     // If the command is empty, store the redirections and apply them to all later commands.
     // If the command is empty, store the redirections and apply them to all later commands.
     if (command.argv.is_empty() && !command.should_immediately_execute_next) {
     if (command.argv.is_empty() && !command.should_immediately_execute_next) {
@@ -642,7 +637,7 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
             return nullptr;
             return nullptr;
     }
     }
 
 
-    if (run_builtin(command, rewirings, last_return_code)) {
+    if (command.should_wait && run_builtin(command, rewirings, last_return_code)) {
         for (auto& next_in_chain : command.next_chain)
         for (auto& next_in_chain : command.next_chain)
             run_tail(command, next_in_chain, last_return_code);
             run_tail(command, next_in_chain, last_return_code);
         return nullptr;
         return nullptr;
@@ -694,7 +689,6 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
         m_is_subshell = true;
         m_is_subshell = true;
         m_pid = getpid();
         m_pid = getpid();
         Core::EventLoop::notify_forked(Core::EventLoop::ForkEvent::Child);
         Core::EventLoop::notify_forked(Core::EventLoop::ForkEvent::Child);
-        jobs.clear();
 
 
         if (apply_rewirings() == IterationDecision::Break)
         if (apply_rewirings() == IterationDecision::Break)
             _exit(126);
             _exit(126);
@@ -732,9 +726,15 @@ RefPtr<Job> Shell::run_command(const AST::Command& command)
             _exit(last_return_code);
             _exit(last_return_code);
         }
         }
 
 
+        if (run_builtin(command, {}, last_return_code))
+            _exit(last_return_code);
+
         if (invoke_function(command, last_return_code))
         if (invoke_function(command, last_return_code))
             _exit(last_return_code);
             _exit(last_return_code);
 
 
+        // We no longer need the jobs here.
+        jobs.clear();
+
         int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
         int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
         if (rc < 0) {
         if (rc < 0) {
             if (errno == ENOENT) {
             if (errno == ENOENT) {