// Copyright 2023 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::os::unix::io::RawFd;56use libc::c_int;7use libc::fcntl;8use libc::F_GETFL;9use libc::F_SETFL;1011use crate::errno::Result;12use crate::syscall;1314/// Returns the file flags set for the given `RawFD`15///16/// Returns an error if the OS indicates the flags can't be retrieved.17fn get_fd_flags(fd: RawFd) -> Result<c_int> {18syscall!(19// SAFETY:20// Safe because no third parameter is expected and we check the return result.21unsafe { fcntl(fd, F_GETFL) }22)23}2425/// Sets the file flags set for the given `RawFD`.26///27/// Returns an error if the OS indicates the flags can't be retrieved.28fn set_fd_flags(fd: RawFd, flags: c_int) -> Result<()> {29syscall!(30// SAFETY:31// Safe because we supply the third parameter and we check the return result.32// fcntlt is trusted not to modify the memory of the calling process.33unsafe { fcntl(fd, F_SETFL, flags) }34)35.map(|_| ())36}3738/// Performs a logical OR of the given flags with the FD's flags, setting the given bits for the39/// FD.40///41/// Returns an error if the OS indicates the flags can't be retrieved or set.42pub fn add_fd_flags(fd: RawFd, set_flags: c_int) -> Result<()> {43let start_flags = get_fd_flags(fd)?;44set_fd_flags(fd, start_flags | set_flags)45}4647/// Clears the given flags in the FD's flags.48///49/// Returns an error if the OS indicates the flags can't be retrieved or set.50pub fn clear_fd_flags(fd: RawFd, clear_flags: c_int) -> Result<()> {51let start_flags = get_fd_flags(fd)?;52set_fd_flags(fd, start_flags & !clear_flags)53}545556