Files
zinnia/syscalls/uname.c
T
2026-10-06 01:34:24 +02:00

66 lines
1.7 KiB
C

#include <zinnia/spin.h>
#include <zinnia/string.h>
#include <zinnia/syscall.h>
#include <zinnia/usercopy.h>
#include <config.h>
#include <uapi/utsname.h>
static struct spinlock uname_lock = {};
static struct __utsname uname_buf = {
.sysname = "Zinnia",
.release = ZINNIA_VERSION,
.version = CONFIG_KERNEL_FLAVOR,
.nodename = "localhost",
.machine = ZINNIA_ARCH,
.domainname = "(none)",
};
struct syscall_ret sys_setuname(const __user struct __utsname* ptr) {
struct syscall_ret ret = {};
if (!ptr) {
ret.error = EINVAL;
return ret;
}
// TODO: User has to be root to do this.
struct __utsname read_buf;
if (!usercopy_read(&read_buf, ptr, sizeof(read_buf))) {
ret.error = EFAULT;
return ret;
}
spin_lock(&uname_lock);
strncpy(uname_buf.sysname, read_buf.sysname, sizeof(uname_buf.sysname) - 1);
strncpy(uname_buf.release, read_buf.release, sizeof(uname_buf.release) - 1);
strncpy(uname_buf.version, read_buf.version, sizeof(uname_buf.version) - 1);
strncpy(uname_buf.nodename, read_buf.nodename, sizeof(uname_buf.nodename) - 1);
strncpy(uname_buf.machine, read_buf.machine, sizeof(uname_buf.machine) - 1);
strncpy(uname_buf.domainname, read_buf.domainname, sizeof(uname_buf.domainname) - 1);
spin_unlock(&uname_lock);
return ret;
}
struct syscall_ret sys_getuname(__user struct __utsname* ptr) {
struct syscall_ret ret = {};
if (!ptr) {
ret.error = EINVAL;
return ret;
}
spin_lock(&uname_lock);
struct __utsname write_buf = uname_buf;
spin_unlock(&uname_lock);
if (!usercopy_write(ptr, &write_buf, sizeof(write_buf)))
ret.error = EFAULT;
return ret;
}