@@ -868,28 +868,39 @@ impl Iterator for ReadDir {
868
868
}
869
869
}
870
870
871
+ /// Aborts the process if a file desceriptor is not open, if debug asserts are enabled
872
+ ///
873
+ /// Many IO syscalls can't be fully trusted about EBADF error codes because those
874
+ /// might get bubbled up from a remote FUSE server rather than the file descriptor
875
+ /// in the current process being invalid.
876
+ ///
877
+ /// So we check file flags instead which live on the file descriptor and not the underlying file.
878
+ /// The downside is that it costs an extra syscall, so we only do it for debug.
879
+ #[ inline]
880
+ pub ( crate ) fn debug_assert_fd_is_open ( fd : RawFd ) {
881
+ use crate :: sys:: os:: errno;
882
+
883
+ // this is similar to assert_unsafe_precondition!() but it doesn't require const
884
+ if core:: ub_checks:: check_library_ub ( ) {
885
+ if unsafe { libc:: fcntl ( fd, libc:: F_GETFD ) } == -1 && errno ( ) == libc:: EBADF {
886
+ rtabort ! ( "IO Safety violation: owned file descriptor already closed" ) ;
887
+ }
888
+ }
889
+ }
890
+
871
891
impl Drop for Dir {
872
892
fn drop ( & mut self ) {
873
- // ideally this would use assert_unsafe_precondition!, but that's only in core
874
- #[ cfg( all(
875
- debug_assertions,
876
- not( any(
877
- target_os = "redox" ,
878
- target_os = "nto" ,
879
- target_os = "vita" ,
880
- target_os = "hurd" ,
881
- ) )
882
- ) ) ]
893
+ // dirfd isn't supported everywhere
894
+ #[ cfg( not( any(
895
+ miri,
896
+ target_os = "redox" ,
897
+ target_os = "nto" ,
898
+ target_os = "vita" ,
899
+ target_os = "hurd" ,
900
+ ) ) ) ]
883
901
{
884
- use crate :: sys:: os:: errno;
885
- // close() can bubble up error codes from FUSE which can send semantically
886
- // inappropriate error codes including EBADF.
887
- // So we check file flags instead which live on the file descriptor and not the underlying file.
888
- // The downside is that it costs an extra syscall, so we only do it for debug.
889
902
let fd = unsafe { libc:: dirfd ( self . 0 ) } ;
890
- if unsafe { libc:: fcntl ( fd, libc:: F_GETFD ) } == -1 && errno ( ) == libc:: EBADF {
891
- rtabort ! ( "IO Safety violation: DIR*'s owned file descriptor already closed" ) ;
892
- }
903
+ debug_assert_fd_is_open ( fd) ;
893
904
}
894
905
let r = unsafe { libc:: closedir ( self . 0 ) } ;
895
906
assert ! (
0 commit comments