From 5d3e884b66607e25a2d8faf3f7da998885a8656f Mon Sep 17 00:00:00 2001 From: Mark Date: Mon, 20 Jan 2020 15:39:57 +0200 Subject: [PATCH] Basic job control with process groups. setuid bit support --- defconfig | 2 ++ etc/make/conf.mk | 4 +++ include/sys/amd64/sys_file.h | 2 ++ include/sys/amd64/sys_proc.h | 2 ++ include/sys/chr.h | 2 ++ include/sys/fs/vfs.h | 3 ++ include/sys/ioctl.h | 5 +++ include/sys/sched.h | 1 + include/sys/syscall.h | 3 ++ include/sys/termios.h | 3 ++ include/sys/thread.h | 4 ++- include/sys/tty.h | 1 + include/sys/types.h | 2 ++ install-headers.sh | 4 ++- sys/amd64/hw/con.c | 7 ++-- sys/amd64/hw/ps2.c | 19 ++++++++++- sys/amd64/mm/heap.c | 13 ++++++++ sys/amd64/sys/sched.c | 26 ++++++++++++++- sys/amd64/sys/thread.c | 18 +++++++++++ sys/amd64/sys_file.c | 16 +++++++++ sys/amd64/sys_proc.c | 44 ++++++++++++++++++++++++- sys/amd64/syscall.c | 3 ++ sys/chr.c | 10 ++++++ sys/dev.c | 2 +- sys/tty.c | 63 ++++++++++++++++++++++++++++++------ sys/vfs/ext2/ext2vnop.c | 12 +++---- sys/vfs/tar.c | 17 +++++----- sys/vfs/vfs_ops.c | 16 ++++++++- 28 files changed, 271 insertions(+), 33 deletions(-) create mode 100644 include/sys/ioctl.h create mode 100644 include/sys/termios.h diff --git a/defconfig b/defconfig index 1602b78..46b5a1f 100644 --- a/defconfig +++ b/defconfig @@ -4,6 +4,8 @@ # amd64-specific export AMD64_TRACE_IRQ=1 +export ALL_SETUID_0=0 + # Emulation export QEMU_SMP=4 # export QEMU_MEM=512 diff --git a/etc/make/conf.mk b/etc/make/conf.mk index 1ea63ba..5cfd263 100644 --- a/etc/make/conf.mk +++ b/etc/make/conf.mk @@ -17,6 +17,10 @@ ifdef KERNEL_TEST_MODE CFLAGS+=-DKERNEL_TEST_MODE endif +ifeq ($(ALL_SETUID_0),1) +CFLAGS+=-DALL_SETUID_0 +endif + CFLAGS+=-D__KERNEL__ \ -DKERNEL_VERSION_STR=\"$(KERNEL_VERSION_GIT)\" diff --git a/include/sys/amd64/sys_file.h b/include/sys/amd64/sys_file.h index 6145296..dab0c30 100644 --- a/include/sys/amd64/sys_file.h +++ b/include/sys/amd64/sys_file.h @@ -35,5 +35,7 @@ int sys_chmod(const char *path, mode_t mode); int sys_chown(const char *path, uid_t uid, gid_t gid); off_t sys_lseek(int fd, off_t offset, int whence); +int sys_ioctl(int fd, unsigned int cmd, void *arg); + // XXX: Will be removed once ioctl(fd, TCGETS, ...) is possible int sys_isatty(int fd); diff --git a/include/sys/amd64/sys_proc.h b/include/sys/amd64/sys_proc.h index 8f5af1d..b1e74a8 100644 --- a/include/sys/amd64/sys_proc.h +++ b/include/sys/amd64/sys_proc.h @@ -9,6 +9,8 @@ int sys_setuid(uid_t uid); int sys_setgid(gid_t gid); uid_t sys_getuid(void); gid_t sys_getgid(void); +pid_t sys_getpgid(pid_t pid); +int sys_setpgid(pid_t pid, pid_t pgrp); // Non-compliant with linux style, but fuck'em, it just works void sys_signal(uintptr_t entry); diff --git a/include/sys/chr.h b/include/sys/chr.h index 32ad61b..a73e098 100644 --- a/include/sys/chr.h +++ b/include/sys/chr.h @@ -6,9 +6,11 @@ struct chrdev { void *dev_data; struct ring buffer; + int (*ioctl) (struct chrdev *chr, unsigned int cmd, void *arg); ssize_t (*write) (struct chrdev *chr, const void *buf, size_t pos, size_t lim); ssize_t (*read) (struct chrdev *chr, void *buf, size_t pos, size_t lim); }; +int chr_ioctl(struct chrdev *chr, unsigned int cmd, void *arg); ssize_t chr_write(struct chrdev *chr, const void *buf, size_t pos, size_t lim); ssize_t chr_read(struct chrdev *chr, void *buf, size_t pos, size_t lim); diff --git a/include/sys/fs/vfs.h b/include/sys/fs/vfs.h index ad50099..1038cdb 100644 --- a/include/sys/fs/vfs.h +++ b/include/sys/fs/vfs.h @@ -12,6 +12,8 @@ #define PATH_MAX 256 #define LINK_MAX 16 +#define VFS_MODE_MASK 0xFFF + struct fs_class; struct vfs_ioctx { @@ -46,6 +48,7 @@ int vfs_rmdir(struct vfs_ioctx *ctx, const char *path); int vfs_mkdir(struct vfs_ioctx *ctx, const char *path, mode_t mode); int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode); int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid); +int vfs_ioctl(struct vfs_ioctx *ctx, struct ofile *fd, unsigned int cmd, void *arg); int vfs_access(struct vfs_ioctx *ctx, const char *path, int accmode); int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st); diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h new file mode 100644 index 0000000..5e9de99 --- /dev/null +++ b/include/sys/ioctl.h @@ -0,0 +1,5 @@ +#pragma once + +#if !defined(__KERNEL__) +int ioctl(int fd, unsigned int cmd, void *arg); +#endif diff --git a/include/sys/sched.h b/include/sys/sched.h index b7e9c86..be00db3 100644 --- a/include/sys/sched.h +++ b/include/sys/sched.h @@ -4,6 +4,7 @@ // Terminate all tasks void sched_reboot(unsigned int cmd); +int sched_signal_group(int pgid, int signum); struct thread *sched_find(int pid); void sched_set_cpu_count(size_t ncpus); void sched_add(struct thread *t); diff --git a/include/sys/syscall.h b/include/sys/syscall.h index a9a19f8..ac713e7 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -6,6 +6,7 @@ #define SYSCALL_NR_CLOSE 3 #define SYSCALL_NR_STAT 4 #define SYSCALL_NR_LSEEK 8 +#define SYSCALL_NR_IOCTL 16 #define SYSCALL_NR_ACCESS 21 #define SYSCALL_NR_SELECT 23 #define SYSCALL_NR_GETCWD 79 @@ -32,6 +33,8 @@ #define SYSCALL_NR_GETGID 104 #define SYSCALL_NR_SETUID 105 #define SYSCALL_NR_SETGID 106 +#define SYSCALL_NR_SETPGID 109 +#define SYSCALL_NR_GETPGID 121 #define SYSCALL_NR_UNAME 63 #define SYSCALL_NR_MOUNT 165 diff --git a/include/sys/termios.h b/include/sys/termios.h new file mode 100644 index 0000000..d1bb969 --- /dev/null +++ b/include/sys/termios.h @@ -0,0 +1,3 @@ +#pragma once + +#define TIOCSPGRP 0x5410 diff --git a/include/sys/thread.h b/include/sys/thread.h index 4664d7e..af53b4d 100644 --- a/include/sys/thread.h +++ b/include/sys/thread.h @@ -42,7 +42,9 @@ struct thread { uintptr_t argp_page_phys; uint64_t flags; - uint32_t pid; + pid_t pid; + pid_t pgid; + pid_t sid; int exit_code; diff --git a/include/sys/tty.h b/include/sys/tty.h index 459b35d..d0ce6a4 100644 --- a/include/sys/tty.h +++ b/include/sys/tty.h @@ -1,5 +1,6 @@ #pragma once #include "sys/fs/node.h" +void tty_signal_write(int n, int signum); void tty_buffer_write(int n, char c); void tty_init(void); diff --git a/include/sys/types.h b/include/sys/types.h index 125dc97..e85c5e8 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -31,3 +31,5 @@ typedef int64_t off_t; typedef uint32_t mode_t; typedef uint32_t uid_t; typedef uint32_t gid_t; + +typedef int32_t pid_t; diff --git a/install-headers.sh b/install-headers.sh index 8a8f12f..5f4fa5c 100755 --- a/install-headers.sh +++ b/install-headers.sh @@ -15,7 +15,9 @@ KERNEL_HEADERS="include/sys/fcntl.h \ include/sys/errno.h \ include/sys/signum.h \ include/sys/utsname.h \ - include/sys/select.h" + include/sys/select.h \ + include/sys/termios.h \ + include/sys/ioctl.h" for src_file in $KERNEL_HEADERS; do dst_file=$INSTALL_HDR$(echo $src_file | sed -e 's/^include//g') diff --git a/sys/amd64/hw/con.c b/sys/amd64/hw/con.c index c74cd2a..6af9705 100644 --- a/sys/amd64/hw/con.c +++ b/sys/amd64/hw/con.c @@ -137,8 +137,8 @@ static void amd64_scroll_down(void) { } static void clear(void) { -#if defined(VESA_ENABLE) memsetw(con_buffer, attr, con_width * con_height); +#if defined(VESA_ENABLE) if (vesa_available) { for (size_t i = 0; i < vesa_height; ++i) { memsetl((uint32_t *) (vesa_addr + vesa_pitch * i), rgb_map[(attr >> 12) & 0xF], vesa_width); @@ -361,6 +361,9 @@ void amd64_con_putc(int c) { } void amd64_con_init(void) { + // XXX XXX XXX: Had to do this because of memory allocation problem: + // setc overwrites data in heap headers + static uint16_t second_buffer[80 * 25]; #if defined(VESA_ENABLE) if (vesa_available) { psf_init(vesa_addr, vesa_pitch, &char_width, &char_height); @@ -372,7 +375,7 @@ void amd64_con_init(void) { #else { #endif - con_buffer = kmalloc(80 * 25 * 2); //(uint16_t *) MM_VIRTUALIZE(CGA_BUFFER_ADDR); + con_buffer = second_buffer; con_width = 80; con_height = 25; } diff --git a/sys/amd64/hw/ps2.c b/sys/amd64/hw/ps2.c index b7e9471..2ba5846 100644 --- a/sys/amd64/hw/ps2.c +++ b/sys/amd64/hw/ps2.c @@ -1,6 +1,7 @@ #include "sys/amd64/hw/ps2.h" #include "sys/amd64/hw/irq.h" #include "sys/amd64/hw/io.h" +#include "sys/signum.h" #include "sys/debug.h" #include "sys/tty.h" @@ -9,7 +10,11 @@ #define PS2_KEY_LSHIFT_UP 0xAA #define PS2_KEY_RSHIFT_UP 0xB6 +#define PS2_KEY_LCTRL_DOWN 0x1D +#define PS2_KEY_LCTRL_UP 0x9D + #define PS2_MOD_SHIFT (1 << 0) +#define PS2_MOD_CTRL (1 << 1) static uint32_t ps2_mods = 0; @@ -60,8 +65,14 @@ uint32_t ps2_irq_keyboard(void *ctx) { if (key == PS2_KEY_LSHIFT_UP || key == PS2_KEY_RSHIFT_UP) { ps2_mods &= ~PS2_MOD_SHIFT; } + if (key == PS2_KEY_LCTRL_DOWN) { + ps2_mods |= PS2_MOD_CTRL; + } + if (key == PS2_KEY_LCTRL_UP) { + ps2_mods &= ~PS2_MOD_CTRL; + } - if (!(key & 0x80)) { + if (!(key & 0x80) && !(ps2_mods & PS2_MOD_CTRL)) { // Special keys switch (key) { case 0x01: @@ -108,6 +119,12 @@ uint32_t ps2_irq_keyboard(void *ctx) { if (key_char != 0) { tty_buffer_write(0, key_char); } + } else { + switch (key) { + case 0x2E: // ^C + tty_signal_write(0, SIGINT); + break; + } } return IRQ_HANDLED; diff --git a/sys/amd64/mm/heap.c b/sys/amd64/mm/heap.c index 3a4d2a9..b43e773 100644 --- a/sys/amd64/mm/heap.c +++ b/sys/amd64/mm/heap.c @@ -5,6 +5,8 @@ #include "sys/debug.h" #include "sys/mm.h" +#include "sys/amd64/sys_file.h" + #define HEAP_MAGIC 0x1BAD83A0 typedef struct heap_block { @@ -42,6 +44,9 @@ void heap_stat(heap_t *heap, struct heap_stat *st) { st->total_size = heap->limit; for (heap_block_t *block = begin; block; block = block->next) { + if ((block->magic & HEAP_MAGIC) != HEAP_MAGIC) { + panic("Broken heap"); + } if (block->magic & 1) { ++st->alloc_count; st->alloc_size += block->size; @@ -74,6 +79,7 @@ void amd64_heap_init(heap_t *heap, uintptr_t phys_base, size_t sz) { // Heap interface implementation void *heap_alloc(heap_t *heap, size_t count) { + asm volatile ("cli"); heap_block_t *begin = (heap_block_t *) MM_VIRTUALIZE(heap->phys_base); // Some alignment fuck ups led me to this @@ -115,10 +121,14 @@ void *heap_alloc(heap_t *heap, size_t count) { } void heap_free(heap_t *heap, void *ptr) { + asm volatile ("cli"); if (!ptr) { return; } + if (ptr == (void *) 0xffffff00042ddd70) { + } + // Check if the pointer belongs to the heap if (((uintptr_t) ptr) < MM_VIRTUALIZE(heap->phys_base) || ((uintptr_t) ptr) > (MM_VIRTUALIZE(heap->phys_base) + heap->limit)) { @@ -136,6 +146,9 @@ void heap_free(heap_t *heap, void *ptr) { heap_block_t *begin = (heap_block_t *) MM_VIRTUALIZE(heap->phys_base); for (heap_block_t *block = begin; block; block = block->next) { + if (block->next == (struct heap_block *) 0xffffff00042ddd70) { + kdebug("%p's NEXT IS %p\n", block, block->next); + } if ((block->magic & HEAP_MAGIC) != HEAP_MAGIC) { panic("Heap is broken: magic %08x, %p (%lu), size could be %S\n", block->magic, block, (uintptr_t) block - (uintptr_t) begin, block->size); } diff --git a/sys/amd64/sys/sched.c b/sys/amd64/sys/sched.c index 00a7f59..442998d 100644 --- a/sys/amd64/sys/sched.c +++ b/sys/amd64/sys/sched.c @@ -6,6 +6,7 @@ #include "sys/assert.h" #include "sys/reboot.h" #include "sys/panic.h" +#include "sys/errno.h" #include "sys/sched.h" #include "sys/debug.h" #include "sys/time.h" @@ -44,7 +45,7 @@ void idle_func(uintptr_t id) { } } -static uint32_t sched_alloc_pid(int is_kernel) { +static pid_t sched_alloc_pid(int is_kernel) { // The first pid allocation will be 1 (init process) static uint32_t last_user_pid = 1; static uint32_t last_kernel_pid = 1; @@ -62,6 +63,8 @@ struct thread *sched_find(int pid) { return NULL; } + // TODO: this only finds processes which are queued. Implement a global process list + // to fix this // Search through queues for (size_t cpu = 0; cpu < sched_ncpus; ++cpu) { for (struct thread *t = sched_queue_heads[cpu]; t; t = t->next) { @@ -74,6 +77,26 @@ struct thread *sched_find(int pid) { return NULL; } +int sched_signal_group(int pgid, int signum) { + int res = 0; + + for (size_t cpu = 0; cpu < sched_ncpus; ++cpu) { + for (struct thread *t = sched_queue_heads[cpu]; t; t = t->next) { + if ((int) t->pgid == pgid) { + ++res; + + thread_signal(t, signum); + } + } + } + + if (!res) { + return -ESRCH; + } else { + return res; + } +} + void sched_add_to(int cpu, struct thread *t) { t->next = NULL; @@ -89,6 +112,7 @@ void sched_add_to(int cpu, struct thread *t) { t->pid = sched_alloc_pid(t->flags & THREAD_KERNEL); if (!(t->flags & THREAD_KERNEL)) { if (t->pid == 1) { + t->pgid = 1; t_user_init = t; } } diff --git a/sys/amd64/sys/thread.c b/sys/amd64/sys/thread.c index 6f154f3..ea7f991 100644 --- a/sys/amd64/sys/thread.c +++ b/sys/amd64/sys/thread.c @@ -18,6 +18,8 @@ #include "sys/debug.h" #include "sys/mm.h" +#include "sys/amd64/sys_proc.h" + #define THREAD_KSTACK_SIZE 32768 // Means stack0 wasn't kmalloc'd, so don't free it @@ -167,6 +169,8 @@ int thread_init( t->space = space; // Set this stuff to prevent undefined behavior + t->pgid = 0; + t->sid = 0; t->sigq = 0; t->flags = flags; @@ -292,6 +296,18 @@ int sys_execve(const char *filename, const char *const argv[], const char *const return res; } + // If the file has setuid bit, apply owner's UID: + if (st.st_mode & S_ISUID) { + // I don't want to compromise my development machine by having SUID + // binaries written by myself residing there with root UID. Better + // employ this kind of hack for that. +#if defined(ALL_SETUID_0) + thr->ioctx.uid = 0; +#else + thr->ioctx.uid = st.st_uid; +#endif + } + // Read first line of the file if ((bread = vfs_read(&thr->ioctx, &fd, shebang_buf, sizeof(shebang_buf))) < 0) { kwarn("%s: %s\n", filename, kstrerror(bread)); @@ -445,6 +461,8 @@ int sys_fork(void) { thr_dst->parent = thr_src; thr_dst->next_child = thr_src->child; thr_src->child = thr_dst; + thr_dst->sid = thr_src->sid; + thr_dst->pgid = thr_src->pgid; sched_add(thr_dst); _assert(thr_dst->pid); diff --git a/sys/amd64/sys_file.c b/sys/amd64/sys_file.c index 9cbf9de..0980641 100644 --- a/sys/amd64/sys_file.c +++ b/sys/amd64/sys_file.c @@ -291,6 +291,22 @@ done: return res; } +int sys_ioctl(int fd, unsigned int cmd, void *arg) { + struct thread *thr = get_cpu()->thread; + struct ofile *of; + _assert(thr); + + if (fd < 0 || fd >= THREAD_MAX_FDS) { + return -EBADF; + } + + if (!(of = thr->fds[fd])) { + return -EBADF; + } + + return vfs_ioctl(&thr->ioctx, of, cmd, arg); +} + int sys_isatty(int fd) { struct thread *thr = get_cpu()->thread; struct ofile *of; diff --git a/sys/amd64/sys_proc.c b/sys/amd64/sys_proc.c index 9daab3f..d9bf313 100644 --- a/sys/amd64/sys_proc.c +++ b/sys/amd64/sys_proc.c @@ -120,7 +120,7 @@ int sys_setgid(gid_t gid) { struct thread *thr = get_cpu()->thread; _assert(thr); - if (thr->ioctx.gid != 0) { + if (thr->ioctx.gid != 0 && thr->ioctx.uid != 0) { return -EACCES; } @@ -140,6 +140,48 @@ gid_t sys_getgid(void) { return thr->ioctx.gid; } +pid_t sys_getpgid(pid_t pid) { + struct thread *thr; + + if (pid == 0) { + thr = get_cpu()->thread; + _assert(thr); + } else { + thr = sched_find(pid); + } + + if (!thr) { + return -ESRCH; + } + + return thr->pgid; +} + +int sys_setpgid(pid_t pid, pid_t pgrp) { + struct thread *thr = get_cpu()->thread; + _assert(thr); + + if (pid == 0 && pgrp == 0) { + thr->pgid = thr->pid; + return 0; + } + + // Find child with pid pid (guess only children can be setpgid'd) + struct thread *ch; + for (ch = thr->child; ch; ch = ch->next_child) { + if (ch->pid == pid) { + if (ch->pgid != thr->pgid) { + return -EACCES; + } + + ch->pgid = pgrp; + return 0; + } + } + + return -ESRCH; +} + int sys_unknown(int no) { asm volatile ("cli"); struct thread *thr = get_cpu()->thread; diff --git a/sys/amd64/syscall.c b/sys/amd64/syscall.c index 1330353..c087d9b 100644 --- a/sys/amd64/syscall.c +++ b/sys/amd64/syscall.c @@ -18,6 +18,7 @@ const void *amd64_syscall_jmp_table[256] = { [SYSCALL_NR_OPEN] = sys_open, [SYSCALL_NR_CLOSE] = sys_close, [SYSCALL_NR_LSEEK] = sys_lseek, + [SYSCALL_NR_IOCTL] = sys_ioctl, [SYSCALL_NR_SELECT] = sys_select, [SYSCALL_NR_GETCWD] = sys_getcwd, [SYSCALL_NR_CHDIR] = sys_chdir, @@ -44,6 +45,8 @@ const void *amd64_syscall_jmp_table[256] = { [SYSCALL_NR_SETGID] = sys_setgid, [SYSCALL_NR_GETUID] = sys_getuid, [SYSCALL_NR_GETGID] = sys_getgid, + [SYSCALL_NR_SETPGID] = sys_setpgid, + [SYSCALL_NR_GETPGID] = sys_getpgid, // System [SYSCALL_NR_UNAME] = sys_uname, diff --git a/sys/chr.c b/sys/chr.c index 8498875..eb61f38 100644 --- a/sys/chr.c +++ b/sys/chr.c @@ -1,6 +1,16 @@ #include "sys/chr.h" #include "sys/errno.h" +int chr_ioctl(struct chrdev *chr, unsigned int cmd, void *arg) { + if (!chr) { + return -ENODEV; + } + if (!chr->ioctl) { + return -EINVAL; + } + return chr->ioctl(chr, cmd, arg); +} + ssize_t chr_write(struct chrdev *chr, const void *buf, size_t off, size_t count) { if (!chr) { return -ENODEV; diff --git a/sys/dev.c b/sys/dev.c index 7e924a4..581f97e 100644 --- a/sys/dev.c +++ b/sys/dev.c @@ -163,7 +163,7 @@ int dev_find(enum dev_class cls, const char *name, struct vnode **node) { //// static int devfs_vnode_stat(struct vnode *node, struct stat *st) { - st->st_mode = (node->mode & 0x1FF) | vfs_vnode_to_mode(node->type); + st->st_mode = (node->mode & VFS_MODE_MASK) | vfs_vnode_to_mode(node->type); st->st_uid = node->uid; st->st_gid = node->gid; st->st_size = 0; diff --git a/sys/tty.c b/sys/tty.c index 44bf0b7..b1b90c7 100644 --- a/sys/tty.c +++ b/sys/tty.c @@ -4,6 +4,9 @@ #include "sys/debug.h" #include "sys/panic.h" #include "sys/string.h" +#include "sys/assert.h" +#include "sys/termios.h" +#include "sys/sched.h" #include "sys/ring.h" #include "sys/mm.h" #include "sys/amd64/cpu.h" @@ -11,18 +14,46 @@ #include "sys/dev.h" #define DEV_TTY(n) (n ## ULL) -#define DEV_DATA_TTY(n) ((void *) n ## ULL) -#define DEV_DATA_GETTTY(d) ((uint64_t) (d)->dev_data) static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim); static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim); +static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg); + +struct tty_data { + // Process group ID of the foreground group (session leader) + pid_t fg_pgid; + // Number + int tty_n; + // TODO: make console screen and keyboard character devices +}; + +static struct tty_data _dev_tty0_data = { + .fg_pgid = 1, + .tty_n = DEV_TTY(0) +}; static struct chrdev _dev_tty0 = { - .dev_data = DEV_DATA_TTY(0), + .dev_data = &_dev_tty0_data, .write = tty_write, - .read = tty_read + .read = tty_read, + .ioctl = tty_ioctl }; +static void tty_signal_group(struct chrdev *tty, int signum) { + struct tty_data *data = tty->dev_data; + _assert(data); + sched_signal_group(data->fg_pgid, signum); +} + +void tty_signal_write(int tty_no, int signum) { + kdebug("Send signal %d on tty%d\n", signum, tty_no); + switch (tty_no) { + case 0: + tty_signal_group(&_dev_tty0, signum); + break; + } +} + // This function receives keystrokes from keyboard drivers void tty_buffer_write(int tty_no, char c) { switch (tty_no) { @@ -40,9 +71,9 @@ void tty_init(void) { // TODO: multiple ttys static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim) { - uint64_t tty_no = DEV_DATA_GETTTY(tty); - - if (tty_no != DEV_TTY(0)) { + struct tty_data *data = tty->dev_data; + _assert(data); + if (data->tty_n != DEV_TTY(0)) { return -EINVAL; } @@ -54,10 +85,11 @@ static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t } static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim) { - uint64_t tty_no = DEV_DATA_GETTTY(tty); + struct tty_data *data = tty->dev_data; + _assert(data); char ibuf[16]; - if (tty_no != DEV_TTY(0)) { + if (data->tty_n != DEV_TTY(0)) { return -EINVAL; } @@ -81,3 +113,16 @@ static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim) { return p; } + +static int tty_ioctl(struct chrdev *tty, unsigned int cmd, void *arg) { + struct tty_data *data = tty->dev_data; + _assert(data); + + switch (cmd) { + case TIOCSPGRP: + data->fg_pgid = *(pid_t *) arg; + return 0; + default: + return -EINVAL; + } +} diff --git a/sys/vfs/ext2/ext2vnop.c b/sys/vfs/ext2/ext2vnop.c index 3e9454d..ae88d71 100644 --- a/sys/vfs/ext2/ext2vnop.c +++ b/sys/vfs/ext2/ext2vnop.c @@ -104,7 +104,7 @@ static int ext2_vnode_find(struct vnode *vn, const char *name, struct vnode **re node->ino = dirent->ino; node->op = &ext2_vnode_ops; - node->mode = inode->type_perm & 0x1FF; + node->mode = inode->type_perm & VFS_MODE_MASK; node->uid = inode->uid; node->gid = inode->gid; @@ -202,7 +202,7 @@ static int ext2_vnode_mkdir(struct vnode *at, const char *name, uid_t uid, gid_t ent_inode->l2_indirect_block = 0; ent_inode->l3_indirect_block = 0; - ent_inode->type_perm = (mode & 0x1FF) | EXT2_TYPE_DIR; + ent_inode->type_perm = (mode & VFS_MODE_MASK) | EXT2_TYPE_DIR; ent_inode->uid = uid; ent_inode->gid = gid; ent_inode->disk_sector_count = 0; @@ -288,7 +288,7 @@ static int ext2_vnode_creat(struct vnode *at, const char *name, uid_t uid, gid_t ent_inode->uid = uid; ent_inode->gid = gid; // NOTE: only regular files can be created this way now - ent_inode->type_perm = (mode & 0x1FF) | (EXT2_TYPE_REG); + ent_inode->type_perm = (mode & VFS_MODE_MASK) | (EXT2_TYPE_REG); ent_inode->disk_sector_count = 0; ent_inode->size_lower = 0; @@ -612,8 +612,8 @@ static int ext2_vnode_chmod(struct vnode *vn, mode_t mode) { struct ext2_inode *inode = (struct ext2_inode *) vn->fs_data; // Update only access mode - inode->type_perm &= ~0x1FF; - inode->type_perm |= mode & 0x1FF; + inode->type_perm &= ~VFS_MODE_MASK; + inode->type_perm |= mode & VFS_MODE_MASK; // Write the inode back return ext2_write_inode(vn->fs, inode, vn->ino); @@ -725,7 +725,7 @@ static int ext2_vnode_unlink(struct vnode *node) { // // *uid = inode->uid; // *gid = inode->gid; -// *mode = inode->type_perm & 0x1FF; +// *mode = inode->type_perm & VFS_MODE_MASK; // // return 0; //} diff --git a/sys/vfs/tar.c b/sys/vfs/tar.c index 3c24459..133ee04 100644 --- a/sys/vfs/tar.c +++ b/sys/vfs/tar.c @@ -200,7 +200,7 @@ static int tar_init(struct fs *tar, const char *opt) { // Convert node metadata values from octal uid_t uid = tarfs_octal(hdr->meta_oct.uid, 8); gid_t gid = tarfs_octal(hdr->meta_oct.gid, 8); - mode_t mode = tarfs_octal(hdr->meta_oct.mode, 8) & 0x1FF; + mode_t mode = tarfs_octal(hdr->meta_oct.mode, 8) & VFS_MODE_MASK; time_t mtime = tarfs_octal(hdr->meta_oct.mtime, 12); @@ -255,12 +255,12 @@ static int tar_init(struct fs *tar, const char *opt) { node->uid = hdr->meta.uid; node->gid = hdr->meta.gid; - node->mode = hdr->meta.mode & 0x1FF; + node->mode = hdr->meta.mode & VFS_MODE_MASK; node->fs_data = hdr; node->fs = tar; - off += 512 + ((node_size + 0x1FF) & ~0x1FF); + off += 512 + ((node_size + 511) & ~511); } return 0; @@ -313,7 +313,7 @@ static int tarfs_vnode_stat(struct vnode *vn, struct stat *st) { st->st_uid = vn->uid; st->st_gid = vn->gid; - st->st_mode = (vn->mode & 0x1FF) | (vn->type == VN_DIR ? S_IFDIR : S_IFREG); + st->st_mode = (vn->mode & VFS_MODE_MASK) | (vn->type == VN_DIR ? S_IFDIR : S_IFREG); st->st_ino = 0; @@ -341,7 +341,7 @@ static int tarfs_vnode_mkdir(struct vnode *at, const char *name, uid_t uid, gid_ hdr->meta.uid = uid; hdr->meta.gid = gid; - hdr->meta.mode = mode & 0x1FF; + hdr->meta.mode = mode & VFS_MODE_MASK; hdr->meta.size = 0; time_t cur_time = time(); hdr->meta.mtime = cur_time; @@ -349,7 +349,7 @@ static int tarfs_vnode_mkdir(struct vnode *at, const char *name, uid_t uid, gid_ node->uid = uid; node->gid = gid; - node->mode = mode & 0x1FF; + node->mode = mode & VFS_MODE_MASK; node->flags = VN_MEMORY; node->fs_data = hdr; @@ -372,7 +372,7 @@ static int tarfs_vnode_creat(struct vnode *at, const char *name, uid_t uid, gid_ hdr->meta.uid = uid; hdr->meta.gid = gid; - hdr->meta.mode = mode & 0x1FF; + hdr->meta.mode = mode & VFS_MODE_MASK; hdr->meta.size = 0; time_t cur_time = time(); hdr->meta.mtime = cur_time; @@ -387,7 +387,7 @@ static int tarfs_vnode_creat(struct vnode *at, const char *name, uid_t uid, gid_ node->uid = uid; node->gid = gid; - node->mode = mode & 0x1FF; + node->mode = mode & VFS_MODE_MASK; node->flags = VN_MEMORY; node->fs_data = hdr; @@ -496,7 +496,6 @@ static ssize_t tarfs_vnode_read(struct ofile *fd, void *buf, size_t count) { uintptr_t blk_addr; while (can_read) { - kdebug("pos = %u\n", fd->pos); size_t blk_off = fd->pos % 512; size_t blk_ind = fd->pos / 512; size_t bread = MIN(can_read, 512 - blk_off); diff --git a/sys/vfs/vfs_ops.c b/sys/vfs/vfs_ops.c index 287f685..f5f4986 100644 --- a/sys/vfs/vfs_ops.c +++ b/sys/vfs/vfs_ops.c @@ -558,7 +558,7 @@ int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode) { struct vnode *node; int res; - mode &= 0x1FF; + mode &= VFS_MODE_MASK; if ((res = vfs_find(ctx, ctx->cwd_vnode, path, &node)) != 0) { return res; @@ -608,3 +608,17 @@ int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid) { return 0; } + +int vfs_ioctl(struct vfs_ioctx *ctx, struct ofile *fd, unsigned int cmd, void *arg) { + _assert(ctx); + _assert(fd); + struct vnode *node = fd->vnode; + _assert(node); + + switch (node->type) { + case VN_CHR: + return chr_ioctl(node->dev, cmd, arg); + default: + return -EINVAL; + } +}