Browse Source

feat: setpgrp

greatbridf 2 years ago
parent
commit
427190bcbe

+ 2 - 0
gblibc/include/unistd.h

@@ -33,6 +33,8 @@ unsigned int sleep(unsigned int seconds);
 int chdir(const char* path);
 char* getcwd(char* buf, size_t bufsize);
 
+int setpgid(pid_t pid, pid_t pgid);
+
 pid_t setsid(void);
 pid_t getsid(pid_t pid);
 

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

@@ -18,6 +18,7 @@
 #define SYS_getdents (78)
 #define SYS_getcwd (79)
 #define SYS_chdir (80)
+#define SYS_setpgid (109)
 #define SYS_setsid (112)
 #define SYS_getsid (124)
 

+ 5 - 0
gblibc/src/unistd.c

@@ -63,6 +63,11 @@ char* getcwd(char* buf, size_t bufsize)
     return (char*)syscall2(SYS_getcwd, (uint32_t)buf, bufsize);
 }
 
+int setpgid(pid_t pid, pid_t pgid)
+{
+    return syscall2(SYS_setpgid, pid, pgid);
+}
+
 pid_t setsid(void)
 {
     return syscall0(SYS_setsid);

+ 1 - 0
include/kernel/errno.h

@@ -28,5 +28,6 @@ extern uint32_t* _get_errno(void);
 #define ESRCH (1 << 10)
 #define EINTR (1 << 11)
 #define EPIPE (1 << 12)
+#define ENOTTY (1 << 13)
 
 #endif

+ 4 - 1
include/kernel/process.hpp

@@ -453,7 +453,10 @@ public:
 
     constexpr process* find(pid_t pid)
     {
-        return &m_procs.find(pid)->value;
+        auto iter = m_procs.find(pid);
+        // TODO: change this
+        assert(!!iter);
+        return &iter->value;
     }
 
     constexpr bool has_child(pid_t pid)

+ 27 - 0
src/kernel/syscall.cpp

@@ -344,6 +344,32 @@ int _syscall_pipe(interrupt_stack* data)
     return current_process->files.pipe(pipefd);
 }
 
+int _syscall_setpgid(interrupt_stack* data)
+{
+    pid_t pid = data->s_regs.edi;
+    pid_t pgid = data->s_regs.esi;
+
+    if (pgid < 0)
+        return -EINVAL;
+
+    if (pid == 0)
+        pid = current_process->pid;
+
+    if (pgid == 0)
+        pgid = pid;
+
+    auto* proc = procs->find(pid);
+    // TODO: check whether the process exists
+    // if (!proc)
+    //     return -ESRCH;
+
+    // TODO: check whether pgid and the original
+    //       pgid is in the same session
+    proc->pgid = pgid;
+
+    return 0;
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = data->s_regs.eax;
@@ -377,6 +403,7 @@ void init_syscall(void)
     syscall_handlers[78] = _syscall_getdents;
     syscall_handlers[79] = _syscall_getcwd;
     syscall_handlers[80] = _syscall_chdir;
+    syscall_handlers[109] = _syscall_setpgid;
     syscall_handlers[112] = _syscall_setsid;
     syscall_handlers[124] = _syscall_getsid;
 }

+ 5 - 1
user-space-program/sh.c

@@ -224,8 +224,12 @@ main(void)
         printf("cannot cd %s\n", buf+3);
       continue;
     }
-    if(fork1() == 0)
+    pid_t pid = 0;
+    if((pid = fork1()) == 0) {
+      setpgid(0, 0);
       runcmd(parsecmd(buf));
+    }
+    setpgid(pid, 0);
     int code;
     wait(&code);
   }