mirror of
https://github.com/hexagonal-sun/moss-kernel.git
synced 2026-04-18 14:19:01 -04:00
distinguish between file permissions and file mode
This commit is contained in:
@@ -41,6 +41,28 @@ bitflags! {
|
||||
|
||||
const S_ISGID = 0x0400;
|
||||
const S_ISUID = 0x0800;
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct FileMode: u16 {
|
||||
const S_IXOTH = 0x0001;
|
||||
const S_IWOTH = 0x0002;
|
||||
const S_IROTH = 0x0004;
|
||||
|
||||
const S_IXGRP = 0x0008;
|
||||
const S_IWGRP = 0x0010;
|
||||
const S_IRGRP = 0x0020;
|
||||
|
||||
const S_IXUSR = 0x0040;
|
||||
const S_IWUSR = 0x0080;
|
||||
const S_IRUSR = 0x0100;
|
||||
|
||||
const S_ISVTX = 0x0200;
|
||||
|
||||
const S_ISGID = 0x0400;
|
||||
const S_ISUID = 0x0800;
|
||||
|
||||
// Mutually-exclusive file types:
|
||||
const S_IFIFO = 0x1000;
|
||||
@@ -53,6 +75,28 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FileMode> for FilePermissions {
|
||||
fn from(mode: FileMode) -> Self {
|
||||
FilePermissions::from_bits_truncate(mode.bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl FileMode {
|
||||
pub fn new(file_type: FileType, permissions: FilePermissions) -> Self {
|
||||
let mut mode = FileMode::from_bits_truncate(permissions.bits());
|
||||
mode |= match file_type {
|
||||
FileType::Directory => FileMode::S_IFDIR,
|
||||
FileType::File => FileMode::S_IFREG,
|
||||
FileType::Symlink => FileMode::S_IFLNK,
|
||||
FileType::BlockDevice(_) => FileMode::S_IFBLK,
|
||||
FileType::CharDevice(_) => FileMode::S_IFCHR,
|
||||
FileType::Fifo => FileMode::S_IFIFO,
|
||||
FileType::Socket => FileMode::S_IFSOCK,
|
||||
};
|
||||
mode
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents file metadata, similar to `stat`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileAttr {
|
||||
@@ -65,12 +109,18 @@ pub struct FileAttr {
|
||||
pub mtime: Duration, // Modification time
|
||||
pub ctime: Duration, // Change time
|
||||
pub file_type: FileType,
|
||||
pub mode: FilePermissions,
|
||||
pub permissions: FilePermissions,
|
||||
pub nlinks: u32,
|
||||
pub uid: Uid,
|
||||
pub gid: Gid,
|
||||
}
|
||||
|
||||
impl FileAttr {
|
||||
pub fn mode(&self) -> FileMode {
|
||||
FileMode::new(self.file_type, self.permissions)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FileAttr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -83,7 +133,7 @@ impl Default for FileAttr {
|
||||
mtime: Duration::new(0, 0),
|
||||
ctime: Duration::new(0, 0),
|
||||
file_type: FileType::File,
|
||||
mode: FilePermissions::empty(),
|
||||
permissions: FilePermissions::empty(),
|
||||
nlinks: 1,
|
||||
uid: Uid::new_root(),
|
||||
gid: Gid::new_root_group(),
|
||||
@@ -116,7 +166,7 @@ impl FileAttr {
|
||||
if uid.is_root() {
|
||||
if requested_mode.contains(AccessMode::X_OK) {
|
||||
// Root still needs at least one execute bit to be set for X_OK
|
||||
if self.mode.intersects(
|
||||
if self.permissions.intersects(
|
||||
FilePermissions::S_IXUSR | FilePermissions::S_IXGRP | FilePermissions::S_IXOTH,
|
||||
) {
|
||||
return Ok(());
|
||||
@@ -129,13 +179,13 @@ impl FileAttr {
|
||||
// Determine which set of permission bits to use (owner, group, or other)
|
||||
let perms_to_check = if self.uid == uid {
|
||||
// User is the owner
|
||||
self.mode
|
||||
self.permissions
|
||||
} else if self.gid == gid {
|
||||
// User is in the file's group. Shift group bits to align with owner bits for easier checking.
|
||||
FilePermissions::from_bits_truncate(self.mode.bits() << 3)
|
||||
FilePermissions::from_bits_truncate(self.permissions.bits() << 3)
|
||||
} else {
|
||||
// Others. Shift other bits to align with owner bits.
|
||||
FilePermissions::from_bits_truncate(self.mode.bits() << 6)
|
||||
FilePermissions::from_bits_truncate(self.permissions.bits() << 6)
|
||||
};
|
||||
|
||||
if requested_mode.contains(AccessMode::R_OK)
|
||||
@@ -175,11 +225,11 @@ mod tests {
|
||||
const OTHER_UID: Uid = Uid::new(1002);
|
||||
const OTHER_GID: Gid = Gid::new(3000);
|
||||
|
||||
fn setup_file(mode: FilePermissions) -> FileAttr {
|
||||
fn setup_file(permissions: FilePermissions) -> FileAttr {
|
||||
FileAttr {
|
||||
uid: OWNER_UID,
|
||||
gid: FILE_GROUP_GID,
|
||||
mode,
|
||||
permissions,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,8 +96,7 @@ impl From<Metadata> for FileAttr {
|
||||
FileAttr {
|
||||
size: meta.size_in_bytes,
|
||||
file_type: meta.file_type.into(),
|
||||
// Infallible, since they are identical
|
||||
mode: FilePermissions::from_bits(meta.mode.bits()).unwrap(),
|
||||
permissions: FilePermissions::from_bits_truncate(meta.mode.bits()),
|
||||
uid: Uid::new(meta.uid),
|
||||
gid: Gid::new(meta.gid),
|
||||
atime: meta.atime,
|
||||
|
||||
@@ -221,7 +221,7 @@ impl<T: Fat32Operations> Fat32DirStream<T> {
|
||||
let attr = FileAttr {
|
||||
size: dir_entry.size as u64,
|
||||
file_type,
|
||||
mode: FilePermissions::from_bits_retain(0o755),
|
||||
permissions: FilePermissions::from_bits_retain(0o755),
|
||||
atime: fat_date_to_duration(dir_entry.adate),
|
||||
mtime: fat_datetime_to_duration(dir_entry.mdate, dir_entry.mtime, 0),
|
||||
ctime: fat_datetime_to_duration(
|
||||
|
||||
@@ -126,14 +126,14 @@ where
|
||||
G: PageAllocGetter<C>,
|
||||
T: AddressTranslator<()>,
|
||||
{
|
||||
fn new(id: InodeId, mode: FilePermissions) -> Result<Self> {
|
||||
fn new(id: InodeId, permissions: FilePermissions) -> Result<Self> {
|
||||
Ok(Self {
|
||||
id,
|
||||
attr: SpinLockIrq::new(FileAttr {
|
||||
file_type: FileType::File,
|
||||
size: 0,
|
||||
nlinks: 1,
|
||||
mode,
|
||||
permissions,
|
||||
..Default::default()
|
||||
}),
|
||||
inner: SpinLockIrq::new(TmpFsRegInner {
|
||||
@@ -666,14 +666,14 @@ where
|
||||
G: PageAllocGetter<C>,
|
||||
T: AddressTranslator<()>,
|
||||
{
|
||||
pub fn new(id: u64, fs: Weak<TmpFs<C, G, T>>, mode: FilePermissions) -> Arc<Self> {
|
||||
pub fn new(id: u64, fs: Weak<TmpFs<C, G, T>>, permissions: FilePermissions) -> Arc<Self> {
|
||||
Arc::new_cyclic(|weak_this| Self {
|
||||
entries: SpinLockIrq::new(Vec::new()),
|
||||
attrs: SpinLockIrq::new(FileAttr {
|
||||
size: 0,
|
||||
file_type: FileType::Directory,
|
||||
block_size: BLOCK_SZ as _,
|
||||
mode,
|
||||
permissions,
|
||||
..Default::default()
|
||||
}),
|
||||
id,
|
||||
|
||||
Reference in New Issue
Block a user