base/sys/unix/
file_flags.rs1use libc::fcntl;
6use libc::EINVAL;
7use libc::F_GETFL;
8use libc::O_ACCMODE;
9use libc::O_RDONLY;
10use libc::O_RDWR;
11use libc::O_WRONLY;
12
13use crate::errno_result;
14use crate::AsRawDescriptor;
15use crate::Error;
16use crate::Result;
17
18#[derive(Copy, Clone, Debug, Eq, PartialEq)]
19pub enum FileFlags {
20 Read,
21 Write,
22 ReadWrite,
23}
24
25impl FileFlags {
26 pub fn from_file(file: &dyn AsRawDescriptor) -> Result<FileFlags> {
27 let flags = unsafe { fcntl(file.as_raw_descriptor(), F_GETFL) };
31 if flags == -1 {
32 errno_result()
33 } else {
34 match flags & O_ACCMODE {
35 O_RDONLY => Ok(FileFlags::Read),
36 O_WRONLY => Ok(FileFlags::Write),
37 O_RDWR => Ok(FileFlags::ReadWrite),
38 _ => Err(Error::new(EINVAL)),
39 }
40 }
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47 use crate::sys::pipe;
48 use crate::Event;
49
50 #[test]
51 fn pipe_pair() {
52 let (read_pipe, write_pipe) = pipe().unwrap();
53 assert_eq!(FileFlags::from_file(&read_pipe).unwrap(), FileFlags::Read);
54 assert_eq!(FileFlags::from_file(&write_pipe).unwrap(), FileFlags::Write);
55 }
56
57 #[test]
58 fn event() {
59 let evt = Event::new().unwrap();
60 assert_eq!(FileFlags::from_file(&evt).unwrap(), FileFlags::ReadWrite);
61 }
62}