diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 395e60cd5d..f77674f261 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -104,6 +104,8 @@ namespace Kernel BAN::ErrorOr sys_raise(int signal); static BAN::ErrorOr sys_kill(pid_t pid, int signal); + BAN::ErrorOr sys_tcsetpgrp(int fd, pid_t pgid); + BAN::ErrorOr sys_termid(char*) const; BAN::ErrorOr sys_clock_gettime(clockid_t, timespec*) const; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 6a7b22dea0..b1ab1cb3d5 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -848,10 +848,31 @@ namespace Kernel return 0; } - pid_t Process::foreground_pid() + BAN::ErrorOr Process::sys_tcsetpgrp(int fd, pid_t pgid) { - ASSERT(s_foreground_pid); - return s_foreground_pid; + LockGuard _(m_lock); + + // FIXME: validate the inode + auto inode = TRY(m_open_file_descriptors.inode_of(fd)); + if (!inode->is_tty()) + return BAN::Error::from_errno(ENOTTY); + + // FIXME: use process groups instead of process ids + // FIXME: return values + + LockGuard process_guard(s_process_lock); + for (auto* process : s_processes) + { + if (process->pid() == pgid) + { + if (!process->is_userspace()) + return BAN::Error::from_errno(EINVAL); + ((TTY*)inode.ptr())->set_foreground_process(pgid); + return 0; + } + } + + return BAN::Error::from_errno(EPERM); } BAN::ErrorOr Process::sys_setuid(uid_t uid) diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index 0b18cb34ea..91260a7000 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -160,6 +160,12 @@ namespace Kernel case SYS_SIGNAL_DONE: // Handled above ASSERT_NOT_REACHED(); + case SYS_TCSETPGRP: + ret = Process::current().sys_tcsetpgrp((int)arg1, (pid_t)arg2); + break; + case SYS_GET_PID: + ret = Process::current().pid(); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index c4ba6dc90a..d5ef87690a 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -45,6 +45,8 @@ __BEGIN_DECLS #define SYS_KILL 38 #define SYS_SIGNAL 39 #define SYS_SIGNAL_DONE 40 +#define SYS_TCSETPGRP 41 +#define SYS_GET_PID 42 __END_DECLS diff --git a/libc/unistd.cpp b/libc/unistd.cpp index a116a89289..a13cb02c96 100644 --- a/libc/unistd.cpp +++ b/libc/unistd.cpp @@ -286,6 +286,18 @@ long syscall(long syscall, ...) ret = Kernel::syscall(SYS_SIGNAL, signal, (uintptr_t)handler); break; } + case SYS_TCSETPGRP: + { + int fd = va_arg(args, int); + pid_t pgrp = va_arg(args, pid_t); + ret = Kernel::syscall(SYS_TCSETPGRP, fd, pgrp); + break; + } + case SYS_GET_PID: + { + ret = Kernel::syscall(SYS_GET_PID); + break; + } case SYS_SIGNAL_DONE: // Should not be called by an user // fall through @@ -438,6 +450,11 @@ int chdir(const char* path) return syscall(SYS_SET_PWD, path); } +pid_t getpid(void) +{ + return syscall(SYS_GET_PID); +} + uid_t getuid(void) { return syscall(SYS_GET_UID); @@ -487,3 +504,8 @@ int setregid(gid_t rgid, gid_t egid) { return syscall(SYS_SET_REGID, rgid, egid); } + +int tcsetpgrp(int fildes, pid_t pgid_id) +{ + return syscall(SYS_TCSETPGRP, fildes, pgid_id); +}