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