Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions litebox_common_linux/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ bitflags::bitflags! {
}

#[repr(u32)]
#[derive(IntEnum)]
pub enum InodeType {
/// FIFO (named pipe)
NamedPipe = 0o010000,
Expand Down Expand Up @@ -2136,6 +2137,12 @@ pub enum SyscallRequest<Platform: litebox::platform::RawPointerProvider> {
fd: i32,
length: usize,
},
Mknodat {
dirfd: i32,
pathname: Platform::RawConstPointer<i8>,
mode_and_type: u32,
dev: u32,
},
Unlinkat {
dirfd: i32,
pathname: Platform::RawConstPointer<i8>,
Expand Down Expand Up @@ -2723,6 +2730,13 @@ impl<Platform: litebox::platform::RawPointerProvider> SyscallRequest<Platform> {
mode: ctx.sys_req_arg(2),
}
}
Sysno::mknodat => sys_req!(Mknodat { dirfd,pathname:*,mode_and_type,dev }),
Sysno::mknod => SyscallRequest::Mknodat {
dirfd: AT_FDCWD,
pathname: ctx.sys_req_ptr(0),
mode_and_type: ctx.sys_req_arg(1),
dev: ctx.sys_req_arg(2),
},
Sysno::unlinkat => sys_req!(Unlinkat { dirfd,pathname:*,flags }),
Sysno::unlink => {
// unlink is equivalent to unlinkat with dirfd AT_FDCWD and flags 0
Expand Down
8 changes: 8 additions & 0 deletions litebox_shim_linux/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,14 @@ impl<FS: ShimFS> Task<FS> {
syscall!(sys_openat(dirfd, path, flags, mode))
}),
SyscallRequest::Ftruncate { fd, length } => syscall!(sys_ftruncate(fd, length)),
SyscallRequest::Mknodat {
dirfd,
pathname,
mode_and_type,
dev,
} => pathname.to_cstring().map_or(Err(Errno::EFAULT), |path| {
syscall!(sys_mknodat(dirfd, path, mode_and_type, dev))
}),
SyscallRequest::Unlinkat {
dirfd,
pathname,
Expand Down
43 changes: 41 additions & 2 deletions litebox_shim_linux/src/syscalls/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use litebox::{
utils::{ReinterpretSignedExt as _, ReinterpretUnsignedExt as _, TruncateExt as _},
};
use litebox_common_linux::{
AtFlags, EfdFlags, EpollCreateFlags, FcntlArg, FileDescriptorFlags, FileStat, IoReadVec,
IoWriteVec, IoctlArg, TimeParam, errno::Errno,
AtFlags, EfdFlags, EpollCreateFlags, FcntlArg, FileDescriptorFlags, FileStat, InodeType,
IoReadVec, IoWriteVec, IoctlArg, TimeParam, errno::Errno,
};
use litebox_platform_multiplex::Platform;

Expand Down Expand Up @@ -258,6 +258,45 @@ impl<FS: ShimFS> Task<FS> {
.flatten()
}

/// Handle syscall `mknodat` — create a filesystem node.
pub(crate) fn sys_mknodat(
&self,
dirfd: i32,
pathname: impl path::Arg,
mode_and_type: u32,
_dev: u32,
) -> Result<(), Errno> {
const FILE_TYPE_MASK: u32 = 0o170000;

let file_type = mode_and_type & FILE_TYPE_MASK;
let file_type = if file_type == 0 {
// zero translates to S_IFREG
InodeType::File
} else {
InodeType::try_from(file_type).map_err(|_| Errno::EINVAL)?
};
match file_type {
InodeType::File => {
let mode = Mode::from_bits_truncate(mode_and_type & !FILE_TYPE_MASK);
let fd = self.sys_openat(
dirfd,
pathname,
OFlags::CREAT | OFlags::EXCL | OFlags::WRONLY,
mode,
)?;
self.sys_close(fd.cast_signed())?;
}
// TODO: Named pipe, socket, block and char files are not supported
InodeType::NamedPipe
| InodeType::Socket
| InodeType::BlockDevice
| InodeType::CharDevice
| InodeType::Dir => return Err(Errno::EPERM),
InodeType::SymLink => return Err(Errno::EINVAL),
}
Ok(())
}

/// Handle syscall `unlinkat`
pub(crate) fn sys_unlinkat(
&self,
Expand Down
Loading