mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 23:26:32 +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 | ✅ |
|
| 130 | rt_sigsuspend | ✅ |
|
||||||
| 131 | sigaltstack | ✅ |
|
| 131 | sigaltstack | ✅ |
|
||||||
| 132 | utime | ✅ |
|
| 132 | utime | ✅ |
|
||||||
| 133 | mknod | ❌ |
|
| 133 | mknod | ✅ |
|
||||||
|
| 132 | utime | ❌ |
|
||||||
|
| 133 | mknod | ✅ |
|
||||||
| 134 | uselib | ❌ |
|
| 134 | uselib | ❌ |
|
||||||
| 135 | personality | ❌ |
|
| 135 | personality | ❌ |
|
||||||
| 136 | ustat | ❌ |
|
| 136 | ustat | ❌ |
|
||||||
@ -279,7 +281,7 @@ provided by Linux on x86-64 architecture.
|
|||||||
| 256 | migrate_pages | ❌ |
|
| 256 | migrate_pages | ❌ |
|
||||||
| 257 | openat | ✅ |
|
| 257 | openat | ✅ |
|
||||||
| 258 | mkdirat | ✅ |
|
| 258 | mkdirat | ✅ |
|
||||||
| 259 | mknodat | ❌ |
|
| 259 | mknodat | ✅ |
|
||||||
| 260 | fchownat | ✅ |
|
| 260 | fchownat | ✅ |
|
||||||
| 261 | futimesat | ✅ |
|
| 261 | futimesat | ✅ |
|
||||||
| 262 | newfstatat | ✅ |
|
| 262 | newfstatat | ✅ |
|
||||||
|
@ -47,3 +47,20 @@ pub fn init() -> Result<()> {
|
|||||||
pty::init()?;
|
pty::init()?;
|
||||||
Ok(())
|
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,
|
lseek::sys_lseek,
|
||||||
madvise::sys_madvise,
|
madvise::sys_madvise,
|
||||||
mkdir::{sys_mkdir, sys_mkdirat},
|
mkdir::{sys_mkdir, sys_mkdirat},
|
||||||
|
mknod::{sys_mknod, sys_mknodat},
|
||||||
mmap::sys_mmap,
|
mmap::sys_mmap,
|
||||||
mount::sys_mount,
|
mount::sys_mount,
|
||||||
mprotect::sys_mprotect,
|
mprotect::sys_mprotect,
|
||||||
@ -236,6 +237,7 @@ impl_syscall_nums_and_dispatch_fn! {
|
|||||||
SYS_RT_SIGSUSPEND = 130 => sys_rt_sigsuspend(args[..2]);
|
SYS_RT_SIGSUSPEND = 130 => sys_rt_sigsuspend(args[..2]);
|
||||||
SYS_SIGALTSTACK = 131 => sys_sigaltstack(args[..2]);
|
SYS_SIGALTSTACK = 131 => sys_sigaltstack(args[..2]);
|
||||||
SYS_UTIME = 132 => sys_utime(args[..2]);
|
SYS_UTIME = 132 => sys_utime(args[..2]);
|
||||||
|
SYS_MKNOD = 133 => sys_mknod(args[..3]);
|
||||||
SYS_STATFS = 137 => sys_statfs(args[..2]);
|
SYS_STATFS = 137 => sys_statfs(args[..2]);
|
||||||
SYS_FSTATFS = 138 => sys_fstatfs(args[..2]);
|
SYS_FSTATFS = 138 => sys_fstatfs(args[..2]);
|
||||||
SYS_GET_PRIORITY = 140 => sys_get_priority(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_WAITID = 247 => sys_waitid(args[..5]);
|
||||||
SYS_OPENAT = 257 => sys_openat(args[..4]);
|
SYS_OPENAT = 257 => sys_openat(args[..4]);
|
||||||
SYS_MKDIRAT = 258 => sys_mkdirat(args[..3]);
|
SYS_MKDIRAT = 258 => sys_mkdirat(args[..3]);
|
||||||
|
SYS_MKNODAT = 259 => sys_mknodat(args[..4]);
|
||||||
SYS_FCHOWNAT = 260 => sys_fchownat(args[..5]);
|
SYS_FCHOWNAT = 260 => sys_fchownat(args[..5]);
|
||||||
SYS_FUTIMESAT = 261 => sys_futimesat(args[..3]);
|
SYS_FUTIMESAT = 261 => sys_futimesat(args[..3]);
|
||||||
SYS_FSTATAT = 262 => sys_fstatat(args[..4]);
|
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 lseek;
|
||||||
mod madvise;
|
mod madvise;
|
||||||
mod mkdir;
|
mod mkdir;
|
||||||
|
mod mknod;
|
||||||
mod mmap;
|
mod mmap;
|
||||||
mod mount;
|
mod mount;
|
||||||
mod mprotect;
|
mod mprotect;
|
||||||
|
@ -77,11 +77,19 @@ pub fn sys_fstatat(
|
|||||||
Ok(SyscallReturn::Return(0))
|
Ok(SyscallReturn::Return(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const S_IFMT: u32 = 0o170000;
|
bitflags! {
|
||||||
pub const S_IFCHR: u32 = 0o020000;
|
/// File type.
|
||||||
pub const S_IFDIR: u32 = 0o040000;
|
pub struct FileTypeFlags: u16 {
|
||||||
pub const S_IFREG: u32 = 0o100000;
|
const S_IFMT = 0o170000; // File type mask.
|
||||||
pub const S_IFLNK: u32 = 0o120000;
|
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
|
/// File Stat
|
||||||
#[derive(Debug, Clone, Copy, Pod, Default)]
|
#[derive(Debug, Clone, Copy, Pod, Default)]
|
||||||
|
@ -20,6 +20,7 @@ TESTS ?= \
|
|||||||
link_test \
|
link_test \
|
||||||
lseek_test \
|
lseek_test \
|
||||||
mkdir_test \
|
mkdir_test \
|
||||||
|
mknod_test \
|
||||||
mmap_test \
|
mmap_test \
|
||||||
mount_test \
|
mount_test \
|
||||||
open_create_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