• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::os::unix::io::AsRawFd;
6 
7 use libc::{fcntl, EINVAL, F_GETFL, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY};
8 
9 use super::{errno_result, Error, Result};
10 
11 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
12 pub enum FileFlags {
13     Read,
14     Write,
15     ReadWrite,
16 }
17 
18 impl FileFlags {
from_file(file: &dyn AsRawFd) -> Result<FileFlags>19     pub fn from_file(file: &dyn AsRawFd) -> Result<FileFlags> {
20         // Trivially safe because fcntl with the F_GETFL command is totally safe and we check for
21         // error.
22         let flags = unsafe { fcntl(file.as_raw_fd(), F_GETFL) };
23         if flags == -1 {
24             errno_result()
25         } else {
26             match flags & O_ACCMODE {
27                 O_RDONLY => Ok(FileFlags::Read),
28                 O_WRONLY => Ok(FileFlags::Write),
29                 O_RDWR => Ok(FileFlags::ReadWrite),
30                 _ => Err(Error::new(EINVAL)),
31             }
32         }
33     }
34 }
35 
36 #[cfg(test)]
37 mod tests {
38     use super::{
39         super::{pipe, EventFd},
40         *,
41     };
42 
43     #[test]
pipe_pair()44     fn pipe_pair() {
45         let (read_pipe, write_pipe) = pipe(true).unwrap();
46         assert_eq!(FileFlags::from_file(&read_pipe).unwrap(), FileFlags::Read);
47         assert_eq!(FileFlags::from_file(&write_pipe).unwrap(), FileFlags::Write);
48     }
49 
50     #[test]
eventfd()51     fn eventfd() {
52         let evt = EventFd::new().unwrap();
53         assert_eq!(FileFlags::from_file(&evt).unwrap(), FileFlags::ReadWrite);
54     }
55 }
56