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 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::{
|
use super::{
|
||||||
sched::__ygg_sched_param_t,
|
sched::__ygg_sched_param_t,
|
||||||
sys_types::{mode_t, pid_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)]
|
#[repr(C)]
|
||||||
pub struct posix_spawnattr_t {}
|
pub struct posix_spawnattr_t {}
|
||||||
@ -21,15 +28,39 @@ pub const POSIX_SPAWN_SETSIGMASK: c_int = 1 << 6;
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn posix_spawn(
|
unsafe extern "C" fn posix_spawn(
|
||||||
_pid: *mut pid_t,
|
pid: *mut pid_t,
|
||||||
path: *const c_char,
|
path: *const c_char,
|
||||||
_file_actions: *const posix_spawn_file_actions_t,
|
_file_actions: *const posix_spawn_file_actions_t,
|
||||||
_attrp: *const posix_spawnattr_t,
|
_attrp: *const posix_spawnattr_t,
|
||||||
_argv: *const *mut c_char,
|
argv: *const *mut c_char,
|
||||||
_envp: *const *mut c_char,
|
_envp: *const *mut c_char,
|
||||||
) -> c_int {
|
) -> CIntZeroResult {
|
||||||
let path = path.ensure_str();
|
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]
|
#[no_mangle]
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
use core::ffi::{c_char, c_int, c_long};
|
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;
|
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]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn ftruncate(fd: c_int, size: off_t) -> c_int {
|
unsafe extern "C" fn ftruncate(fd: c_int, size: off_t) -> CIntZeroResult {
|
||||||
todo!()
|
let mut file = RawFile::e_try_from(fd)?;
|
||||||
|
let size: u64 = size.try_into().unwrap();
|
||||||
|
file.truncate(size)?;
|
||||||
|
CIntZeroResult::SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -45,7 +45,7 @@ unsafe extern "C" fn fsync(fd: c_int) -> CIntZeroResult {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn isatty(fd: c_int) -> c_int {
|
unsafe extern "C" fn isatty(fd: c_int) -> c_int {
|
||||||
log::error!("TODO: isatty()");
|
log::error!("TODO: isatty()");
|
||||||
1
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -46,7 +46,7 @@ unsafe extern "C" fn swab(from: *const c_void, to: *mut c_void, n: isize) {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn sysconf(name: Sysconf) -> c_long {
|
unsafe extern "C" fn sysconf(name: Sysconf) -> c_long {
|
||||||
match name {
|
match name {
|
||||||
Sysconf::_SC_ARG_MAX => 256,
|
Sysconf::_SC_ARG_MAX => 4096,
|
||||||
Sysconf::_SC_PAGE_SIZE => 0x1000,
|
Sysconf::_SC_PAGE_SIZE => 0x1000,
|
||||||
_ => todo!("{name:?}"),
|
_ => todo!("{name:?}"),
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,11 @@ impl RawFile {
|
|||||||
EResult::Ok(())
|
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> {
|
pub fn duplicate(&self, new: Option<RawFd>) -> EResult<Self> {
|
||||||
let fd = unsafe { syscall::clone_fd(self.0, new) }?;
|
let fd = unsafe { syscall::clone_fd(self.0, new) }?;
|
||||||
EResult::Ok(Self(fd))
|
EResult::Ok(Self(fd))
|
||||||
|
@ -12,6 +12,54 @@ use crate::{
|
|||||||
headers::{errno::Errno, fcntl::AT_FDCWD},
|
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 {
|
pub trait PointerExt {
|
||||||
unsafe fn ensure(self: *const Self) -> &'static Self;
|
unsafe fn ensure(self: *const Self) -> &'static Self;
|
||||||
unsafe fn ensure_mut(self: *mut Self) -> &'static mut Self;
|
unsafe fn ensure_mut(self: *mut Self) -> &'static mut Self;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user