From 83b1d9a281fd00de1e7fdc9526a07dcd52184b45 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 31 Jul 2020 15:27:18 +0300 Subject: [PATCH] Add setsid(2) syscall --- arch/amd64/syscall.c | 1 + include/sys/sys_proc.h | 1 + include/sys/thread.h | 3 ++- include/user/syscall.h | 1 + sys/char/tty.c | 21 +++++++++++++++------ sys/init.c | 2 ++ sys/sys_file.c | 12 ++++++++++++ sys/thread.c | 26 +++++++++++++++++++++++++- 8 files changed, 59 insertions(+), 8 deletions(-) diff --git a/arch/amd64/syscall.c b/arch/amd64/syscall.c index 27f264e..dfe8287 100644 --- a/arch/amd64/syscall.c +++ b/arch/amd64/syscall.c @@ -82,6 +82,7 @@ void *syscall_table[256] = { [SYSCALL_NRX_WAITPID] = sys_waitpid, [SYSCALL_NR_GETPGID] = sys_getpgid, [SYSCALL_NR_SETPGID] = sys_setpgid, + [SYSCALL_NR_SETSID] = sys_setsid, [SYSCALL_NR_SIGALTSTACK] = sys_sigaltstack, [SYSCALL_NR_GETPPID] = sys_getppid, diff --git a/include/sys/sys_proc.h b/include/sys/sys_proc.h index 1bbb97c..a610c45 100644 --- a/include/sys/sys_proc.h +++ b/include/sys/sys_proc.h @@ -11,6 +11,7 @@ int sys_clone(int (*entry) (void *), void *stack, int flags, void *arg); int sys_execve(const char *path, const char **argp, const char **envp); pid_t sys_getpid(void); pid_t sys_getppid(void); +pid_t sys_setsid(void); uid_t sys_getuid(void); gid_t sys_getgid(void); diff --git a/include/sys/thread.h b/include/sys/thread.h index 8dab6e1..9d37c9b 100644 --- a/include/sys/thread.h +++ b/include/sys/thread.h @@ -94,8 +94,9 @@ struct process { // Signal uint64_t sigq; - // procfs + // Filesystem-stuff struct vnode *fs_entry; + struct vnode *ctty; // State char name[256]; diff --git a/include/user/syscall.h b/include/user/syscall.h index 5019d75..dc525ac 100644 --- a/include/user/syscall.h +++ b/include/user/syscall.h @@ -52,6 +52,7 @@ #define SYSCALL_NR_SETGID 106 #define SYSCALL_NR_SETPGID 109 #define SYSCALL_NR_GETPPID 110 +#define SYSCALL_NR_SETSID 112 #define SYSCALL_NR_GETPGID 121 #define SYSCALL_NR_SIGALTSTACK 131 #define SYSCALL_NRX_WAITPID 247 diff --git a/sys/char/tty.c b/sys/char/tty.c index b7c83d4..8cd6a5c 100644 --- a/sys/char/tty.c +++ b/sys/char/tty.c @@ -174,9 +174,13 @@ void tty_putc(struct chrdev *tty, int c) { } static struct vnode *tty_link_getter(struct thread *ctx, struct vnode *link) { - struct vnode *res; - dev_find(DEV_CLASS_CHAR, "tty0", &res); - return res; + struct process *proc; + + if (!(proc = ctx->proc)) { + return NULL; + } + + return proc->ctty; } void tty_init(void) { @@ -209,10 +213,15 @@ static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg) { { _assert(arg); struct winsize *winsz = arg; - _assert(data->master); + if (data->has_console) { + _assert(data->master); - winsz->ws_col = data->master->width_chars; - winsz->ws_row = data->master->height_chars; + winsz->ws_col = data->master->width_chars; + winsz->ws_row = data->master->height_chars; + } else { + winsz->ws_col = 80; + winsz->ws_row = 25; + } } return 0; case TCGETS: diff --git a/sys/init.c b/sys/init.c index 3f3091e..f37327e 100644 --- a/sys/init.c +++ b/sys/init.c @@ -57,6 +57,8 @@ static void user_init_func(void *arg) { _assert(fd_stdin->refcount == 1); _assert(fd_stdout->refcount == 2); + thread_self->proc->ctty = tty_dev; + const char *argp[] = { "/init", NULL }; diff --git a/sys/sys_file.c b/sys/sys_file.c index 5dcc784..47e7a47 100644 --- a/sys/sys_file.c +++ b/sys/sys_file.c @@ -195,6 +195,18 @@ int sys_openat(int dfd, const char *filename, int flags, int mode) { proc->fds[fd] = ofile_dup(ofile); _assert(proc->fds[fd]->refcount == 1); + // Set controlling terminal if none present and TTY is opened + // TODO: O_NOCTTY + if (!proc->ctty && !(ofile->flags & OF_SOCKET)) { + struct vnode *node = ofile->file.vnode; + _assert(node); + + if (node->type == VN_CHR && ((struct chrdev *) node->dev)->type == CHRDEV_TTY) { + kdebug("Setting controlling terminal for #%d (%s)\n", proc->pid, proc->name); + proc->ctty = node; + } + } + return fd; } diff --git a/sys/thread.c b/sys/thread.c index 088c6df..40cf844 100644 --- a/sys/thread.c +++ b/sys/thread.c @@ -325,6 +325,7 @@ int process_init_thread(struct process *proc, uintptr_t entry, void *arg, int us proc->next_child = NULL; proc->pgid = -1; proc->pid = process_alloc_pid(user); + proc->ctty = NULL; kdebug("New process #%d with main thread <%p>", proc->pid, main_thread); proc->sigq = 0; @@ -570,6 +571,7 @@ int sys_fork(struct sys_fork_frame *frame) { dst->pgid = src->pgid; dst->sigq = 0; dst->proc_state = PROC_ACTIVE; + dst->ctty = src->ctty; kdebug("New process #%d with main thread <%p>\n", dst->pid, dst_thread); // Initialize dst thread @@ -723,7 +725,7 @@ __attribute__((noreturn)) void sys_exit(int status) { sched_unqueue(thr, THREAD_STOPPED); panic("This code shouldn't run\n"); } - kdebug("Process %d exited with status %d\n", proc->pid, status); + kdebug("Process #%d (%s) exited with status %d\n", proc->pid, proc->name, status); // Clear pending I/O (if exiting from signal interrupting select()) if (!list_empty(&thr->wait_head)) { @@ -987,3 +989,25 @@ uid_t sys_getuid(void) { gid_t sys_getgid(void) { return thread_self->proc->ioctx.gid; } + +pid_t sys_setsid(void) { + struct process *proc = thread_self->proc; + _assert(proc); + if (proc->ctty) { + // Close current tty filedes + for (size_t i = 0; i < THREAD_MAX_FDS; ++i) { + if (proc->fds[i] && !(proc->fds[i]->flags & OF_SOCKET)) { + if (proc->fds[i]->file.vnode == proc->ctty) { + kdebug("setsid: detaching fd %d from #%d (%s)\n", i, proc->pid, proc->name); + ofile_close(&proc->ioctx, proc->fds[i]); + proc->fds[i] = NULL; + } + } + } + proc->ctty = NULL; + } else { + kdebug("setsid: #%d (%s) didn't have a tty\n", proc->pid, proc->name); + } + + return proc->pid; +}