Browse Source

add sid and pgid

greatbridf 2 năm trước cách đây
mục cha
commit
300de58007

+ 3 - 0
gblibc/include/unistd.h

@@ -26,6 +26,9 @@ unsigned int sleep(unsigned int seconds);
 int chdir(const char* path);
 char* getcwd(char* buf, size_t bufsize);
 
+pid_t setsid(void);
+pid_t getsid(pid_t pid);
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 0
gblibc/private-include/syscall.h

@@ -14,6 +14,8 @@
 #define SYS_getdents (0x08)
 #define SYS_open (0x09)
 #define SYS_getcwd (0x0a)
+#define SYS_setsid (0x0b)
+#define SYS_getsid (0x0c)
 
 #ifdef __cplusplus
 extern "C" {

+ 10 - 0
gblibc/src/unistd.c

@@ -42,3 +42,13 @@ char* getcwd(char* buf, size_t bufsize)
 {
     return (char*)syscall2(SYS_getcwd, (uint32_t)buf, bufsize);
 }
+
+pid_t setsid(void)
+{
+    return syscall0(SYS_setsid);
+}
+
+pid_t getsid(pid_t pid)
+{
+    return syscall1(SYS_getsid, pid);
+}

+ 27 - 2
include/kernel/process.hpp

@@ -6,6 +6,7 @@
 #include <kernel/interrupt.h>
 #include <kernel/mm.hpp>
 #include <kernel/task.h>
+#include <kernel/tty.hpp>
 #include <kernel/vfs.hpp>
 #include <stdint.h>
 #include <sys/types.h>
@@ -263,11 +264,14 @@ public:
     thdlist thds;
     kernel::evtqueue wait_lst;
     process_attr attr;
-    pid_t pid;
-    pid_t ppid;
     filearr files;
     types::string<> pwd;
 
+    pid_t pid;
+    pid_t ppid;
+    pid_t pgid;
+    pid_t sid;
+
 public:
     process(process&& val);
     process(const process&);
@@ -296,12 +300,14 @@ class proclist final {
 public:
     using list_type = types::map<pid_t, process>;
     using child_index_type = types::hash_map<pid_t, types::list<pid_t>, types::linux_hasher<pid_t>>;
+    using tty_index_type = types::map<pid_t, tty*>;
     using iterator_type = list_type::iterator_type;
     using const_iterator_type = list_type::const_iterator_type;
 
 private:
     list_type m_procs;
     child_index_type m_child_idx;
+    tty_index_type m_tty_idx;
 
 public:
     template <typename... Args>
@@ -323,6 +329,25 @@ public:
         return iter;
     }
 
+    constexpr void set_ctrl_tty(pid_t pid, tty* _tty)
+    {
+        auto iter = m_tty_idx.find(pid);
+        _tty->set_pgrp(pid);
+        if (iter) {
+            iter->value = _tty;
+        } else {
+            m_tty_idx.insert(types::make_pair(pid, _tty));
+        }
+    }
+
+    constexpr tty* get_ctrl_tty(pid_t pid)
+    {
+        auto iter = m_tty_idx.find(pid);
+        if (!iter)
+            return nullptr;
+        return iter->value;
+    }
+
     constexpr void remove(pid_t pid)
     {
         make_children_orphans(pid);

+ 13 - 0
include/kernel/tty.hpp

@@ -1,6 +1,7 @@
 #pragma once
 #include <kernel/event/evtqueue.hpp>
 #include <stdint.h>
+#include <sys/types.h>
 #include <types/allocator.hpp>
 #include <types/buffer.hpp>
 #include <types/cplusplus.hpp>
@@ -17,12 +18,24 @@ public:
     void print(const char* str);
     size_t read(char* buf, size_t buf_size, size_t n);
 
+    constexpr void set_pgrp(pid_t pgid)
+    {
+        fg_pgroup = pgid;
+    }
+
+    constexpr pid_t get_pgrp(void) const
+    {
+        return fg_pgroup;
+    }
+
     char name[NAME_SIZE];
     bool echo = true;
 
 protected:
     types::buffer<types::kernel_ident_allocator> buf;
     kernel::evtqueue blocklist;
+
+    pid_t fg_pgroup;
 };
 
 class vga_tty : public virtual tty {

+ 10 - 8
src/kernel/process.cpp

@@ -93,23 +93,23 @@ process::process(process&& val)
     , thds { types::move(val.thds), this }
     , wait_lst(types::move(val.wait_lst))
     , attr { val.attr }
-    , pid(val.pid)
-    , ppid(val.ppid)
     , files(types::move(val.files))
     , pwd(types::move(val.pwd))
+    , pid(val.pid)
+    , ppid(val.ppid)
+    , pgid(val.pgid)
+    , sid(val.sid)
 {
     if (current_process == &val)
         current_process = this;
-
-    val.pid = 0;
-    val.ppid = 0;
-    val.attr.system = 0;
-    val.attr.zombie = 0;
 }
 
 process::process(const process& parent)
     : process { parent.pid, parent.is_system(), types::string<>(parent.pwd) }
 {
+    this->pgid = parent.pgid;
+    this->sid = parent.sid;
+
     for (auto& area : parent.mms) {
         if (area.is_kernel_space() || area.attr.in.system)
             continue;
@@ -123,9 +123,11 @@ process::process(const process& parent)
 process::process(pid_t _ppid, bool _system, types::string<>&& path)
     : mms(*kernel_mms)
     , attr { .system = _system }
+    , pwd { path }
     , pid { process::alloc_pid() }
     , ppid { _ppid }
-    , pwd { path }
+    , pgid { 0 }
+    , sid { 0 }
 {
 }
 

+ 31 - 0
src/kernel/syscall.cpp

@@ -292,6 +292,35 @@ void _syscall_getcwd(interrupt_stack* data)
     SYSCALL_SET_RETURN_VAL_EAX(buf);
 }
 
+void _syscall_setsid(interrupt_stack* data)
+{
+    if (current_process->pid == current_process->pgid) {
+        SYSCALL_SET_RETURN_VAL_EAX(-1);
+        return;
+    }
+
+    current_process->sid = current_process->pid;
+    current_process->pgid = current_process->pid;
+
+    // TODO: get tty* from fd or block device id
+    procs->set_ctrl_tty(current_process->pid, console);
+
+    SYSCALL_SET_RETURN_VAL_EAX(current_process->pid);
+}
+
+void _syscall_getsid(interrupt_stack* data)
+{
+    pid_t pid = data->s_regs.edi;
+
+    auto* proc = procs->find(pid);
+    if (!proc || proc->sid != current_process->sid) {
+        SYSCALL_SET_RETURN_VAL_EAX(-1);
+        return;
+    }
+
+    SYSCALL_SET_RETURN_VAL_EAX(proc->sid);
+}
+
 SECTION(".text.kinit")
 void init_syscall(void)
 {
@@ -306,4 +335,6 @@ void init_syscall(void)
     syscall_handlers[8] = _syscall_getdents;
     syscall_handlers[9] = _syscall_open;
     syscall_handlers[10] = _syscall_getcwd;
+    syscall_handlers[11] = _syscall_setsid;
+    syscall_handlers[12] = _syscall_getsid;
 }

+ 10 - 0
user-space-program/init.c

@@ -9,6 +9,7 @@ int main(int argc, char** argv)
 {
     print("***** GBOS INIT SYSTEM *****\n");
 
+_run_sh:;
     pid_t sh_pid = fork();
     if (sh_pid < 0) {
         print("[init] unable to fork(), exiting...\n");
@@ -17,6 +18,12 @@ int main(int argc, char** argv)
 
     // child
     if (sh_pid == 0) {
+        pid_t sid = setsid();
+        if (sid < 0) {
+            print("[init] unable to setsid, exiting...\n");
+            return -1;
+        }
+
         char* shell_argv[128] = {};
         char* envp[1] = { NULL };
 
@@ -40,6 +47,9 @@ int main(int argc, char** argv)
         pid = wait(&ret);
         snprintf(buf, sizeof(buf), "[init] pid%d has exited with code %d\n", pid, ret);
         print(buf);
+        // sh
+        if (pid == sh_pid)
+            goto _run_sh;
     }
 
     return 0;