ソースを参照

feat: tc{s,g}etpgrp

greatbridf 2 年 前
コミット
9d560da181

+ 15 - 0
gblibc/include/bits/ioctl.h

@@ -0,0 +1,15 @@
+#ifndef __GBLIBC_BITS_IOCTL_H_
+#define __GBLIBC_BITS_IOCTL_H_
+
+#define TIOCSPGRP (0)
+#define TIOCGPGRP (1)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 16 - 0
gblibc/include/sys/ioctl.h

@@ -0,0 +1,16 @@
+#ifndef __GBLIBC_SYS_IOCTL_H_
+#define __GBLIBC_SYS_IOCTL_H_
+
+#include <bits/ioctl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ioctl(int fd, unsigned long request, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 3 - 0
gblibc/include/unistd.h

@@ -38,6 +38,9 @@ int setpgid(pid_t pid, pid_t pgid);
 pid_t setsid(void);
 pid_t getsid(pid_t pid);
 
+pid_t tcgetpgrp(int fd);
+int tcsetpgrp(int fd, pid_t pgrp);
+
 #ifdef __cplusplus
 }
 #endif

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

@@ -7,6 +7,7 @@
 #define SYS_write (1)
 #define SYS_open (2)
 #define SYS_close (3)
+#define SYS_ioctl (16)
 #define SYS_pipe (22)
 #define SYS_dup (32)
 #define SYS_dup2 (33)

+ 35 - 0
gblibc/src/unistd.c

@@ -1,3 +1,5 @@
+#include <stdarg.h>
+#include <sys/ioctl.h>
 #include <unistd.h>
 #include <syscall.h>
 
@@ -77,3 +79,36 @@ pid_t getsid(pid_t pid)
 {
     return syscall1(SYS_getsid, pid);
 }
+
+pid_t tcgetpgrp(int fd)
+{
+    pid_t pgrp;
+    return ioctl(fd, TIOCGPGRP, &pgrp);
+}
+
+int tcsetpgrp(int fd, pid_t pgrp)
+{
+    return ioctl(fd, TIOCSPGRP, &pgrp);
+}
+
+int ioctl(int fd, unsigned long request, ...)
+{
+    int ret = -1;
+
+    va_list args;
+    va_start(args, request);
+
+    switch (request) {
+    case TIOCGPGRP:
+        ret = syscall3(SYS_ioctl, fd, request, va_arg(args, uint32_t));
+        break;
+    case TIOCSPGRP:
+        ret = syscall3(SYS_ioctl, fd, request, va_arg(args, uint32_t));
+        break;
+    default:
+        break;
+    }
+
+    va_end(args);
+    return ret;
+}

+ 39 - 0
src/kernel/syscall.cpp

@@ -1,6 +1,7 @@
 #include <asm/port_io.h>
 #include <asm/sys.h>
 #include <assert.h>
+#include <bits/ioctl.h>
 #include <kernel/errno.h>
 #include <kernel/interrupt.h>
 #include <kernel/log.hpp>
@@ -370,6 +371,43 @@ int _syscall_setpgid(interrupt_stack* data)
     return 0;
 }
 
+int _syscall_ioctl(interrupt_stack* data)
+{
+    int fd = data->s_regs.edi;
+    unsigned long request = data->s_regs.esi;
+
+    // TODO: check fd type and get tty* from fd
+    //
+    //       we use a trick for now, check whether
+    //       the file that fd points to is a pipe or
+    //       not. and we suppose that stdin will be
+    //       either a tty or a pipe.
+    auto* file = current_process->files[fd];
+    if (!file || file->type != fs::file::types::ind)
+        return -ENOTTY;
+
+    switch (request) {
+    case TIOCGPGRP: {
+        auto* pgid = (pid_t*)data->s_regs.edx;
+        tty* ctrl_tty = procs->get_ctrl_tty(current_process->pid);
+        // TODO: copy_to_user
+        *pgid = ctrl_tty->get_pgrp();
+        break;
+    }
+    case TIOCSPGRP: {
+        // TODO: copy_from_user
+        pid_t pgid = *(const pid_t*)data->s_regs.edx;
+        tty* ctrl_tty = procs->get_ctrl_tty(current_process->pid);
+        ctrl_tty->set_pgrp(pgid);
+        break;
+    }
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
 extern "C" void syscall_entry(interrupt_stack* data)
 {
     int syscall_no = data->s_regs.eax;
@@ -392,6 +430,7 @@ void init_syscall(void)
     syscall_handlers[1] = _syscall_write;
     syscall_handlers[2] = _syscall_open;
     syscall_handlers[3] = _syscall_close;
+    syscall_handlers[16] = _syscall_ioctl;
     syscall_handlers[22] = _syscall_pipe;
     syscall_handlers[32] = _syscall_dup;
     syscall_handlers[33] = _syscall_dup2;

+ 2 - 0
user-space-program/sh.c

@@ -229,9 +229,11 @@ main(void)
       setpgid(0, 0);
       runcmd(parsecmd(buf));
     }
+    tcsetpgrp(STDOUT_FILENO, pid);
     setpgid(pid, 0);
     int code;
     wait(&code);
+    tcsetpgrp(STDOUT_FILENO, 3);
   }
   _exit(0);
 }