Ver Fonte

Kernel: Make sure processes always start out with fds 0, 1 and 2 open.

If we don't have a TTY for the process, fall back to /dev/null.
Andreas Kling há 6 anos atrás
pai
commit
111589a558
5 ficheiros alterados com 46 adições e 15 exclusões
  1. 27 8
      Applications/Terminal/main.cpp
  2. 9 0
      Kernel/NullDevice.cpp
  3. 2 0
      Kernel/NullDevice.h
  4. 6 6
      Kernel/Process.cpp
  5. 2 1
      Kernel/init.cpp

+ 27 - 8
Applications/Terminal/main.cpp

@@ -24,21 +24,40 @@ static void make_shell(int ptm_fd)
             perror("ptsname");
             exit(1);
         }
-        int rc = 0;
         close(ptm_fd);
         int pts_fd = open(tty_name, O_RDWR);
-        rc = ioctl(0, TIOCNOTTY);
-        if (rc < 0) {
-            perror("ioctl(TIOCNOTTY)");
+        if (pts_fd < 0) {
+            perror("open");
             exit(1);
         }
+
+        // NOTE: It's okay if this fails.
+        (void) ioctl(0, TIOCNOTTY);
+
         close(0);
         close(1);
         close(2);
-        dup2(pts_fd, 0);
-        dup2(pts_fd, 1);
-        dup2(pts_fd, 2);
-        close(pts_fd);
+
+        int rc = dup2(pts_fd, 0);
+        if (rc < 0) {
+            perror("dup2");
+            exit(1);
+        }
+        rc = dup2(pts_fd, 1);
+        if (rc < 0) {
+            perror("dup2");
+            exit(1);
+        }
+        rc = dup2(pts_fd, 2);
+        if (rc < 0) {
+            perror("dup2");
+            exit(1);
+        }
+        rc = close(pts_fd);
+        if (rc < 0) {
+            perror("close");
+            exit(1);
+        }
         rc = ioctl(0, TIOCSCTTY);
         if (rc < 0) {
             perror("ioctl(TIOCSCTTY)");

+ 9 - 0
Kernel/NullDevice.cpp

@@ -3,9 +3,18 @@
 #include <AK/StdLibExtras.h>
 #include <AK/kstdio.h>
 
+static NullDevice* s_the;
+
+NullDevice& NullDevice::the()
+{
+    ASSERT(s_the);
+    return *s_the;
+}
+
 NullDevice::NullDevice()
     : CharacterDevice(1, 3)
 {
+    s_the = this;
 }
 
 NullDevice::~NullDevice()

+ 2 - 0
Kernel/NullDevice.h

@@ -8,6 +8,8 @@ public:
     NullDevice();
     virtual ~NullDevice() override;
 
+    static NullDevice& the();
+
 private:
     // ^CharacterDevice
     virtual ssize_t read(Process&, byte* buffer, size_t bufferSize) override;

+ 6 - 6
Kernel/Process.cpp

@@ -6,6 +6,7 @@
 #include "system.h"
 #include <Kernel/FileDescriptor.h>
 #include <Kernel/VirtualFileSystem.h>
+#include <Kernel/NullDevice.h>
 #include "ELFLoader.h"
 #include "MemoryManager.h"
 #include "i8253.h"
@@ -623,12 +624,11 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring
         }
     } else {
         m_fds.resize(m_max_open_file_descriptors);
-        if (tty) {
-            int error;
-            m_fds[0].set(tty->open(error, O_RDONLY));
-            m_fds[1].set(tty->open(error, O_WRONLY));
-            m_fds[2].set(tty->open(error, O_WRONLY));
-        }
+        auto& device_to_use_as_tty = tty ? (CharacterDevice&)*tty : NullDevice::the();
+        int error;
+        m_fds[0].set(device_to_use_as_tty.open(error, O_RDONLY));
+        m_fds[1].set(device_to_use_as_tty.open(error, O_WRONLY));
+        m_fds[2].set(device_to_use_as_tty.open(error, O_WRONLY));
     }
 
     if (fork_parent)

+ 2 - 1
Kernel/init.cpp

@@ -43,6 +43,7 @@ VirtualConsole* tty3;
 Keyboard* keyboard;
 PS2MouseDevice* ps2mouse;
 GUIEventDevice* gui_event_device;
+NullDevice* dev_null;
 VFS* vfs;
 
 #ifdef STRESS_TEST_SPAWNING
@@ -72,7 +73,6 @@ static void init_stage2()
     auto dev_zero = make<ZeroDevice>();
     vfs->register_character_device(*dev_zero);
 
-    auto dev_null = make<NullDevice>();
     vfs->register_character_device(*dev_null);
 
     auto dev_full = make<FullDevice>();
@@ -162,6 +162,7 @@ void init()
     keyboard = new Keyboard;
     ps2mouse = new PS2MouseDevice;
     gui_event_device = new GUIEventDevice;
+    dev_null = new NullDevice;
 
     VirtualConsole::initialize();
     tty0 = new VirtualConsole(0, VirtualConsole::AdoptCurrentVGABuffer);