mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 13:06:33 +00:00
Add syscall mknod
Signed-off-by: Zhenchen Wang <m202372036@hust.edu.cn>
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0cf954801d
commit
d8389da797
@ -153,7 +153,9 @@ provided by Linux on x86-64 architecture.
|
||||
| 130 | rt_sigsuspend | ✅ |
|
||||
| 131 | sigaltstack | ✅ |
|
||||
| 132 | utime | ✅ |
|
||||
| 133 | mknod | ❌ |
|
||||
| 133 | mknod | ✅ |
|
||||
| 132 | utime | ❌ |
|
||||
| 133 | mknod | ✅ |
|
||||
| 134 | uselib | ❌ |
|
||||
| 135 | personality | ❌ |
|
||||
| 136 | ustat | ❌ |
|
||||
@ -279,7 +281,7 @@ provided by Linux on x86-64 architecture.
|
||||
| 256 | migrate_pages | ❌ |
|
||||
| 257 | openat | ✅ |
|
||||
| 258 | mkdirat | ✅ |
|
||||
| 259 | mknodat | ❌ |
|
||||
| 259 | mknodat | ✅ |
|
||||
| 260 | fchownat | ✅ |
|
||||
| 261 | futimesat | ✅ |
|
||||
| 262 | newfstatat | ✅ |
|
||||
|
@ -47,3 +47,20 @@ pub fn init() -> Result<()> {
|
||||
pty::init()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_device(dev: usize) -> Result<Arc<dyn Device>> {
|
||||
if dev == 0 {
|
||||
return_errno_with_message!(Errno::EPERM, "whiteout device")
|
||||
}
|
||||
let major = ((dev >> 32) & 0xffff_f000 | (dev >> 8) & 0x0000_0fff) as u32;
|
||||
let minor = ((dev >> 12) & 0xffff_ff00 | dev & 0x0000_00ff) as u32;
|
||||
|
||||
match (major, minor) {
|
||||
(1, 3) => Ok(Arc::new(null::Null)),
|
||||
(1, 5) => Ok(Arc::new(zero::Zero)),
|
||||
(5, 0) => Ok(Arc::new(tty::TtyDevice)),
|
||||
(1, 8) => Ok(Arc::new(random::Random)),
|
||||
(1, 9) => Ok(Arc::new(urandom::Urandom)),
|
||||
_ => return_errno_with_message!(Errno::EINVAL, "unsupported device"),
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ use crate::syscall::{
|
||||
lseek::sys_lseek,
|
||||
madvise::sys_madvise,
|
||||
mkdir::{sys_mkdir, sys_mkdirat},
|
||||
mknod::{sys_mknod, sys_mknodat},
|
||||
mmap::sys_mmap,
|
||||
mount::sys_mount,
|
||||
mprotect::sys_mprotect,
|
||||
@ -236,6 +237,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
||||
SYS_RT_SIGSUSPEND = 130 => sys_rt_sigsuspend(args[..2]);
|
||||
SYS_SIGALTSTACK = 131 => sys_sigaltstack(args[..2]);
|
||||
SYS_UTIME = 132 => sys_utime(args[..2]);
|
||||
SYS_MKNOD = 133 => sys_mknod(args[..3]);
|
||||
SYS_STATFS = 137 => sys_statfs(args[..2]);
|
||||
SYS_FSTATFS = 138 => sys_fstatfs(args[..2]);
|
||||
SYS_GET_PRIORITY = 140 => sys_get_priority(args[..2]);
|
||||
@ -267,6 +269,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
||||
SYS_WAITID = 247 => sys_waitid(args[..5]);
|
||||
SYS_OPENAT = 257 => sys_openat(args[..4]);
|
||||
SYS_MKDIRAT = 258 => sys_mkdirat(args[..3]);
|
||||
SYS_MKNODAT = 259 => sys_mknodat(args[..4]);
|
||||
SYS_FCHOWNAT = 260 => sys_fchownat(args[..5]);
|
||||
SYS_FUTIMESAT = 261 => sys_futimesat(args[..3]);
|
||||
SYS_FSTATAT = 262 => sys_fstatat(args[..4]);
|
||||
|
62
kernel/aster-nix/src/syscall/mknod.rs
Normal file
62
kernel/aster-nix/src/syscall/mknod.rs
Normal file
@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
use super::SyscallReturn;
|
||||
use crate::{
|
||||
device::get_device,
|
||||
fs::{
|
||||
file_table::FileDesc,
|
||||
fs_resolver::{FsPath, AT_FDCWD},
|
||||
utils::{InodeMode, InodeType},
|
||||
},
|
||||
prelude::*,
|
||||
syscall::{constants::MAX_FILENAME_LEN, stat::FileTypeFlags},
|
||||
util::read_cstring_from_user,
|
||||
};
|
||||
|
||||
pub fn sys_mknodat(
|
||||
dirfd: FileDesc,
|
||||
path_addr: Vaddr,
|
||||
mode: u16,
|
||||
dev: usize,
|
||||
) -> Result<SyscallReturn> {
|
||||
let path = read_cstring_from_user(path_addr, MAX_FILENAME_LEN)?;
|
||||
let current = current!();
|
||||
let inode_mode = {
|
||||
let mask_mode = mode & !current.umask().read().get();
|
||||
InodeMode::from_bits_truncate(mask_mode)
|
||||
};
|
||||
let file_type = FileTypeFlags::from_bits_truncate(mode);
|
||||
debug!(
|
||||
"dirfd = {}, path = {:?}, inode_mode = {:?}, file_type = {:?}, dev = {}",
|
||||
dirfd, path, inode_mode, file_type, dev
|
||||
);
|
||||
|
||||
let (dir_dentry, name) = {
|
||||
let path = path.to_string_lossy();
|
||||
if path.is_empty() {
|
||||
return_errno_with_message!(Errno::ENOENT, "path is empty");
|
||||
}
|
||||
let fs_path = FsPath::new(dirfd, path.as_ref())?;
|
||||
current.fs().read().lookup_dir_and_base_name(&fs_path)?
|
||||
};
|
||||
|
||||
if file_type.contains(FileTypeFlags::S_IFREG) || file_type.is_empty() {
|
||||
let _ = dir_dentry.new_fs_child(name.trim_end_matches('/'), InodeType::File, inode_mode)?;
|
||||
} else if file_type.contains(FileTypeFlags::S_IFCHR)
|
||||
|| file_type.contains(FileTypeFlags::S_IFBLK)
|
||||
{
|
||||
let _ = dir_dentry.mknod(name.trim_end_matches('/'), inode_mode, get_device(dev)?)?;
|
||||
} else if file_type.contains(FileTypeFlags::S_IFIFO)
|
||||
|| file_type.contains(FileTypeFlags::S_IFSOCK)
|
||||
{
|
||||
return_errno_with_message!(Errno::EINVAL, "unsupported file type flag");
|
||||
} else {
|
||||
return_errno_with_message!(Errno::EPERM, "unimplemented types");
|
||||
}
|
||||
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
pub fn sys_mknod(path_addr: Vaddr, mode: u16, dev: usize) -> Result<SyscallReturn> {
|
||||
self::sys_mknodat(AT_FDCWD, path_addr, mode, dev)
|
||||
}
|
@ -62,6 +62,7 @@ mod listen;
|
||||
mod lseek;
|
||||
mod madvise;
|
||||
mod mkdir;
|
||||
mod mknod;
|
||||
mod mmap;
|
||||
mod mount;
|
||||
mod mprotect;
|
||||
|
@ -77,11 +77,19 @@ pub fn sys_fstatat(
|
||||
Ok(SyscallReturn::Return(0))
|
||||
}
|
||||
|
||||
pub const S_IFMT: u32 = 0o170000;
|
||||
pub const S_IFCHR: u32 = 0o020000;
|
||||
pub const S_IFDIR: u32 = 0o040000;
|
||||
pub const S_IFREG: u32 = 0o100000;
|
||||
pub const S_IFLNK: u32 = 0o120000;
|
||||
bitflags! {
|
||||
/// File type.
|
||||
pub struct FileTypeFlags: u16 {
|
||||
const S_IFMT = 0o170000; // File type mask.
|
||||
const S_IFSOCK = 0o140000; // Socket.
|
||||
const S_IFCHR = 0o020000; // Character device.
|
||||
const S_IFBLK = 0o060000; // Block device.
|
||||
const S_IFDIR = 0o040000; // Directory.
|
||||
const S_IFIFO = 0o010000; // FIFO (named pipe).
|
||||
const S_IFREG = 0o100000; // Regular file.
|
||||
const S_IFLNK = 0o120000; // Symbolic link.
|
||||
}
|
||||
}
|
||||
|
||||
/// File Stat
|
||||
#[derive(Debug, Clone, Copy, Pod, Default)]
|
||||
|
@ -20,6 +20,7 @@ TESTS ?= \
|
||||
link_test \
|
||||
lseek_test \
|
||||
mkdir_test \
|
||||
mknod_test \
|
||||
mmap_test \
|
||||
mount_test \
|
||||
open_create_test \
|
||||
|
1
test/syscall_test/blocklists.exfat/mknod_test
Normal file
1
test/syscall_test/blocklists.exfat/mknod_test
Normal file
@ -0,0 +1 @@
|
||||
MknodTest.RegularFilePermissions
|
6
test/syscall_test/blocklists/mknod_test
Normal file
6
test/syscall_test/blocklists/mknod_test
Normal file
@ -0,0 +1,6 @@
|
||||
MknodTest.MknodAtFIFO
|
||||
MknodTest.MknodOnExistingPathFails
|
||||
MknodTest.Socket
|
||||
MknodTest.Fifo
|
||||
MknodTest.FifoOtrunc
|
||||
MknodTest.FifoTruncNoOp
|
Reference in New Issue
Block a user