From 6cbe58797781cb8514a62bb3ab0e3e8a5d58bce2 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Thu, 31 Aug 2023 01:06:41 +0200 Subject: kernel: add _sys_getprocfs in place of HANDLE_PROCFS This makes the side-effects more explicit, and feels less hacky than `HANDLE_PROCFS`. I don't think accessing a handle alone should have side-effects, even if it's a "special" one. --- src/bootstrap/main.c | 7 ++++--- src/cmd/ps/ps.c | 18 ++++++++++++++---- src/cmd/shell/shell.c | 3 ++- src/kernel/proc.c | 14 -------------- src/kernel/proc.h | 3 --- src/kernel/syscalls.c | 18 +++++++++++++++++- src/libc/camellia.c | 11 +++++++++++ src/libc/include/camellia.h | 2 ++ src/libc/syscall.c | 4 ++++ src/libk/include/camellia/flags.h | 1 - src/libk/include/camellia/syscalls.h | 3 +++ 11 files changed, 57 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index d27da39..27c5fad 100644 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -1,10 +1,11 @@ #include <_proc.h> +#include #include +#include #include +#include #include #include -#include -#include #include "tar.h" @@ -17,7 +18,7 @@ int main(void) { _sys_memflag(_psdata_loc, 1, MEMFLAG_PRESENT); setprogname("bootstrap"); - _sys_mount(HANDLE_PROCFS, "/proc/", strlen("/proc/")); + camellia_procfs("/proc/"); MOUNT_AT("/") { fs_dirinject2((const char*[]) { "/proc/", diff --git a/src/cmd/ps/ps.c b/src/cmd/ps/ps.c index 76a5841..a4b2e4c 100644 --- a/src/cmd/ps/ps.c +++ b/src/cmd/ps/ps.c @@ -5,14 +5,24 @@ #include #include +void +usage(void) +{ + fprintf(stderr, "usage: ps [path]\n"); + exit(1); +} + int -main(void) +main(int argc, const char *argv[]) { + const char *path = argc >= 2 ? argv[1] : "/proc/"; + if (argc > 2) usage(); + char *readbuf = malloc(4096); char *procbuf = malloc(4096); - FILE *f = fopen("/proc/", "r"); + FILE *f = fopen(path, "r"); if (!f) { - err(1, "couldn't open /proc/"); + err(1, "couldn't open %s", path); } // TODO library for iterating over directories @@ -27,7 +37,7 @@ main(void) size_t entryl = end - (readbuf+pos) + 1; if (isdigit(readbuf[pos])) { FILE *g; - sprintf(procbuf, "/proc/%smem", readbuf+pos); + sprintf(procbuf, "%s%smem", path, readbuf+pos); g = fopen(procbuf, "r"); if (!g) { warn("couldn't open \"%s\"", procbuf); diff --git a/src/cmd/shell/shell.c b/src/cmd/shell/shell.c index df239eb..3f33756 100644 --- a/src/cmd/shell/shell.c +++ b/src/cmd/shell/shell.c @@ -1,5 +1,6 @@ #include "builtins.h" #include "shell.h" +#include #include #include #include @@ -61,7 +62,7 @@ void run_args(int argc, char **argv, struct redir *redir) { fprintf(stderr, "procmnt: missing mountpoint\n"); return; } - _sys_mount(HANDLE_PROCFS, argv[1], strlen(argv[1])); + camellia_procfs(argv[1]); /* if (!(3 <= argc && !strcmp(argv[2], "raw"))) { if (!mount_at("/")) { diff --git a/src/kernel/proc.c b/src/kernel/proc.c index bbf939c..1084f48 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -384,7 +383,6 @@ void proc_tryreap(Proc *dead) { return; /* keep the tombstone */ } - handle_close(dead->specialh.procfs); assert(dead->refcount == 0); if (parent) { /* not applicable to init */ proc_forget(dead); @@ -513,18 +511,6 @@ Handle *proc_handle_get(Proc *p, hid_t id) { .refcount = 2, /* never free */ }; return &h; - } else if (id == HANDLE_PROCFS) { - if (!p->specialh.procfs) { - Handle *h = kmalloc(sizeof *h); - proc_ns_create(p); - *h = (Handle){ - .type = HANDLE_FS_FRONT, - .backend = procfs_backend(p), - .refcount = 1, - }; - p->specialh.procfs = h; - } - return p->specialh.procfs; } else if (0 <= id && id < HANDLE_MAX) { return p->_handles[id]; } else { diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 0dffe08..15da852 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -69,9 +69,6 @@ struct Proc { VfsMount *mount; Handle **_handles; /* points to Handle *[HANDLE_MAX] */ uint64_t *handles_refcount; /* works just like pages_refcount */ - struct { - Handle *procfs; - } specialh; // TODO pids should be 64bit. also typedef pid_t uint32_t globalid; /* only for internal use, don't expose to userland */ diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 0dda320..b040285 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -120,7 +121,6 @@ long _sys_mount(hid_t hid, const char __user *path, long len) { // remove trailing slash // mounting something under `/this` and `/this/` should be equalivent if (path_buf[len - 1] == '/') { - if (len == 0) goto fail; len--; } @@ -404,6 +404,21 @@ int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out) { return 0; // dummy } +hid_t _sys_getprocfs(int flags) { + if (flags != 0) { + SYSCALL_RETURN(-ENOSYS); + } + proc_ns_create(proc_cur); + + Handle *h; + hid_t hid = proc_handle_init(proc_cur, HANDLE_FS_FRONT, &h); + if (hid < 0) { + SYSCALL_RETURN(-EMFILE); + } + h->backend = procfs_backend(proc_cur); + SYSCALL_RETURN(hid); +} + long _sys_execbuf(void __user *ubuf, size_t len) { if (len == 0) SYSCALL_RETURN(0); if (len > EXECBUF_MAX_LEN) @@ -458,6 +473,7 @@ long _syscall(long num, long a, long b, long c, long d, long e) { break; case _SYS_GETPID: _sys_getpid(); break; case _SYS_GETPPID: _sys_getppid(); break; case _SYS_WAIT2: _sys_wait2(a, b, (userptr_t)c); + break; case _SYS_GETPROCFS: _sys_getprocfs(a); break; case _SYS_EXECBUF: _sys_execbuf((userptr_t)a, b); break; case _SYS_DEBUG_KLOG: _sys_debug_klog((userptr_t)a, b); break; diff --git a/src/libc/camellia.c b/src/libc/camellia.c index 4e092e4..bc38e77 100644 --- a/src/libc/camellia.c +++ b/src/libc/camellia.c @@ -28,3 +28,14 @@ hid_t camellia_open(const char *path, int flags) { return ret; } + +int camellia_procfs(const char *path) { + hid_t hid = _sys_getprocfs(0); + if (hid < 0) { + errno = -hid; + return -1; + } + _sys_mount(hid, path, strlen(path)); + close(hid); + return 0; +} diff --git a/src/libc/include/camellia.h b/src/libc/include/camellia.h index 2e4998b..49298bd 100644 --- a/src/libc/include/camellia.h +++ b/src/libc/include/camellia.h @@ -3,3 +3,5 @@ #include hid_t camellia_open(const char *path, int flags); + +int camellia_procfs(const char *path); diff --git a/src/libc/syscall.c b/src/libc/syscall.c index b920e14..706aec6 100644 --- a/src/libc/syscall.c +++ b/src/libc/syscall.c @@ -90,6 +90,10 @@ int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out) { return (int)_syscall(_SYS_WAIT2, (long)pid, (long)flags, (long)out, 0, 0); } +hid_t _sys_getprocfs(int flags) { + return (hid_t)_syscall(_SYS_GETPROCFS, (long)flags, 0, 0, 0, 0); +} + long _sys_execbuf(void __user *buf, size_t len) { return _syscall(_SYS_EXECBUF, (long)buf, (long)len, 0, 0, 0); } diff --git a/src/libk/include/camellia/flags.h b/src/libk/include/camellia/flags.h index f4c54fe..bc34616 100644 --- a/src/libk/include/camellia/flags.h +++ b/src/libk/include/camellia/flags.h @@ -32,4 +32,3 @@ /* special handles */ #define HANDLE_NULLFS -2 -#define HANDLE_PROCFS -3 diff --git a/src/libk/include/camellia/syscalls.h b/src/libk/include/camellia/syscalls.h index b7e60a0..58898d4 100644 --- a/src/libk/include/camellia/syscalls.h +++ b/src/libk/include/camellia/syscalls.h @@ -21,6 +21,7 @@ #define _SYS_GETPID 19 #define _SYS_GETPPID 20 #define _SYS_WAIT2 21 +#define _SYS_GETPROCFS 22 #define _SYS_EXECBUF 100 #define _SYS_DEBUG_KLOG 101 @@ -81,6 +82,8 @@ uint32_t _sys_getppid(void); int _sys_wait2(int pid, int flags, struct sys_wait2 __user *out); +hid_t _sys_getprocfs(int flags); + /* see shared/execbuf.h */ long _sys_execbuf(void __user *buf, size_t len); -- cgit v1.2.3