implement hostname properly

This commit is contained in:
Ashwin Naren
2026-02-07 15:35:47 -08:00
parent 157c29104f
commit c07dd2140c
6 changed files with 66 additions and 4 deletions

View File

@@ -161,7 +161,7 @@
| 0x9e (158) | getgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_getgroups | false |
| 0x9f (159) | setgroups | (int gidsetsize, gid_t *grouplist) | __arm64_sys_setgroups | false |
| 0xa0 (160) | newuname | (struct new_utsname *name) | __arm64_sys_newuname | true |
| 0xa1 (161) | sethostname | (char *name, int len) | __arm64_sys_sethostname | false |
| 0xa1 (161) | sethostname | (char *name, int len) | __arm64_sys_sethostname | true |
| 0xa2 (162) | setdomainname | (char *name, int len) | __arm64_sys_setdomainname | false |
| 0xa3 (163) | getrlimit | (unsigned int resource, struct rlimit *rlim) | __arm64_sys_getrlimit | dummy |
| 0xa4 (164) | setrlimit | (unsigned int resource, struct rlimit *rlim) | __arm64_sys_setrlimit | false |

View File

@@ -195,6 +195,9 @@ pub enum KernelError {
#[error("Interrupted system call")]
Interrupted,
#[error("Name too long")]
NameTooLong,
#[error("{0}")]
Other(&'static str),
}

View File

@@ -42,7 +42,10 @@ use crate::{
trunc::{sys_ftruncate, sys_truncate},
},
},
kernel::{power::sys_reboot, rand::sys_getrandom, sysinfo::sys_sysinfo, uname::sys_uname},
kernel::{
hostname::sys_sethostname, power::sys_reboot, rand::sys_getrandom, sysinfo::sys_sysinfo,
uname::sys_uname,
},
memory::{
brk::sys_brk,
mincore::sys_mincore,
@@ -488,6 +491,7 @@ pub async fn handle_syscall() {
0x9c => sys_getsid().await,
0x9d => sys_setsid().await,
0xa0 => sys_uname(TUA::from_value(arg1 as _)).await,
0xa1 => sys_sethostname(TUA::from_value(arg1 as _), arg2 as _).await,
0xa3 => Err(KernelError::InvalidValue),
0xa6 => sys_umask(arg1 as _).map_err(|e| match e {}),
0xa7 => sys_prctl(arg1 as _, arg2, arg3).await,

49
src/kernel/hostname.rs Normal file
View File

@@ -0,0 +1,49 @@
use crate::memory::uaccess::copy_from_user_slice;
use crate::sched::current::current_task_shared;
use crate::sync::OnceLock;
use crate::sync::SpinLock;
use alloc::string::String;
use alloc::vec;
use core::ffi::c_char;
use libkernel::error::{KernelError, Result};
use libkernel::memory::address::TUA;
use libkernel::proc::caps::CapabilitiesFlags;
static HOSTNAME: OnceLock<SpinLock<String>> = OnceLock::new();
pub fn hostname() -> &'static SpinLock<String> {
HOSTNAME.get_or_init(|| SpinLock::new(String::from("moss-machine")))
}
const HOST_NAME_MAX: usize = 64;
pub async fn sys_sethostname(name_ptr: TUA<c_char>, name_len: usize) -> Result<usize> {
{
let task = current_task_shared();
let creds = task.creds.lock_save_irq();
creds
.caps()
.check_capable(CapabilitiesFlags::CAP_SYS_ADMIN)?;
}
if name_len > HOST_NAME_MAX {
return Err(KernelError::NameTooLong);
}
let mut buf = vec![0u8; name_len];
copy_from_user_slice(name_ptr.to_untyped(), &mut buf).await?;
let name = String::from_utf8(buf).map_err(|_| KernelError::InvalidValue)?;
*hostname().lock_save_irq() = name;
Ok(0)
}
// pub async fn sys_gethostname(name_ptr: TUA<c_char>, name_len: usize) -> Result<usize> {
// let hostname = hostname().lock_save_irq();
// let bytes = hostname.as_bytes();
// let len = core::cmp::min(bytes.len(), name_len);
// copy_to_user_slice(&bytes[..len], name_ptr.to_untyped()).await?;
// // Null-terminate if there's space
// if name_len > len {
// copy_to_user(name_ptr.add_bytes(len), 0u8).await?;
// }
// Ok(0)
// }

View File

@@ -1,4 +1,5 @@
pub mod cpu_id;
pub mod hostname;
pub mod kpipe;
pub mod power;
pub mod rand;

View File

@@ -1,8 +1,10 @@
use crate::kernel::hostname::hostname;
use crate::{
arch::{Arch, ArchImpl},
memory::uaccess::{UserCopyable, copy_to_user},
};
use alloc::ffi::CString;
use core::str::FromStr;
use core::{ffi::c_char, mem};
use libkernel::{error::Result, memory::address::TUA};
@@ -37,13 +39,16 @@ pub async fn sys_uname(uts_ptr: TUA<OldUtsname>) -> Result<usize> {
let sysname = c"Moss".to_bytes_with_nul();
copy_str_to_c_char_arr(&mut uts.sysname, sysname);
let nodename = c"moss-machine".to_bytes_with_nul();
copy_str_to_c_char_arr(&mut uts.nodename, nodename);
let nodename = CString::from_str(&hostname().lock_save_irq()).unwrap();
copy_str_to_c_char_arr(&mut uts.nodename, nodename.as_c_str().to_bytes_with_nul());
let release = c"4.2.3".to_bytes_with_nul();
copy_str_to_c_char_arr(&mut uts.release, release);
#[cfg(feature = "smp")]
let version = c"#1 Moss SMP Tue Feb 20 12:34:56 UTC 2024".to_bytes_with_nul();
#[cfg(not(feature = "smp"))]
let version = c"#1 Moss Tue Feb 20 12:34:56 UTC 2024".to_bytes_with_nul();
copy_str_to_c_char_arr(&mut uts.version, version);
let machine = CString::new(ArchImpl::name()).unwrap();