Skip to content

Commit 4e773be

Browse files
committed
feat(fs): add set_permissions for unix
1 parent e2aafcc commit 4e773be

File tree

5 files changed

+40
-22
lines changed

5 files changed

+40
-22
lines changed

compio-driver/src/iour/op.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl FileStat {
6767
}
6868

6969
impl OpCode for FileStat {
70-
fn create_entry(mut self: Pin<&mut Self>) -> io_uring::squeue::Entry {
70+
fn create_entry(mut self: Pin<&mut Self>) -> OpEntry {
7171
static EMPTY_NAME: &[u8] = b"\0";
7272
opcode::Statx::new(
7373
Fd(self.fd),
@@ -76,6 +76,7 @@ impl OpCode for FileStat {
7676
)
7777
.flags(libc::AT_EMPTY_PATH)
7878
.build()
79+
.into()
7980
}
8081
}
8182

@@ -106,7 +107,7 @@ impl PathStat {
106107
}
107108

108109
impl OpCode for PathStat {
109-
fn create_entry(mut self: Pin<&mut Self>) -> io_uring::squeue::Entry {
110+
fn create_entry(mut self: Pin<&mut Self>) -> OpEntry {
110111
let mut flags = libc::AT_EMPTY_PATH;
111112
if !self.follow_symlink {
112113
flags |= libc::AT_SYMLINK_NOFOLLOW;
@@ -118,6 +119,7 @@ impl OpCode for PathStat {
118119
)
119120
.flags(flags)
120121
.build()
122+
.into()
121123
}
122124
}
123125

compio-fs/src/file.rs

+12
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,18 @@ impl File {
112112
.await
113113
}
114114

115+
/// Changes the permissions on the underlying file.
116+
#[cfg(unix)]
117+
pub async fn set_permissions(&self, perm: Permissions) -> io::Result<()> {
118+
let fd = self.try_as_raw_fd()? as _;
119+
Runtime::current()
120+
.spawn_blocking(move || {
121+
syscall!(libc::fchmod(fd, perm.0))?;
122+
Ok(())
123+
})
124+
.await
125+
}
126+
115127
async fn sync_impl(&self, datasync: bool) -> io::Result<()> {
116128
let op = Sync::new(self.try_as_raw_fd()?, datasync);
117129
Runtime::current().submit(op).await.0?;

compio-fs/src/lib.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,11 @@ pub(crate) fn path_string(
3636

3737
#[cfg(unix)]
3838
pub(crate) fn path_string(path: impl AsRef<std::path::Path>) -> std::io::Result<std::ffi::CString> {
39-
CString::new(path.as_ref().as_os_str().as_bytes().to_vec()).map_err(|_| {
40-
io::Error::new(
41-
io::ErrorKind::InvalidInput,
39+
use std::os::unix::ffi::OsStrExt;
40+
41+
std::ffi::CString::new(path.as_ref().as_os_str().as_bytes().to_vec()).map_err(|_| {
42+
std::io::Error::new(
43+
std::io::ErrorKind::InvalidInput,
4244
"file name contained an unexpected NUL byte",
4345
)
4446
})

compio-fs/src/metadata/unix.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
use std::{
2-
ffi::CString,
32
io,
4-
os::unix::prelude::{FileTypeExt, MetadataExt, OsStrExt, PermissionsExt},
3+
os::unix::prelude::{FileTypeExt, MetadataExt, PermissionsExt},
54
path::Path,
65
time::{Duration, SystemTime},
76
};
87

98
use compio_buf::{BufResult, IntoInner};
10-
use compio_driver::op::PathStat;
9+
use compio_driver::{op::PathStat, syscall};
1110
use compio_runtime::Runtime;
1211

12+
use crate::path_string;
13+
1314
async fn metadata_impl(path: impl AsRef<Path>, follow_symlink: bool) -> io::Result<Metadata> {
14-
let path = CString::new(path.as_ref().as_os_str().as_bytes().to_vec()).map_err(|_| {
15-
io::Error::new(
16-
io::ErrorKind::InvalidInput,
17-
"file name contained an unexpected NUL byte",
18-
)
19-
})?;
15+
let path = path_string(path)?;
2016
let op = PathStat::new(path, follow_symlink);
2117
let BufResult(res, op) = Runtime::current().submit(op).await;
2218
res.map(|_| Metadata::from_stat(op.into_inner()))
@@ -33,6 +29,17 @@ pub async fn symlink_metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
3329
metadata_impl(path, false).await
3430
}
3531

32+
/// Changes the permissions found on a file or a directory.
33+
pub async fn set_permissions(path: impl AsRef<Path>, perm: Permissions) -> io::Result<()> {
34+
let path = path_string(path)?;
35+
Runtime::current()
36+
.spawn_blocking(move || {
37+
syscall!(libc::chmod(path.as_ptr(), perm.0))?;
38+
Ok(())
39+
})
40+
.await
41+
}
42+
3643
/// Metadata information about a file.
3744
#[derive(Clone)]
3845
pub struct Metadata(pub(crate) libc::stat);

compio-fs/src/open_options/unix.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use std::{ffi::CString, io, os::unix::prelude::OsStrExt, path::Path};
1+
use std::{io, path::Path};
22

33
use compio_driver::{op::OpenFile, FromRawFd, RawFd};
44
use compio_runtime::Runtime;
55

6-
use crate::File;
6+
use crate::{path_string, File};
77

88
#[derive(Clone, Debug)]
99
pub struct OpenOptions {
@@ -89,12 +89,7 @@ impl OpenOptions {
8989
if cfg!(not(any(target_os = "linux", target_os = "android"))) {
9090
flags |= libc::O_NONBLOCK;
9191
}
92-
let p = CString::new(p.as_ref().as_os_str().as_bytes().to_vec()).map_err(|_| {
93-
io::Error::new(
94-
io::ErrorKind::InvalidInput,
95-
"file name contained an unexpected NUL byte",
96-
)
97-
})?;
92+
let p = path_string(p)?;
9893
let op = OpenFile::new(p, flags, self.mode);
9994
let fd = Runtime::current().submit(op).await.0? as RawFd;
10095
Ok(unsafe { File::from_raw_fd(fd) })

0 commit comments

Comments
 (0)