From 9261852a50372dd888ba5bffab988403fb8eb7c7 Mon Sep 17 00:00:00 2001 From: Valentyn Kit Date: Tue, 23 Jun 2026 21:33:11 +0300 Subject: [PATCH] Add `io::ErrorKind::TooManyOpenFiles` `EMFILE` and `ENFILE` decoded to `ErrorKind::Uncategorized`, so running out of file descriptors could only be detected through `raw_os_error()`. Map them, and the equivalent codes on Windows (`ERROR_TOO_MANY_OPEN_FILES`, `WSAEMFILE`) and VEXos (`FR_TOO_MANY_OPEN_FILES`), to a new unstable `TooManyOpenFiles` variant. --- library/core/src/io/error.rs | 7 +++++++ library/std/src/lib.rs | 1 + library/std/src/sys/fs/vexos.rs | 2 +- library/std/src/sys/io/error/unix.rs | 1 + library/std/src/sys/io/error/wasi.rs | 1 + library/std/src/sys/io/error/windows.rs | 2 ++ 6 files changed, 13 insertions(+), 1 deletion(-) diff --git a/library/core/src/io/error.rs b/library/core/src/io/error.rs index 67cd1eebf44f2..961e3c7281200 100644 --- a/library/core/src/io/error.rs +++ b/library/core/src/io/error.rs @@ -238,6 +238,11 @@ pub enum ErrorKind { #[unstable(feature = "io_error_inprogress", issue = "130840")] InProgress, + /// The process or the whole system has reached its limit on the number of + /// open files or sockets. + #[unstable(feature = "io_error_too_many_open_files", issue = "158319")] + TooManyOpenFiles, + // "Unusual" error kinds which do not correspond simply to (sets // of) OS error codes, should be added just above this comment. // `Other` and `Uncategorized` should remain at the end: @@ -309,6 +314,7 @@ impl ErrorKind { StorageFull => "no storage space", TimedOut => "timed out", TooManyLinks => "too many links", + TooManyOpenFiles => "too many open files", Uncategorized => "uncategorized error", UnexpectedEof => "unexpected end of file", Unsupported => "unsupported", @@ -379,6 +385,7 @@ impl ErrorKind { Unsupported, OutOfMemory, InProgress, + TooManyOpenFiles, Uncategorized, }) } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c9e884d89c85e..1b27be8e2dde3 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -355,6 +355,7 @@ #![feature(int_from_ascii)] #![feature(io_error_inprogress)] #![feature(io_error_more)] +#![feature(io_error_too_many_open_files)] #![feature(io_error_uncategorized)] #![feature(io_slice_as_bytes)] #![feature(ip)] diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 9de9570cb5b24..d13b28d2abffa 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -612,7 +612,7 @@ fn map_fresult(fresult: vex_sdk::FRESULT) -> io::Result<()> { Err(io::const_error!(io::ErrorKind::OutOfMemory, "not enough memory for the operation")) } vex_sdk::FRESULT::FR_TOO_MANY_OPEN_FILES => Err(io::const_error!( - io::ErrorKind::Uncategorized, + io::ErrorKind::TooManyOpenFiles, "maximum number of open files has been reached", )), vex_sdk::FRESULT::FR_INVALID_PARAMETER => { diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index b10343b2752c2..56295578bf7d9 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -137,6 +137,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { libc::ETXTBSY => ExecutableFileBusy, libc::EXDEV => CrossesDevices, libc::EINPROGRESS => InProgress, + libc::EMFILE | libc::ENFILE => TooManyOpenFiles, libc::EOPNOTSUPP => Unsupported, libc::EACCES | libc::EPERM => PermissionDenied, diff --git a/library/std/src/sys/io/error/wasi.rs b/library/std/src/sys/io/error/wasi.rs index 719fc0c900adc..3a0fa37e979bc 100644 --- a/library/std/src/sys/io/error/wasi.rs +++ b/library/std/src/sys/io/error/wasi.rs @@ -59,6 +59,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { libc::ETXTBSY => ExecutableFileBusy, libc::EXDEV => CrossesDevices, libc::EINPROGRESS => InProgress, + libc::EMFILE | libc::ENFILE => TooManyOpenFiles, libc::EOPNOTSUPP => Unsupported, libc::EACCES | libc::EPERM => PermissionDenied, libc::EWOULDBLOCK => WouldBlock, diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index 3c2f41a907813..9af11588fe322 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs @@ -61,6 +61,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, c::ERROR_NOT_SAME_DEVICE => return CrossesDevices, c::ERROR_TOO_MANY_LINKS => return TooManyLinks, + c::ERROR_TOO_MANY_OPEN_FILES => return TooManyOpenFiles, c::ERROR_FILENAME_EXCED_RANGE => return InvalidFilename, c::ERROR_CANT_RESOLVE_FILENAME => return FilesystemLoop, _ => {} @@ -81,6 +82,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { c::WSAENETDOWN => NetworkDown, c::WSAENETUNREACH => NetworkUnreachable, c::WSAEDQUOT => QuotaExceeded, + c::WSAEMFILE => TooManyOpenFiles, // Not a perfect mapping but this error is only returned when writing to // a socket after shutting down the write-end. On Unix targets, EPIPE is // returned in those cases.