139 lines
4.3 KiB
Diff
139 lines
4.3 KiB
Diff
From d570a9c740fec2c89f006c83f0cd46cec5e547a8 Mon Sep 17 00:00:00 2001
|
|
From: chenjiayi <chenjiayi22@huawei.com>
|
|
Date: Mon, 3 Jul 2023 01:03:39 +0800
|
|
Subject: [PATCH] feature(devmaster): support update device database and tags
|
|
|
|
Besides, move the loop device interfaces to libdevice as some test
|
|
cases in libdevice need to use loop device.
|
|
---
|
|
libs/basic/src/fs_util.rs | 88 +++++-
|
|
9 files changed, 542 insertions(+), 128 deletions(-)
|
|
delete mode 100644 exts/devmaster/src/lib/utils/loop_device.rs
|
|
|
|
diff --git a/libs/basic/src/fs_util.rs b/libs/basic/src/fs_util.rs
|
|
index 8a8f276..413008b 100644
|
|
--- a/libs/basic/src/fs_util.rs
|
|
+++ b/libs/basic/src/fs_util.rs
|
|
@@ -15,7 +15,7 @@
|
|
use crate::{error::*, format_proc_fd_path};
|
|
use libc::{fchownat, mode_t, timespec, AT_EMPTY_PATH, S_IFLNK, S_IFMT};
|
|
use nix::{
|
|
- fcntl::{readlink, renameat, OFlag},
|
|
+ fcntl::{open, readlink, renameat, OFlag},
|
|
sys::stat::{fstat, Mode},
|
|
unistd::{unlinkat, Gid, Uid, UnlinkatFlags},
|
|
};
|
|
@@ -23,7 +23,7 @@ use pathdiff::diff_paths;
|
|
use rand::Rng;
|
|
use std::{
|
|
ffi::CString,
|
|
- fs::{remove_dir, File},
|
|
+ fs::{create_dir_all, remove_dir, File},
|
|
io::ErrorKind,
|
|
os::unix::prelude::{AsRawFd, FromRawFd, PermissionsExt, RawFd},
|
|
path::Path,
|
|
@@ -245,13 +245,70 @@ pub fn remove_dir_until(path: &str, stop: &str) -> Result<()> {
|
|
Ok(())
|
|
}
|
|
|
|
+/// create and open a temporary file
|
|
+pub fn open_temporary(path: &str) -> Result<(File, String)> {
|
|
+ let tmp_file = format!("{}.{}", path, rand::thread_rng().gen::<u32>());
|
|
+
|
|
+ let f = open(
|
|
+ tmp_file.as_str(),
|
|
+ OFlag::O_CLOEXEC | OFlag::O_NOCTTY | OFlag::O_RDWR | OFlag::O_CREAT | OFlag::O_EXCL,
|
|
+ Mode::from_bits(0o644).unwrap(),
|
|
+ )
|
|
+ .context(NixSnafu)?;
|
|
+
|
|
+ let file = unsafe { File::from_raw_fd(f) };
|
|
+
|
|
+ Ok((file, tmp_file))
|
|
+}
|
|
+
|
|
+/// Create a new file based on absolute path.
|
|
+pub fn touch_file(
|
|
+ path: &str,
|
|
+ parents: bool,
|
|
+ mode: Option<mode_t>,
|
|
+ uid: Option<Uid>,
|
|
+ gid: Option<Gid>,
|
|
+) -> Result<bool> {
|
|
+ let p = Path::new(path);
|
|
+
|
|
+ if parents && p.parent().is_some() {
|
|
+ let _ = create_dir_all(p.parent().unwrap());
|
|
+ }
|
|
+
|
|
+ let fd = match open(
|
|
+ p,
|
|
+ OFlag::O_PATH | OFlag::O_CLOEXEC | OFlag::O_NOFOLLOW,
|
|
+ Mode::empty(),
|
|
+ ) {
|
|
+ Ok(n) => n,
|
|
+ Err(e) => {
|
|
+ if e != nix::Error::ENOENT {
|
|
+ return Err(Error::Nix { source: e });
|
|
+ }
|
|
+
|
|
+ open(
|
|
+ p,
|
|
+ OFlag::O_WRONLY | OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_CLOEXEC,
|
|
+ mode.map(|v| Mode::from_bits(v).unwrap_or(Mode::empty()))
|
|
+ .unwrap_or(Mode::empty()),
|
|
+ )
|
|
+ .context(NixSnafu)?
|
|
+ }
|
|
+ };
|
|
+
|
|
+ /* The returned value should be explicitly declared, otherwise the file will be closed at once */
|
|
+ let _f = unsafe { File::from_raw_fd(fd) };
|
|
+
|
|
+ fchmod_and_chown(fd, path, mode, uid, gid)
|
|
+}
|
|
+
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::fs_util::symlink;
|
|
- use nix::unistd::{self};
|
|
+ use nix::unistd::{self, unlink};
|
|
use std::{
|
|
- fs::{create_dir_all, File},
|
|
+ fs::{create_dir_all, remove_file, File},
|
|
os::unix::prelude::MetadataExt,
|
|
time::SystemTime,
|
|
};
|
|
@@ -369,4 +426,27 @@ mod tests {
|
|
assert!(!Path::new("/tmp/test_remove_dir_until_2/test2").exists());
|
|
assert!(Path::new("/tmp/test_remove_dir_until_2/test_file").exists());
|
|
}
|
|
+
|
|
+ #[test]
|
|
+ fn test_open_temporary() {
|
|
+ let (file, name) = open_temporary("test_open_temporary").unwrap();
|
|
+ let p = Path::new(&name);
|
|
+ println!("{:?}", p.canonicalize().unwrap());
|
|
+ drop(file);
|
|
+ remove_file(name).unwrap();
|
|
+ }
|
|
+
|
|
+ #[test]
|
|
+ fn test_touch_file() {
|
|
+ let _ = unlink("/tmp/test_touch_file/f1");
|
|
+ touch_file("/tmp/test_touch_file/f1", true, Some(0o444), None, None).unwrap();
|
|
+ let p = Path::new("/tmp/test_touch_file/f1");
|
|
+ assert!(p.exists());
|
|
+ let md = p.metadata().unwrap();
|
|
+ assert_eq!(md.mode() & 0o777, 0o444);
|
|
+ touch_file("/tmp/test_touch_file/f1", true, Some(0o666), None, None).unwrap();
|
|
+ let md = p.metadata().unwrap();
|
|
+ assert_eq!(md.mode() & 0o777, 0o666);
|
|
+ let _ = unlink("/tmp/test_touch_file/f1");
|
|
+ }
|
|
}
|
|
--
|
|
2.33.0
|
|
|