mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-01-30 09:01:44 -05:00
Implement sys_truncate (#86)
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
| 0x29 (41) | pivot_root | (const char *new_root, const char *put_old) | __arm64_sys_pivot_root | false |
|
||||
| 0x2b (43) | statfs | (const char *pathname, struct statfs *buf) | __arm64_sys_statfs | false |
|
||||
| 0x2c (44) | fstatfs | (unsigned int fd, struct statfs *buf) | __arm64_sys_fstatfs | false |
|
||||
| 0x2d (45) | truncate | (const char *path, long length) | __arm64_sys_truncate | false |
|
||||
| 0x2d (45) | truncate | (const char *path, long length) | __arm64_sys_truncate | true |
|
||||
| 0x2e (46) | ftruncate | (unsigned int fd, off_t length) | __arm64_sys_ftruncate | true |
|
||||
| 0x2f (47) | fallocate | (int fd, int mode, loff_t offset, loff_t len) | __arm64_sys_fallocate | false |
|
||||
| 0x30 (48) | faccessat | (int dfd, const char *filename, int mode) | __arm64_sys_faccessat | true |
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::{
|
||||
splice::sys_sendfile,
|
||||
stat::sys_fstat,
|
||||
sync::sys_sync,
|
||||
trunc::sys_ftruncate,
|
||||
trunc::{sys_ftruncate, sys_truncate},
|
||||
},
|
||||
},
|
||||
kernel::{power::sys_reboot, rand::sys_getrandom, sysinfo::sys_sysinfo, uname::sys_uname},
|
||||
@@ -97,6 +97,7 @@ pub async fn handle_syscall() {
|
||||
0x1d => sys_ioctl(arg1.into(), arg2 as _, arg3 as _).await,
|
||||
0x22 => sys_mkdirat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
||||
0x23 => sys_unlinkat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
||||
0x2d => sys_truncate(TUA::from_value(arg1 as _), arg2 as _).await,
|
||||
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,
|
||||
0x30 => sys_faccessat(arg1.into(), TUA::from_value(arg2 as _), arg3 as _).await,
|
||||
0x31 => sys_chdir(TUA::from_value(arg1 as _)).await,
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
use crate::{process::fd_table::Fd, sched::current_task};
|
||||
use libkernel::error::{KernelError, Result};
|
||||
use core::ffi::c_char;
|
||||
|
||||
use crate::{fs::VFS, memory::uaccess::cstr::UserCStr, process::fd_table::Fd, sched::current_task};
|
||||
use libkernel::{
|
||||
error::{KernelError, Result},
|
||||
fs::{OpenFlags, attr::FilePermissions, path::Path},
|
||||
memory::address::TUA,
|
||||
};
|
||||
|
||||
pub async fn sys_truncate(path: TUA<c_char>, new_size: usize) -> Result<usize> {
|
||||
let mut buf = [0; 1024];
|
||||
|
||||
let task = current_task();
|
||||
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
|
||||
|
||||
let root = task.root.lock_save_irq().0.clone();
|
||||
let file = VFS
|
||||
.open(
|
||||
path,
|
||||
OpenFlags::O_WRONLY,
|
||||
root,
|
||||
FilePermissions::empty(),
|
||||
task,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let (ops, ctx) = &mut *file.lock().await;
|
||||
|
||||
ops.truncate(ctx, new_size).await.map(|_| 0)
|
||||
}
|
||||
|
||||
pub async fn sys_ftruncate(fd: Fd, new_size: usize) -> Result<usize> {
|
||||
let fd = current_task()
|
||||
|
||||
@@ -319,6 +319,59 @@ fn test_futex() {
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn test_truncate() {
|
||||
print!("Testing truncate syscall ...");
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Seek, Write};
|
||||
|
||||
let path = "/tmp/truncate_test.txt";
|
||||
let mut file = File::create_new(path).expect("Failed to create file");
|
||||
file.write_all(b"Hello, world!")
|
||||
.expect("Failed to write to file");
|
||||
unsafe {
|
||||
libc::truncate(std::ffi::CString::new(path).unwrap().as_ptr(), 5);
|
||||
}
|
||||
|
||||
let mut string = String::new();
|
||||
file.rewind().expect("Failed to rewind file");
|
||||
file.read_to_string(&mut string)
|
||||
.expect("Failed to read from file");
|
||||
if string != "Hello" {
|
||||
println!("{string}");
|
||||
panic!("truncate failed");
|
||||
}
|
||||
|
||||
fs::remove_file(path).expect("Failed to delete file");
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn test_ftruncate() {
|
||||
print!("Testing ftruncate syscall ...");
|
||||
let file = "/tmp/ftruncate_test.txt";
|
||||
let c_file = std::ffi::CString::new(file).unwrap();
|
||||
let data = b"Hello, world!";
|
||||
let mut buffer = [1u8; 5];
|
||||
unsafe {
|
||||
let fd = libc::open(c_file.as_ptr(), libc::O_RDWR | libc::O_CREAT, 0o777);
|
||||
let ret = libc::write(fd, data.as_ptr() as *const libc::c_void, data.len());
|
||||
if ret < 0 || ret as usize != data.len() {
|
||||
panic!("write failed");
|
||||
}
|
||||
libc::ftruncate(fd, 5);
|
||||
libc::lseek(fd, 0, libc::SEEK_SET);
|
||||
let ret = libc::read(fd, buffer.as_mut_ptr() as *mut libc::c_void, buffer.len());
|
||||
if ret < 0 || ret as usize != 5 {
|
||||
panic!("read failed");
|
||||
}
|
||||
if &buffer != b"Hello" {
|
||||
panic!("ftruncate failed");
|
||||
}
|
||||
libc::close(fd);
|
||||
}
|
||||
fs::remove_file(file).expect("Failed to delete file");
|
||||
println!(" OK");
|
||||
}
|
||||
|
||||
fn test_rust_file() {
|
||||
print!("Testing rust file operations ...");
|
||||
use std::fs::{self, File};
|
||||
@@ -436,6 +489,8 @@ fn main() {
|
||||
run_test(test_read);
|
||||
run_test(test_write);
|
||||
run_test(test_futex);
|
||||
run_test(test_truncate);
|
||||
run_test(test_ftruncate);
|
||||
run_test(test_rust_file);
|
||||
run_test(test_rust_dir);
|
||||
run_test(test_rust_thread);
|
||||
|
||||
Reference in New Issue
Block a user