xref: /aosp_15_r20/external/crosvm/base/src/sys/unix/fcntl.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2023 The ChromiumOS Authors
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::RawFd;
6 
7 use libc::c_int;
8 use libc::fcntl;
9 use libc::F_GETFL;
10 use libc::F_SETFL;
11 
12 use crate::errno::Result;
13 use crate::syscall;
14 
15 /// Returns the file flags set for the given `RawFD`
16 ///
17 /// Returns an error if the OS indicates the flags can't be retrieved.
get_fd_flags(fd: RawFd) -> Result<c_int>18 fn get_fd_flags(fd: RawFd) -> Result<c_int> {
19     syscall!(
20         // SAFETY:
21         // Safe because no third parameter is expected and we check the return result.
22         unsafe { fcntl(fd, F_GETFL) }
23     )
24 }
25 
26 /// Sets the file flags set for the given `RawFD`.
27 ///
28 /// Returns an error if the OS indicates the flags can't be retrieved.
set_fd_flags(fd: RawFd, flags: c_int) -> Result<()>29 fn set_fd_flags(fd: RawFd, flags: c_int) -> Result<()> {
30     syscall!(
31         // SAFETY:
32         // Safe because we supply the third parameter and we check the return result.
33         // fcntlt is trusted not to modify the memory of the calling process.
34         unsafe { fcntl(fd, F_SETFL, flags) }
35     )
36     .map(|_| ())
37 }
38 
39 /// Performs a logical OR of the given flags with the FD's flags, setting the given bits for the
40 /// FD.
41 ///
42 /// Returns an error if the OS indicates the flags can't be retrieved or set.
add_fd_flags(fd: RawFd, set_flags: c_int) -> Result<()>43 pub fn add_fd_flags(fd: RawFd, set_flags: c_int) -> Result<()> {
44     let start_flags = get_fd_flags(fd)?;
45     set_fd_flags(fd, start_flags | set_flags)
46 }
47 
48 /// Clears the given flags in the FD's flags.
49 ///
50 /// Returns an error if the OS indicates the flags can't be retrieved or set.
clear_fd_flags(fd: RawFd, clear_flags: c_int) -> Result<()>51 pub fn clear_fd_flags(fd: RawFd, clear_flags: c_int) -> Result<()> {
52     let start_flags = get_fd_flags(fd)?;
53     set_fd_flags(fd, start_flags & !clear_flags)
54 }
55