/src/crosvm/base/src/sys/unix/fcntl.rs
Line | Count | Source |
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. |
18 | 5.56k | fn get_fd_flags(fd: RawFd) -> Result<c_int> { |
19 | 5.56k | syscall!( |
20 | | // SAFETY: |
21 | | // Safe because no third parameter is expected and we check the return result. |
22 | 5.56k | unsafe { fcntl(fd, F_GETFL) } |
23 | | ) |
24 | 5.56k | } |
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. |
29 | 5.56k | fn set_fd_flags(fd: RawFd, flags: c_int) -> Result<()> { |
30 | 5.56k | 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 | 5.56k | unsafe { fcntl(fd, F_SETFL, flags) } |
35 | | ) |
36 | 5.56k | .map(|_| ()) |
37 | 5.56k | } |
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. |
43 | 5.56k | pub fn add_fd_flags(fd: RawFd, set_flags: c_int) -> Result<()> { |
44 | 5.56k | let start_flags = get_fd_flags(fd)?; |
45 | 5.56k | set_fd_flags(fd, start_flags | set_flags) |
46 | 5.56k | } |
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. |
51 | 0 | pub fn clear_fd_flags(fd: RawFd, clear_flags: c_int) -> Result<()> { |
52 | 0 | let start_flags = get_fd_flags(fd)?; |
53 | 0 | set_fd_flags(fd, start_flags & !clear_flags) |
54 | 0 | } |