mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
syscalls: implement sysctl and add process listing
This commit is contained in:
@@ -104,6 +104,7 @@ extern syscall_fstatvfsat
|
|||||||
extern syscall_getsockopt
|
extern syscall_getsockopt
|
||||||
extern syscall_clock_getres
|
extern syscall_clock_getres
|
||||||
extern syscall_setpriority
|
extern syscall_setpriority
|
||||||
|
extern syscall_sysctl
|
||||||
syscalltab:
|
syscalltab:
|
||||||
dq syscall_print
|
dq syscall_print
|
||||||
dq syscall_mmap
|
dq syscall_mmap
|
||||||
@@ -210,7 +211,8 @@ dq syscall_fstatvfsat
|
|||||||
dq syscall_getsockopt
|
dq syscall_getsockopt
|
||||||
dq syscall_clock_getres
|
dq syscall_clock_getres
|
||||||
dq syscall_setpriority
|
dq syscall_setpriority
|
||||||
syscallcount equ 105
|
dq syscall_sysctl
|
||||||
|
syscallcount equ 106
|
||||||
section .text
|
section .text
|
||||||
global arch_syscall_entry
|
global arch_syscall_entry
|
||||||
; on entry:
|
; on entry:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
void arch_interrupt_disable();
|
void arch_interrupt_disable();
|
||||||
void arch_interrupt_enable();
|
void arch_interrupt_enable();
|
||||||
|
|
||||||
#define SYSCALL_COUNT 105
|
#define SYSCALL_COUNT 106
|
||||||
#define LOGSTR(x) arch_e9_puts(x)
|
#define LOGSTR(x) arch_e9_puts(x)
|
||||||
|
|
||||||
static char *name[] = {
|
static char *name[] = {
|
||||||
@@ -118,6 +118,7 @@ static char *name[] = {
|
|||||||
"getsockopt",
|
"getsockopt",
|
||||||
"clock_getres",
|
"clock_getres",
|
||||||
"setpriority",
|
"setpriority",
|
||||||
|
"sysctl",
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *args[] = {
|
static char *args[] = {
|
||||||
@@ -226,6 +227,7 @@ static char *args[] = {
|
|||||||
"fd %d level %d optname %d optval %p optlen %p", // getsockopt
|
"fd %d level %d optname %d optval %p optlen %p", // getsockopt
|
||||||
"clockid %d timespec %p", // clock_getres
|
"clockid %d timespec %p", // clock_getres
|
||||||
"which %d who %d prio %d", // setpriority
|
"which %d who %d prio %d", // setpriority
|
||||||
|
"name %p name_len %lu oldp %p old_size %p newp %p new_size %lu", // sysctl
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
#include <kernel/thread.h>
|
#include <kernel/thread.h>
|
||||||
|
|
||||||
|
#include <kernel/sysctl.h>
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
#include <arch/ldt.h>
|
#include <arch/ldt.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -90,6 +92,11 @@ typedef struct proc_t {
|
|||||||
itimer_t virtualtime;
|
itimer_t virtualtime;
|
||||||
itimer_t profiling;
|
itimer_t profiling;
|
||||||
} timer;
|
} timer;
|
||||||
|
|
||||||
|
char name[SYS_CTL_KERN_PROC_INFO_NAME_SIZE];
|
||||||
|
timespec_t start_time;
|
||||||
|
spinlock_t runtime_lock;
|
||||||
|
timespec_t total_runtime;
|
||||||
} proc_t;
|
} proc_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -125,5 +132,6 @@ void proc_init(void);
|
|||||||
void proc_exit(void);
|
void proc_exit(void);
|
||||||
void proc_run_init();
|
void proc_run_init();
|
||||||
size_t proc_get_count(void);
|
size_t proc_get_count(void);
|
||||||
|
size_t proc_get_table(proc_t **procs, size_t count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef _SYSCTL_H
|
||||||
|
#define _SYSCTL_H
|
||||||
|
|
||||||
|
#include <kernel/abi.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define SYS_CTL_NAME_MAX 6
|
||||||
|
|
||||||
|
#define SYS_CTL_KERN 1
|
||||||
|
#define SYS_CTL_KERN_PROC 1
|
||||||
|
#define SYS_CTL_KERN_PROC_ALL 1
|
||||||
|
|
||||||
|
#define SYS_CTL_KERN_PROC_INFO_NAME_SIZE 64
|
||||||
|
#define SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE 64
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pid_t pid;
|
||||||
|
uid_t uid;
|
||||||
|
uid_t euid;
|
||||||
|
uid_t suid;
|
||||||
|
gid_t gid;
|
||||||
|
gid_t egid;
|
||||||
|
gid_t sgid;
|
||||||
|
size_t thread_count;
|
||||||
|
char name[SYS_CTL_KERN_PROC_INFO_NAME_SIZE];
|
||||||
|
pid_t ppid;
|
||||||
|
pid_t pgid;
|
||||||
|
pid_t sid;
|
||||||
|
timespec_t start_timestamp;
|
||||||
|
timespec_t total_runtime;
|
||||||
|
int state;
|
||||||
|
int cpu_time;
|
||||||
|
int nice;
|
||||||
|
size_t virtual_pages;
|
||||||
|
size_t physical_pages;
|
||||||
|
char tty_name[SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE];
|
||||||
|
} sysctl_proc_info_t;
|
||||||
|
|
||||||
|
int sysctl(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len);
|
||||||
|
int sysctl_kern(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -44,5 +44,6 @@ void tty_process(tty_t *tty, char c);
|
|||||||
void tty_unregister(tty_t *tty);
|
void tty_unregister(tty_t *tty);
|
||||||
int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cred);
|
int tty_ioctl(tty_t *tty, unsigned long req, void *arg, int *result, cred_t *cred);
|
||||||
size_t tty_opened(tty_t *tty);
|
size_t tty_opened(tty_t *tty);
|
||||||
|
void tty_release(tty_t *tty);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
size_t strlen(const char *str);
|
size_t strlen(const char *str);
|
||||||
size_t strnlen(const char *str, size_t max);
|
size_t strnlen(const char *str, size_t max);
|
||||||
char *strcpy(char *dest, const char *src);
|
char *strcpy(char *dest, const char *src);
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n);
|
||||||
char *strcat(char *dest, const char *str);
|
char *strcat(char *dest, const char *str);
|
||||||
void *memcpy(void *dest, const void *src, size_t size);
|
void *memcpy(void *dest, const void *src, size_t size);
|
||||||
void *memset(void *dest, int what, size_t size);
|
void *memset(void *dest, int what, size_t size);
|
||||||
@@ -15,5 +16,6 @@ int memcmp(const void *a, const void *b, size_t s);
|
|||||||
void *memmove(void *_d, const void *_s, size_t c);
|
void *memmove(void *_d, const void *_s, size_t c);
|
||||||
char *strerror(int errno);
|
char *strerror(int errno);
|
||||||
long long atoll(const char *c);
|
long long atoll(const char *c);
|
||||||
|
char *strrchr(const char *s, char c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -590,6 +590,10 @@ void tty_unregister(tty_t *tty) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tty_release(tty_t *tty) {
|
||||||
|
VOP_RELEASE(tty->mastervnode);
|
||||||
|
}
|
||||||
|
|
||||||
size_t tty_opened(tty_t *tty) {
|
size_t tty_opened(tty_t *tty) {
|
||||||
return __atomic_load_n(&tty->opened, __ATOMIC_SEQ_CST);
|
return __atomic_load_n(&tty->opened, __ATOMIC_SEQ_CST);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,37 @@ long long atoll(const char *c) {
|
|||||||
return first == '-' ? -v : v;
|
return first == '-' ? -v : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *strrchr(const char *s, char c) {
|
||||||
|
char *f = NULL;
|
||||||
|
while (*s) {
|
||||||
|
if (*s == c)
|
||||||
|
f = (char *)s;
|
||||||
|
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '\0')
|
||||||
|
return (char *)s;
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strncpy(char *dest, const char *src, size_t n) {
|
||||||
|
char *copy = dest;
|
||||||
|
|
||||||
|
while (n && *src) {
|
||||||
|
*dest = *src;
|
||||||
|
++src;
|
||||||
|
++dest;
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; ++i)
|
||||||
|
dest[i] = '\0';
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
#define DO_NAME(e) \
|
#define DO_NAME(e) \
|
||||||
case e: \
|
case e: \
|
||||||
return #e;
|
return #e;
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
#include <kernel/sysctl.h>
|
||||||
|
#include <kernel/proc.h>
|
||||||
|
#include <kernel/usercopy.h>
|
||||||
|
#include <kernel/alloc.h>
|
||||||
|
#include <kernel/jobctl.h>
|
||||||
|
#include <kernel/tty.h>
|
||||||
|
|
||||||
|
#define SYS_CTL_NAME_MAX 6
|
||||||
|
|
||||||
|
#define SYS_CTL_KERN 1
|
||||||
|
#define SYS_CTL_KERN_PROC 1
|
||||||
|
#define SYS_CTL_KERN_PROC_ALL 1
|
||||||
|
|
||||||
|
static void release_procs(proc_t **procs, size_t size) {
|
||||||
|
for (size_t i = 0; i < size; ++i) {
|
||||||
|
PROC_RELEASE(procs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: fix size differences returning ENOMEM
|
||||||
|
static int ctl_proc(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t) {
|
||||||
|
if (name_len != 4)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
if (newp)
|
||||||
|
return EPERM;
|
||||||
|
|
||||||
|
size_t struct_size = min(name[2], sizeof(sysctl_proc_info_t));
|
||||||
|
size_t proc_count = proc_get_count();
|
||||||
|
size_t struct_count = proc_count;
|
||||||
|
if (name[3])
|
||||||
|
struct_count = min(struct_count, name[3]);
|
||||||
|
|
||||||
|
if (!oldp) {
|
||||||
|
// the caller just wants to know the size of the process table
|
||||||
|
size_t new_len = struct_count * struct_size;
|
||||||
|
return USERCOPY_POSSIBLY_TO_USER(old_lenp, &new_len, sizeof(new_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t old_len;
|
||||||
|
int error = USERCOPY_POSSIBLY_FROM_USER(&old_len, old_lenp, sizeof(old_len));
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (old_len < struct_size * struct_count)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
proc_t **procs = alloc(sizeof(proc_t *) * struct_count);
|
||||||
|
if (procs == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
struct_count = proc_get_table(procs, struct_count);
|
||||||
|
size_t new_len = struct_count * struct_size;
|
||||||
|
error = USERCOPY_POSSIBLY_TO_USER(old_lenp, &new_len, sizeof(new_len));
|
||||||
|
if (error)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < struct_count; ++i) {
|
||||||
|
sysctl_proc_info_t proc_info;
|
||||||
|
|
||||||
|
// TODO: this is currently very unsafe.
|
||||||
|
proc_t *parent = procs[i]->parent;
|
||||||
|
|
||||||
|
cred_getuids(&procs[i]->cred, &proc_info.uid, &proc_info.euid, &proc_info.suid);
|
||||||
|
cred_getgids(&procs[i]->cred, &proc_info.gid, &proc_info.egid, &proc_info.sgid);
|
||||||
|
|
||||||
|
strncpy(proc_info.name, procs[i]->name, sizeof(proc_info.name));
|
||||||
|
|
||||||
|
proc_info.pid = procs[i]->pid;
|
||||||
|
proc_info.thread_count = procs[i]->runningthreadcount;
|
||||||
|
proc_info.ppid = parent ? parent->pid : 0;
|
||||||
|
proc_info.pgid = jobctl_getpgid(procs[i]);
|
||||||
|
proc_info.sid = jobctl_getsid(procs[i]);
|
||||||
|
|
||||||
|
proc_info.start_timestamp = procs[i]->start_time;
|
||||||
|
long ipl = spinlock_acquire_raise_ipl(&procs[i]->runtime_lock, IPL_DPC);
|
||||||
|
proc_info.total_runtime = procs[i]->total_runtime;
|
||||||
|
spinlock_release_lower_ipl(&procs[i]->runtime_lock, ipl);
|
||||||
|
|
||||||
|
proc_info.state = 0;
|
||||||
|
proc_info.cpu_time = 0;
|
||||||
|
proc_info.nice = procs[i]->nice;
|
||||||
|
proc_info.virtual_pages = 0;
|
||||||
|
proc_info.physical_pages = 0;
|
||||||
|
|
||||||
|
tty_t *ctty = jobctl_getctty(procs[i]);
|
||||||
|
if (ctty) {
|
||||||
|
strncpy(proc_info.tty_name, ctty->name, sizeof(proc_info.tty_name));
|
||||||
|
tty_release(ctty);
|
||||||
|
} else {
|
||||||
|
memset(proc_info.tty_name, 0, sizeof(proc_info.tty_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
error = USERCOPY_POSSIBLY_TO_USER(oldp + i * struct_size, &proc_info, struct_size);
|
||||||
|
if (error)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
release_procs(procs, struct_count);
|
||||||
|
free(procs);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sysctl_kern(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len) {
|
||||||
|
switch (*name) {
|
||||||
|
case SYS_CTL_KERN_PROC:
|
||||||
|
return ctl_proc(name + 1, name_len - 1, oldp, old_lenp, newp, new_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include <kernel/sysctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
// oldp, old_lenp and newp might be user pointers
|
||||||
|
int sysctl(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len) {
|
||||||
|
if (name_len < 2 || name_len > SYS_CTL_NAME_MAX)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
switch (*name) {
|
||||||
|
case SYS_CTL_KERN:
|
||||||
|
return sysctl_kern(name + 1, name_len - 1, oldp, old_lenp, newp, new_len);
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
-1
@@ -33,6 +33,24 @@ size_t proc_get_count(void) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t proc_get_table(proc_t **procs, size_t count) {
|
||||||
|
MUTEX_ACQUIRE(&proc_pid_table_mutex);
|
||||||
|
|
||||||
|
size_t done_count = 0;
|
||||||
|
HASHTABLE_FOREACH(&pid_table) {
|
||||||
|
if (done_count == count)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
proc_t *current = entry->value;
|
||||||
|
PROC_HOLD(current);
|
||||||
|
procs[done_count++] = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
MUTEX_RELEASE(&proc_pid_table_mutex);
|
||||||
|
return done_count;
|
||||||
|
}
|
||||||
|
|
||||||
proc_t *proc_get_from_pid(int pid) {
|
proc_t *proc_get_from_pid(int pid) {
|
||||||
MUTEX_ACQUIRE(&proc_pid_table_mutex);
|
MUTEX_ACQUIRE(&proc_pid_table_mutex);
|
||||||
void *_proc = NULL;
|
void *_proc = NULL;
|
||||||
@@ -108,6 +126,8 @@ proc_t *proc_create() {
|
|||||||
SPINLOCK_INIT(proc->threadlistlock);
|
SPINLOCK_INIT(proc->threadlistlock);
|
||||||
EVENT_INITHEADER(&proc->child_exit_event);
|
EVENT_INITHEADER(&proc->child_exit_event);
|
||||||
EVENT_INITHEADER(&proc->thread_exit_event);
|
EVENT_INITHEADER(&proc->thread_exit_event);
|
||||||
|
SPINLOCK_INIT(proc->runtime_lock);
|
||||||
|
memset(&proc->total_runtime, 0, sizeof(proc->total_runtime));
|
||||||
|
|
||||||
proc->fd = alloc(sizeof(fd_t) * 3);
|
proc->fd = alloc(sizeof(fd_t) * 3);
|
||||||
if (proc->fd == NULL) {
|
if (proc->fd == NULL) {
|
||||||
@@ -311,7 +331,8 @@ void proc_exit(void) {
|
|||||||
EVENT_SIGNAL(&proc->parent->child_exit_event);
|
EVENT_SIGNAL(&proc->parent->child_exit_event);
|
||||||
// TODO sigaction flag for this
|
// TODO sigaction flag for this
|
||||||
if (belowzombiecount) {
|
if (belowzombiecount) {
|
||||||
EVENT_SIGNAL(&init_proc->child_exit_event);
|
signal_signalproc(proc->parent, SIGCHLD);
|
||||||
|
EVENT_SIGNAL(&init_proc->child_exit_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +345,17 @@ void proc_run_init() {
|
|||||||
if (init_path == NULL)
|
if (init_path == NULL)
|
||||||
init_path = "/init";
|
init_path = "/init";
|
||||||
|
|
||||||
|
char *last_component = strrchr(init_path, '/');
|
||||||
|
if (last_component) {
|
||||||
|
++last_component;
|
||||||
|
if (*last_component == '\0') {
|
||||||
|
_panic("Bad init path. Do not append a '/' to init=", NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
last_component = init_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *init_console = GET_KERNEL_ARGUMENT(initconsole, char *);
|
char *init_console = GET_KERNEL_ARGUMENT(initconsole, char *);
|
||||||
if (init_console == NULL)
|
if (init_console == NULL)
|
||||||
init_console = "console";
|
init_console = "console";
|
||||||
@@ -341,6 +373,9 @@ void proc_run_init() {
|
|||||||
|
|
||||||
init_proc = proc;
|
init_proc = proc;
|
||||||
|
|
||||||
|
strncpy(proc->name, last_component, sizeof(proc->name));
|
||||||
|
proc->start_time = timekeeper_timefromboot();
|
||||||
|
|
||||||
vnode_t *initnode;
|
vnode_t *initnode;
|
||||||
__assert(vfs_open(vfsroot, init_path, 0, &initnode) == 0);
|
__assert(vfs_open(vfsroot, init_path, 0, &initnode) == 0);
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,14 @@ void sched_thread_running_callback(thread_t *thread) {
|
|||||||
|
|
||||||
void sched_thread_stopping_callback(thread_t *thread, bool sleeping) {
|
void sched_thread_stopping_callback(thread_t *thread, bool sleeping) {
|
||||||
timespec_t now = timekeeper_time();
|
timespec_t now = timekeeper_time();
|
||||||
offset_times(thread, timespec_diffus(thread->metrics.run_start, now), 0);
|
size_t us_diff = timespec_diffus(thread->metrics.run_start, now);
|
||||||
|
offset_times(thread, us_diff, 0);
|
||||||
|
|
||||||
|
if (thread->proc) {
|
||||||
|
spinlock_acquire(&thread->proc->runtime_lock);
|
||||||
|
thread->proc->total_runtime = timespec_add(thread->proc->total_runtime, timespec_from_us(us_diff));
|
||||||
|
spinlock_release(&thread->proc->runtime_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (sleeping)
|
if (sleeping)
|
||||||
thread->metrics.sleep_start = now;
|
thread->metrics.sleep_start = now;
|
||||||
|
|||||||
@@ -51,6 +51,18 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *last_component = strrchr(path, '/');
|
||||||
|
if (last_component) {
|
||||||
|
++last_component;
|
||||||
|
if (*last_component == '\0') {
|
||||||
|
ret.errno = EISDIR;
|
||||||
|
free(path);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
last_component = path;
|
||||||
|
}
|
||||||
|
|
||||||
size_t argsize = 0;
|
size_t argsize = 0;
|
||||||
size_t envsize = 0;
|
size_t envsize = 0;
|
||||||
char **argv = NULL;
|
char **argv = NULL;
|
||||||
@@ -315,6 +327,10 @@ static syscallret_t execve(context_t *context, char *upath, char *uargv[], char
|
|||||||
|
|
||||||
cred_doexec(¤t_thread()->proc->cred, suid, sgid);
|
cred_doexec(¤t_thread()->proc->cred, suid, sgid);
|
||||||
|
|
||||||
|
strncpy(current_thread()->proc->name, last_component, sizeof(current_thread()->proc->name));
|
||||||
|
proc->start_time = timekeeper_timefromboot();
|
||||||
|
memset(&proc->total_runtime, 0, sizeof(proc->total_runtime));
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(path);
|
free(path);
|
||||||
if (argv)
|
if (argv)
|
||||||
|
|||||||
@@ -76,10 +76,19 @@ syscallret_t syscall_fork(context_t *ctx) {
|
|||||||
memcpy(&nproc->signals.pending, &proc->signals.pending, sizeof(sigset_t));
|
memcpy(&nproc->signals.pending, &proc->signals.pending, sizeof(sigset_t));
|
||||||
memcpy(&nproc->signals.actions, &proc->signals.actions[0], sizeof(sigaction_t) * NSIG);
|
memcpy(&nproc->signals.actions, &proc->signals.actions[0], sizeof(sigaction_t) * NSIG);
|
||||||
|
|
||||||
|
strncpy(nproc->name, proc->name, sizeof(proc->name));
|
||||||
|
nproc->start_time = proc->start_time;
|
||||||
|
|
||||||
// copy thread scheduling metrics over
|
// copy thread scheduling metrics over
|
||||||
// raised to IPL_DPC to prevent scheduling
|
// raised to IPL_DPC to prevent scheduling
|
||||||
long ipl = interrupt_raiseipl(IPL_DPC);
|
long ipl = interrupt_raiseipl(IPL_DPC);
|
||||||
|
|
||||||
|
spinlock_acquire(&proc->runtime_lock);
|
||||||
|
nproc->total_runtime = proc->total_runtime;
|
||||||
|
spinlock_release(&proc->runtime_lock);
|
||||||
|
|
||||||
memcpy(&nthread->metrics, ¤t_thread()->metrics, sizeof(nthread->metrics));
|
memcpy(&nthread->metrics, ¤t_thread()->metrics, sizeof(nthread->metrics));
|
||||||
|
|
||||||
interrupt_loweripl(ipl);
|
interrupt_loweripl(ipl);
|
||||||
|
|
||||||
ret.ret = nproc->pid;
|
ret.ret = nproc->pid;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include <kernel/syscalls.h>
|
||||||
|
#include <kernel/sysctl.h>
|
||||||
|
#include <arch/mmu.h>
|
||||||
|
|
||||||
|
syscallret_t syscall_sysctl(context_t *, int *namep, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len) {
|
||||||
|
syscallret_t ret = {
|
||||||
|
.ret = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (name_len > SYS_CTL_NAME_MAX) {
|
||||||
|
ret.errno = EINVAL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_USER_ADDRESS(namep) || !IS_USER_ADDRESS(oldp) || !IS_USER_ADDRESS(old_lenp) || !IS_USER_ADDRESS(newp)) {
|
||||||
|
ret.errno = EFAULT;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int name[name_len];
|
||||||
|
ret.errno = usercopy_fromuser(name, namep, sizeof(name));
|
||||||
|
if (ret.errno)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret.errno = sysctl(name, name_len, oldp, old_lenp, newp, new_len);
|
||||||
|
ret.ret = ret.errno ? -1 : 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -411,6 +411,37 @@ index ba9a520..b958ef3 100644
|
|||||||
|
|
||||||
.section .note.GNU-stack,"",%progbits
|
.section .note.GNU-stack,"",%progbits
|
||||||
-
|
-
|
||||||
|
diff --git mlibc-clean/sysdeps/astral/generic/astral.cpp mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
||||||
|
index a86353f..3e1a18c 100644
|
||||||
|
--- mlibc-clean/sysdeps/astral/generic/astral.cpp
|
||||||
|
+++ mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
||||||
|
@@ -1,13 +1,25 @@
|
||||||
|
#include <astral/syscall.h>
|
||||||
|
#include <astral/archctl.h>
|
||||||
|
+#include <astral/sysctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef MLIBC_BUILDING_RTLD
|
||||||
|
|
||||||
|
+int sysctl(const int *name, size_t name_len, void *oldp, size_t *old_lenp, void *newp, size_t new_len) {
|
||||||
|
+ long ret;
|
||||||
|
+ long error = syscall(SYSCALL_SYSCTL, &ret, (uint64_t)name, name_len, (uint64_t)oldp, (uint64_t)old_lenp, (uint64_t)newp, new_len);
|
||||||
|
+ if (error) {
|
||||||
|
+ errno = error;
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int arch_ctl(int func, void *arg) {
|
||||||
|
long ret;
|
||||||
|
long error = syscall(SYSCALL_ARCHCTL, &ret, func, (uint64_t)arg);
|
||||||
|
- if(error)
|
||||||
|
+ if (error)
|
||||||
|
errno = error;
|
||||||
|
return error ? -1 : ret;
|
||||||
|
}
|
||||||
diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||||
index 3b04372..b7a8ab7 100644
|
index 3b04372..b7a8ab7 100644
|
||||||
--- mlibc-clean/sysdeps/astral/generic/generic.cpp
|
--- mlibc-clean/sysdeps/astral/generic/generic.cpp
|
||||||
@@ -942,10 +973,10 @@ index 7e4f2a1..ecc2677 100644
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
index a6c4067..fd38197 100644
|
index a6c4067..160a140 100644
|
||||||
--- mlibc-clean/sysdeps/astral/include/astral/syscall.h
|
--- mlibc-clean/sysdeps/astral/include/astral/syscall.h
|
||||||
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||||
@@ -103,6 +103,12 @@
|
@@ -103,6 +103,13 @@
|
||||||
#define SYSCALL_SYSINFO 96
|
#define SYSCALL_SYSINFO 96
|
||||||
#define SYSCALL_WRITEV 97
|
#define SYSCALL_WRITEV 97
|
||||||
#define SYSCALL_READV 98
|
#define SYSCALL_READV 98
|
||||||
@@ -955,9 +986,72 @@ index a6c4067..fd38197 100644
|
|||||||
+#define SYSCALL_GETSOCKOPT 102
|
+#define SYSCALL_GETSOCKOPT 102
|
||||||
+#define SYSCALL_CLOCK_GETRES 103
|
+#define SYSCALL_CLOCK_GETRES 103
|
||||||
+#define SYSCALL_SETPRIORITY 104
|
+#define SYSCALL_SETPRIORITY 104
|
||||||
|
+#define SYSCALL_SYSCTL 105
|
||||||
|
|
||||||
#ifndef __MLIBC_ABI_ONLY
|
#ifndef __MLIBC_ABI_ONLY
|
||||||
|
|
||||||
|
diff --git mlibc-workdir/sysdeps/astral/include/astral/sysctl.h mlibc-workdir/sysdeps/astral/include/astral/sysctl.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..161f634
|
||||||
|
--- /dev/null
|
||||||
|
+++ mlibc-workdir/sysdeps/astral/include/astral/sysctl.h
|
||||||
|
@@ -0,0 +1,56 @@
|
||||||
|
+#ifndef _ASTRAL_SYSCTL_H
|
||||||
|
+#define _ASTRAL_SYSCTL_H
|
||||||
|
+
|
||||||
|
+#include <bits/size_t.h>
|
||||||
|
+#include <abi-bits/uid_t.h>
|
||||||
|
+#include <abi-bits/gid_t.h>
|
||||||
|
+#include <abi-bits/pid_t.h>
|
||||||
|
+#include <bits/ansi/timespec.h>
|
||||||
|
+
|
||||||
|
+#define SYS_CTL_NAME_MAX 6
|
||||||
|
+
|
||||||
|
+#define SYS_CTL_KERN 1
|
||||||
|
+#define SYS_CTL_KERN_PROC 1
|
||||||
|
+#define SYS_CTL_KERN_PROC_ALL 1
|
||||||
|
+
|
||||||
|
+#define SYS_CTL_KERN_PROC_INFO_NAME_SIZE 64
|
||||||
|
+#define SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE 64
|
||||||
|
+
|
||||||
|
+typedef struct {
|
||||||
|
+ pid_t pid;
|
||||||
|
+ uid_t uid;
|
||||||
|
+ uid_t euid;
|
||||||
|
+ uid_t suid;
|
||||||
|
+ gid_t gid;
|
||||||
|
+ gid_t egid;
|
||||||
|
+ gid_t sgid;
|
||||||
|
+ size_t thread_count;
|
||||||
|
+ char name[SYS_CTL_KERN_PROC_INFO_NAME_SIZE];
|
||||||
|
+ pid_t ppid;
|
||||||
|
+ pid_t pgid;
|
||||||
|
+ pid_t sid;
|
||||||
|
+ struct timespec start_timestamp;
|
||||||
|
+ struct timespec total_runtime;
|
||||||
|
+ int state;
|
||||||
|
+ int cpu_time;
|
||||||
|
+ int nice;
|
||||||
|
+ size_t virtual_pages;
|
||||||
|
+ size_t physical_pages;
|
||||||
|
+ char tty_name[SYS_CTL_KERN_PROC_INFO_TTY_NAME_SIZE];
|
||||||
|
+} sysctl_proc_info_t;
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+extern "C" {
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef __MLIBC_ABI_ONLY
|
||||||
|
+
|
||||||
|
+int sysctl(const int *__name, size_t __name_len, void *__oldp, size_t *__old_lenp, void *__newp, size_t __new_len);
|
||||||
|
+
|
||||||
|
+#endif /* !__MLIBC_ABI_ONLY */
|
||||||
|
+
|
||||||
|
+#ifdef __cplusplus
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* _ASTRAL_SYSCTL_H */
|
||||||
diff --git mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp
|
diff --git mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp mlibc-workdir/sysdeps/astral/include/mlibc/sysdeps.hpp
|
||||||
index ce91084..54ee08e 100644
|
index ce91084..54ee08e 100644
|
||||||
--- mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp
|
--- mlibc-clean/sysdeps/astral/include/mlibc/sysdeps.hpp
|
||||||
@@ -1030,6 +1124,18 @@ index ce91084..54ee08e 100644
|
|||||||
{};
|
{};
|
||||||
|
|
||||||
template<typename Tag>
|
template<typename Tag>
|
||||||
|
diff --git mlibc-clean/sysdeps/astral/meson.build mlibc-workdir/sysdeps/astral/meson.build
|
||||||
|
index 43dd6b0..3e01e87 100644
|
||||||
|
--- mlibc-clean/sysdeps/astral/meson.build
|
||||||
|
+++ mlibc-workdir/sysdeps/astral/meson.build
|
||||||
|
@@ -86,6 +86,7 @@ if not no_headers
|
||||||
|
install_headers(
|
||||||
|
'include/astral/syscall.h',
|
||||||
|
'include/astral/archctl.h',
|
||||||
|
+ 'include/astral/sysctl.h',
|
||||||
|
subdir: 'astral',
|
||||||
|
follow_symlinks: true,
|
||||||
|
)
|
||||||
diff --git mlibc-clean/sysdeps/linux/generic/sysdeps.cpp mlibc-workdir/sysdeps/linux/generic/sysdeps.cpp
|
diff --git mlibc-clean/sysdeps/linux/generic/sysdeps.cpp mlibc-workdir/sysdeps/linux/generic/sysdeps.cpp
|
||||||
index a07ed53..1474470 100644
|
index a07ed53..1474470 100644
|
||||||
--- mlibc-clean/sysdeps/linux/generic/sysdeps.cpp
|
--- mlibc-clean/sysdeps/linux/generic/sysdeps.cpp
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
name=mlibc
|
name=mlibc
|
||||||
from_source=mlibc
|
from_source=mlibc
|
||||||
revision=6
|
revision=7
|
||||||
hostdeps="xgcc xbinutils pkgconfig"
|
hostdeps="xgcc xbinutils pkgconfig"
|
||||||
builddeps="freestnd-c-hdrs freestnd-cxx-hdrs frigg libsmarter"
|
builddeps="freestnd-c-hdrs freestnd-cxx-hdrs frigg libsmarter"
|
||||||
imagedeps="meson ninja-build git build-essential binutils"
|
imagedeps="meson ninja-build git build-essential binutils"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name=mlibc-headers
|
name=mlibc-headers
|
||||||
from_source=mlibc
|
from_source=mlibc
|
||||||
revision=1
|
revision=2
|
||||||
imagedeps="ninja-build meson build-essential rsync"
|
imagedeps="ninja-build meson build-essential rsync"
|
||||||
builddeps="linux-headers"
|
builddeps="linux-headers"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user