#file #open #github #actions #descriptors

close_fds

A library that makes it easy to close all open file descriptors

7 releases

0.3.2 Jun 5, 2021
0.3.1 Feb 26, 2021
0.3.0 Jan 3, 2021
0.2.2 Sep 13, 2020
0.1.0 Aug 10, 2020

#47 in Unix APIs

Download history 20/week @ 2021-02-25 4/week @ 2021-03-04 2/week @ 2021-03-11 139/week @ 2021-03-25 16/week @ 2021-04-01 22/week @ 2021-04-08 17/week @ 2021-04-15 23/week @ 2021-04-22 7/week @ 2021-04-29 1/week @ 2021-05-06 35/week @ 2021-05-13 2/week @ 2021-05-20 14/week @ 2021-05-27 16/week @ 2021-06-03 13/week @ 2021-06-10

93 downloads per month
Used in privsep

MIT license

78KB
1.5K SLoC

close_fds

crates.io Docs GitHub Actions Cirrus CI codecov

A small Rust library that makes it easy to close all open file descriptors.

Usage

Add to your Cargo.toml:

[dependencies]
close_fds = "0.2"

In your application:

use close_fds::close_open_fds;

fn main() {
    // ...
    unsafe {
        close_open_fds(3, &[]);
    }
    // ...
}

IMPORTANT: Please read the documentation for close_open_fds() for an explanation of why it is unsafe.

The first argument to close_open_fds() is the lowest file descriptor that should be closed; all file descriptors less than this will be left open. The second argument is a slice containing a list of additional file descriptors that should be left open. (Note: close_open_fds() will be more efficient if this list is sorted, especially if it is more than a few elements long.)

close_open_fds() always succeeds. If one method of closing the file descriptors fails, it will fall back on another.

More details, along with other helpful functions, can be found in the documentation.

OS support

close_fds has two OS support tiers, similar to Rust's support tiers:

Tier 1: "Guaranteed to work" (tested in CI)

  • Linux (glibc and musl)
  • macOS
  • FreeBSD

Tier 2: "Guaranteed to build" (built, but not tested, in CI)

  • NetBSD
  • OpenBSD
  • DragonflyBSD
  • Solaris
  • Illumos

Note: As stated in the license, close_fds comes with no warranty.

OS-specific notes

Here is a list of the methods that the this crate will try on various platforms to improve performance when listing the open file descriptors:

  • Linux
    • /proc/self/fd if /proc is mounted (very efficient)
  • macOS
    • /dev/fd (very efficient)
  • FreeBSD
    • /dev/fd if an fdescfs appears to be mounted there (very efficient)
    • The kern.proc.nfds sysctl to get the number of open file descriptors (moderately efficient unless large numbers of file descriptors are open; not used by the "thread-safe" functions or when closing file descriptors)
  • OpenBSD
    • getdtablecount() to get the number of open file descriptors (moderately efficient unless large numbers of file descriptors are open; not used by the "thread-safe" functions or when closing file descriptors)
  • NetBSD
    • /proc/self/fd if /proc is mounted (very efficient)
    • fcntl(0, F_MAXFD) to get the maximum open file descriptor (moderately efficient)
  • Solaris and Illumos
    • /dev/fd or /proc/self/fd if either is available (very efficient)

When closing file descriptors, or setting the close-on-exec flag, this crate may also call closefrom() on the BSDs and/or close_range() on Linux 5.9+/FreeBSD 12.2+, both of which are very efficient.

If none of the methods listed above are available, it will fall back on a simple loop through every possible file descriptor number -- from minfd to sysconf(_SC_OPEN_MAX). This is slow, but it will always work.

Note: The most common use case, close_open_fds(3, &[]), is very efficient on Linux (with /proc mounted, or on kernel 5.9+), macOS, all of the BSDs, and Solaris/Illumos.

Dependencies