Basic job control with process groups. setuid bit support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)\"
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
int ioctl(int fd, unsigned int cmd, void *arg);
|
||||
#endif
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define TIOCSPGRP 0x5410
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+3
-1
@@ -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')
|
||||
|
||||
+5
-2
@@ -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;
|
||||
}
|
||||
|
||||
+18
-1
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+25
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+43
-1
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
//}
|
||||
|
||||
+8
-9
@@ -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);
|
||||
|
||||
+15
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user