sysmaster/backport-feature-libbasic-add-opendirat.patch
huyubiao 8936fa02c5 sync patches from upstream,change the path of the unit,modify permissions for some directories and files
(cherry picked from commit ce9ff469b57f60130621bc293783bd3ac1fc92f2)
2023-08-05 18:15:53 +08:00

87 lines
2.4 KiB
Diff

From 0b9863bfcb3148247986ead64683bd9add2502fa Mon Sep 17 00:00:00 2001
From: chenjiayi <chenjiayi22@huawei.com>
Date: Wed, 21 Jun 2023 21:29:27 +0800
Subject: [PATCH] feature(libbasic): add opendirat
opendirat is used to open a directory with the directory fd.
---
libs/basic/src/fd_util.rs | 46 +++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/libs/basic/src/fd_util.rs b/libs/basic/src/fd_util.rs
index b397472..0d41966 100644
--- a/libs/basic/src/fd_util.rs
+++ b/libs/basic/src/fd_util.rs
@@ -14,9 +14,9 @@
use crate::error::*;
use nix::{
errno::Errno,
- fcntl::{FcntlArg, FdFlag, OFlag},
+ fcntl::{openat, FcntlArg, FdFlag, OFlag},
ioctl_read,
- sys::stat::SFlag,
+ sys::stat::{Mode, SFlag},
};
/// check if the given stat.st_mode is regular file
@@ -157,11 +157,33 @@ pub fn fd_get_diskseq(fd: i32) -> Result<u64> {
Ok(diskseq)
}
+/// open the directory at fd
+pub fn opendirat(dirfd: i32, flags: OFlag) -> Result<nix::dir::Dir> {
+ let nfd = openat(
+ dirfd,
+ ".",
+ OFlag::O_RDONLY | OFlag::O_NONBLOCK | OFlag::O_DIRECTORY | OFlag::O_CLOEXEC | flags,
+ Mode::empty(),
+ )
+ .context(NixSnafu)?;
+
+ nix::dir::Dir::from_fd(nfd).context(NixSnafu)
+}
+
#[cfg(test)]
mod tests {
use crate::fd_util::{stat_is_char, stat_is_reg};
- use nix::sys::stat::fstat;
- use std::{fs::File, os::unix::prelude::AsRawFd, path::Path};
+ use nix::{
+ fcntl::{open, OFlag},
+ sys::stat::{fstat, Mode},
+ };
+ use std::{
+ fs::{remove_dir_all, File},
+ os::unix::prelude::AsRawFd,
+ path::Path,
+ };
+
+ use super::opendirat;
#[test]
fn test_stats() {
@@ -185,4 +207,20 @@ mod tests {
let st = fstat(fd_non_char_file.as_raw_fd()).unwrap();
assert!(!stat_is_char(st.st_mode));
}
+
+ #[test]
+ fn test_opendirat() {
+ std::fs::create_dir_all("/tmp/test_opendirat").unwrap();
+ File::create("/tmp/test_opendirat/entry0").unwrap();
+ File::create("/tmp/test_opendirat/entry1").unwrap();
+
+ let dirfd = open("/tmp/test_opendirat", OFlag::O_DIRECTORY, Mode::empty()).unwrap();
+ let mut dir = opendirat(dirfd, OFlag::O_NOFOLLOW).unwrap();
+
+ for e in dir.iter() {
+ let _ = e.unwrap();
+ }
+
+ remove_dir_all("/tmp/test_opendirat").unwrap();
+ }
}
--
2.33.0