blob: 7a2ad1baeb96d9fdae986634ac73499668b91820 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::os::unix::io::AsRawFd;
use libc::{fcntl, EINVAL, F_GETFL, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY};
use crate::{errno_result, Error, Result};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum FileFlags {
Read,
Write,
ReadWrite,
}
impl FileFlags {
pub fn from_file(file: &dyn AsRawFd) -> Result<FileFlags> {
// Trivially safe because fcntl with the F_GETFL command is totally safe and we check for
// error.
let flags = unsafe { fcntl(file.as_raw_fd(), 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::*;
use crate::{pipe, EventFd};
#[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 eventfd() {
let evt = EventFd::new().unwrap();
assert_eq!(FileFlags::from_file(&evt).unwrap(), FileFlags::ReadWrite);
}
}