base/sys/unix/fcntl.rs
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
5use std::os::unix::io::RawFd;
6
7use libc::c_int;
8use libc::fcntl;
9use libc::F_GETFL;
10use libc::F_SETFL;
11
12use crate::errno::Result;
13use 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.
18fn 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.
29fn 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.
43pub 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.
51pub 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}