libc: implement posix_spawn()/truncate()
This commit is contained in:
parent
5d5379ac8a
commit
6abea7ef22
4
userspace/etc/test.sh
Executable file
4
userspace/etc/test.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
/mnt/bin/clang -cc1as -filetype obj -main-file-name test.S -target-cpu x86-64 -mrelocation-model pic -triple x86_64-unknown-yggdrasil -o /test.o /etc/test.S
|
||||
/bin/ls -lh /
|
@ -1,10 +1,17 @@
|
||||
use core::ffi::{c_char, c_int, c_short, c_void};
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use yggdrasil_rt::{io::RawFd, process::{SpawnFlags, SpawnOption, SpawnOptions}, sys as syscall};
|
||||
|
||||
use super::{
|
||||
sched::__ygg_sched_param_t,
|
||||
sys_types::{mode_t, pid_t},
|
||||
};
|
||||
use crate::util::PointerStrExt;
|
||||
use crate::{
|
||||
error::{CIntCountResult, CIntZeroResult, ResultExt},
|
||||
headers::errno::Errno,
|
||||
util::{NullTerminatedArrayIter, PointerStrExt},
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct posix_spawnattr_t {}
|
||||
@ -21,15 +28,39 @@ pub const POSIX_SPAWN_SETSIGMASK: c_int = 1 << 6;
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn posix_spawn(
|
||||
_pid: *mut pid_t,
|
||||
pid: *mut pid_t,
|
||||
path: *const c_char,
|
||||
_file_actions: *const posix_spawn_file_actions_t,
|
||||
_attrp: *const posix_spawnattr_t,
|
||||
_argv: *const *mut c_char,
|
||||
argv: *const *mut c_char,
|
||||
_envp: *const *mut c_char,
|
||||
) -> c_int {
|
||||
) -> CIntZeroResult {
|
||||
let path = path.ensure_str();
|
||||
todo!("TODO: posix_spawn({path:?})")
|
||||
let argv = NullTerminatedArrayIter::new(argv);
|
||||
let args = argv
|
||||
.map(|arg| arg.cast_const().ensure_str())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
log::info!("posix_spawn({path:?}, {args:?})");
|
||||
|
||||
let options = SpawnOptions {
|
||||
program: path,
|
||||
arguments: &args,
|
||||
environment: &[],
|
||||
directory: None,
|
||||
optional: &[
|
||||
SpawnOption::CopyFile { source: RawFd::STDIN, child: RawFd::STDIN },
|
||||
SpawnOption::CopyFile { source: RawFd::STDOUT, child: RawFd::STDOUT },
|
||||
SpawnOption::CopyFile { source: RawFd::STDERR, child: RawFd::STDERR },
|
||||
],
|
||||
flags: SpawnFlags::empty(),
|
||||
};
|
||||
let id = syscall::spawn_process(&options).e_map_err(Errno::from)?;
|
||||
if let Some(pid) = pid.as_mut() {
|
||||
*pid = id.bits() as i32;
|
||||
}
|
||||
|
||||
CIntZeroResult::SUCCESS
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -1,6 +1,14 @@
|
||||
use core::ffi::{c_char, c_int, c_long};
|
||||
|
||||
use crate::{error::CIntZeroResult, headers::{fcntl::{faccessat, AT_FDCWD}, sys_types::{gid_t, off_t, uid_t}}, util::PointerExt};
|
||||
use crate::{
|
||||
error::{CIntZeroResult, TryFromExt},
|
||||
headers::{
|
||||
fcntl::{faccessat, AT_FDCWD},
|
||||
sys_types::{gid_t, off_t, uid_t},
|
||||
},
|
||||
io::{raw::RawFile, FromRawFd},
|
||||
util::PointerExt,
|
||||
};
|
||||
|
||||
pub const _PC_PATH_MAX: c_int = 0;
|
||||
|
||||
@ -40,8 +48,11 @@ unsafe extern "C" fn fpathconf(fd: c_int, name: c_int) -> c_long {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn ftruncate(fd: c_int, size: off_t) -> c_int {
|
||||
todo!()
|
||||
unsafe extern "C" fn ftruncate(fd: c_int, size: off_t) -> CIntZeroResult {
|
||||
let mut file = RawFile::e_try_from(fd)?;
|
||||
let size: u64 = size.try_into().unwrap();
|
||||
file.truncate(size)?;
|
||||
CIntZeroResult::SUCCESS
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -45,7 +45,7 @@ unsafe extern "C" fn fsync(fd: c_int) -> CIntZeroResult {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn isatty(fd: c_int) -> c_int {
|
||||
log::error!("TODO: isatty()");
|
||||
1
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -46,7 +46,7 @@ unsafe extern "C" fn swab(from: *const c_void, to: *mut c_void, n: isize) {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn sysconf(name: Sysconf) -> c_long {
|
||||
match name {
|
||||
Sysconf::_SC_ARG_MAX => 256,
|
||||
Sysconf::_SC_ARG_MAX => 4096,
|
||||
Sysconf::_SC_PAGE_SIZE => 0x1000,
|
||||
_ => todo!("{name:?}"),
|
||||
}
|
||||
|
@ -29,6 +29,11 @@ impl RawFile {
|
||||
EResult::Ok(())
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, size: u64) -> EResult<()> {
|
||||
unsafe { syscall::truncate(self.0, size) }?;
|
||||
EResult::Ok(())
|
||||
}
|
||||
|
||||
pub fn duplicate(&self, new: Option<RawFd>) -> EResult<Self> {
|
||||
let fd = unsafe { syscall::clone_fd(self.0, new) }?;
|
||||
EResult::Ok(Self(fd))
|
||||
|
@ -12,6 +12,54 @@ use crate::{
|
||||
headers::{errno::Errno, fcntl::AT_FDCWD},
|
||||
};
|
||||
|
||||
pub trait Pointer {
|
||||
type Pointee;
|
||||
|
||||
fn is_null(self) -> bool;
|
||||
}
|
||||
|
||||
impl<T> Pointer for *const T {
|
||||
type Pointee = T;
|
||||
|
||||
fn is_null(self) -> bool {
|
||||
<*const T>::is_null(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Pointer for *mut T {
|
||||
type Pointee = T;
|
||||
|
||||
fn is_null(self) -> bool {
|
||||
<*mut T>::is_null(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NullTerminatedArrayIter<T: Pointer> {
|
||||
pointer: *const T,
|
||||
}
|
||||
|
||||
impl<T: Pointer + Copy> NullTerminatedArrayIter<T> {
|
||||
pub fn new(pointer: *const T) -> Self {
|
||||
Self { pointer }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Pointer + Copy> Iterator for NullTerminatedArrayIter<T> {
|
||||
type Item = T;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.pointer.is_null() {
|
||||
return None;
|
||||
}
|
||||
let current = unsafe { *self.pointer };
|
||||
if current.is_null() {
|
||||
return None;
|
||||
}
|
||||
self.pointer = unsafe { self.pointer.add(1) };
|
||||
Some(current)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PointerExt {
|
||||
unsafe fn ensure(self: *const Self) -> &'static Self;
|
||||
unsafe fn ensure_mut(self: *mut Self) -> &'static mut Self;
|
||||
|
Loading…
x
Reference in New Issue
Block a user