孙浩宇 closed issue #10: 实现 umask syscall at NameNotFound / OSKernel2026-NameNot...

孙浩宇
2026-04-05T12:37:33Z

背景

umask 设置进程的文件创建掩码，决定新建文件/目录时默认去掉哪些权限位。目前是 stub，硬编码返回 0o777：

// kernel/src/syscall/mod.rs:382
SYS_UMASK => self.unimplemented("umask", Ok(0o777)),

很多程序（shell、busybox）在初始化时会调用 umask(022) 来设置合理的默认权限。

目标

让 umask syscall 真正存储掩码值，并返回旧值。

umask 语义

mode_t umask(mode_t mask);

将进程的文件创建掩码设置为 mask & 0o777

返回旧的掩码值

这个 syscall 永远不会失败

实现指引

1. 在 Process 结构体中添加字段

文件：kernel/src/process/proc.rs

pub struct Process {
// ... 已有字段 ...
/// 文件创建掩码
pub umask: u32,
}

初始化为 0o022（Linux 默认值）。

2. 实现 syscall

在 kernel/src/syscall/proc.rs（或 misc.rs，看你觉得哪里更合适）中添加：

pub fn sys_umask(&self, mask: usize) -> SysResult {
info!("umask: mask={:#o}", mask);
let mut proc = self.process();
let old = proc.umask;
proc.umask = (mask as u32) & 0o777;
Ok(old as usize)
}

3. 在 syscall 分发表中注册

将 kernel/src/syscall/mod.rs 中的：

SYS_UMASK => self.unimplemented("umask", Ok(0o777)),

改为：

SYS_UMASK => self.sys_umask(args[0]),

4. fork 时继承

子进程应继承父进程的 umask 值。

涉及的 Rust 知识

结构体字段

位运算（&）

八进制字面量（0o022）

方法定义

难度

⭐ 入门级 — 改动非常小（~15 行），适合作为第一个 PR

验证方式

程序调用 umask(022) 后应返回旧值而不是固定的 0o777，且不再打印 warning 日志。

后续（可选）

如果想进一步，可以在文件创建路径（sys_openat 等）中应用 umask 掩码来过滤权限位。