64 lines
1.5 KiB
C
64 lines
1.5 KiB
C
#include <zinnia/spin.h>
|
|
#include <zinnia/syscall.h>
|
|
#include <zinnia/usercopy.h>
|
|
#include <config.h>
|
|
#include <zinnia/string.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,
|
|
};
|
|
|
|
struct syscall_ret sys_setuname(__user const struct __utsname* ptr) {
|
|
struct syscall_ret ret = {};
|
|
|
|
if (!ptr) {
|
|
ret.errno = 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.errno = EFAULT;
|
|
return ret;
|
|
}
|
|
|
|
spin_lock(&uname_lock);
|
|
|
|
strncpy(uname_buf.sysname, read_buf.sysname, sizeof(uname_buf.sysname));
|
|
strncpy(uname_buf.release, read_buf.release, sizeof(uname_buf.release));
|
|
strncpy(uname_buf.version, read_buf.version, sizeof(uname_buf.version));
|
|
strncpy(uname_buf.nodename, read_buf.nodename, sizeof(uname_buf.nodename));
|
|
strncpy(uname_buf.machine, read_buf.machine, sizeof(uname_buf.machine));
|
|
|
|
spin_unlock(&uname_lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
struct syscall_ret sys_getuname(__user struct __utsname* ptr) {
|
|
struct syscall_ret ret = {};
|
|
|
|
if (!ptr) {
|
|
ret.errno = EINVAL;
|
|
return ret;
|
|
}
|
|
|
|
spin_lock(&uname_lock);
|
|
|
|
if (!usercopy_write(ptr, &uname_buf, sizeof(uname_buf)))
|
|
ret.errno = EFAULT;
|
|
|
|
spin_unlock(&uname_lock);
|
|
|
|
return ret;
|
|
}
|