cap_primitives/rustix/fs/
oflags.rs1use crate::fs::{target_o_path, FollowSymlinks, OpenOptions};
2use rustix::fs::OFlags;
3use std::io;
4
5pub(in super::super) fn compute_oflags(options: &OpenOptions) -> io::Result<OFlags> {
6 let mut oflags = OFlags::CLOEXEC;
7 oflags |= get_access_mode(options)?;
8 oflags |= get_creation_mode(options)?;
9 if options.follow == FollowSymlinks::No {
10 oflags |= OFlags::NOFOLLOW;
11 }
12 if options.sync {
13 oflags |= OFlags::SYNC;
14 }
15 if options.dsync {
16 #[cfg(not(target_os = "freebsd"))]
17 {
18 oflags |= OFlags::DSYNC;
19 }
20
21 #[cfg(target_os = "freebsd")]
23 {
24 oflags |= OFlags::SYNC;
25 }
26 }
27 #[cfg(not(any(
28 target_os = "ios",
29 target_os = "macos",
30 target_os = "tvos",
31 target_os = "watchos",
32 target_os = "visionos",
33 target_os = "freebsd",
34 target_os = "fuchsia"
35 )))]
36 if options.rsync {
37 oflags |= OFlags::RSYNC;
38 }
39 if options.nonblock {
40 oflags |= OFlags::NONBLOCK;
41 }
42 if options.dir_required {
43 oflags |= OFlags::DIRECTORY;
44
45 if !options.readdir_required && !options.write && !options.append {
49 oflags |= target_o_path();
50 }
51 }
52 #[cfg(not(target_os = "wasi"))]
55 {
56 oflags |= OFlags::from_bits(options.ext.custom_flags as _).expect("unrecognized OFlags")
57 & !OFlags::RWMODE;
58 }
59 Ok(oflags)
60}
61
62pub(crate) fn get_access_mode(options: &OpenOptions) -> io::Result<OFlags> {
67 match (options.read, options.write, options.append) {
68 (true, false, false) => Ok(OFlags::RDONLY),
69 (false, true, false) => Ok(OFlags::WRONLY),
70 (true, true, false) => Ok(OFlags::RDWR),
71 (false, _, true) => Ok(OFlags::WRONLY | OFlags::APPEND),
72 (true, _, true) => Ok(OFlags::RDWR | OFlags::APPEND),
73 (false, false, false) => Err(rustix::io::Errno::INVAL.into()),
74 }
75}
76
77pub(crate) fn get_creation_mode(options: &OpenOptions) -> io::Result<OFlags> {
78 match (options.write, options.append) {
79 (true, false) => {}
80 (false, false) => {
81 if options.truncate || options.create || options.create_new {
82 return Err(rustix::io::Errno::INVAL.into());
83 }
84 }
85 (_, true) => {
86 if options.truncate && !options.create_new {
87 return Err(rustix::io::Errno::INVAL.into());
88 }
89 }
90 }
91
92 Ok(
93 match (options.create, options.truncate, options.create_new) {
94 (false, false, false) => OFlags::empty(),
95 (true, false, false) => OFlags::CREATE,
96 (false, true, false) => OFlags::TRUNC,
97 (true, true, false) => OFlags::CREATE | OFlags::TRUNC,
98 (_, _, true) => OFlags::CREATE | OFlags::EXCL,
99 },
100 )
101}