@@ -232,10 +232,22 @@ pub fn fd_set_num_elements(set_count: usize, nfds: RawFd) -> usize {
232232#[ cfg( any( windows, target_os = "wasi" ) ) ]
233233#[ inline]
234234pub ( crate ) fn fd_set_num_elements_for_fd_array ( set_count : usize ) -> usize {
235+ // Ensure that we always have a big enough set to derefence an `FD_SET`.
236+ core:: cmp:: max (
237+ fd_set_num_elements_for_fd_array_raw ( set_count) ,
238+ div_ceil ( size_of :: < FD_SET > ( ) , size_of :: < FdSetElement > ( ) ) ,
239+ )
240+ }
241+
242+ /// Compute the raw `fd_set_num_elements` value, before ensuring the value is
243+ /// big enough to dereference an `FD_SET`.
244+ #[ cfg( any( windows, target_os = "wasi" ) ) ]
245+ #[ inline]
246+ fn fd_set_num_elements_for_fd_array_raw ( set_count : usize ) -> usize {
235247 // Allocate space for an `fd_count` field, plus `set_count` elements
236248 // for the `fd_array` field.
237249 div_ceil (
238- align_of :: < FD_SET > ( ) + set_count * size_of :: < RawFd > ( ) ,
250+ core :: cmp :: max ( align_of :: < FD_SET > ( ) , align_of :: < RawFd > ( ) ) + set_count * size_of :: < RawFd > ( ) ,
239251 size_of :: < FdSetElement > ( ) ,
240252 )
241253}
@@ -346,12 +358,24 @@ mod test {
346358
347359 // The layout of `FD_SET` should match our layout of a set of the same
348360 // size.
361+ assert_eq ! (
362+ fd_set_num_elements_for_fd_array_raw(
363+ memoffset:: span_of!( FD_SET , fd_array) . len( ) / size_of:: <RawFd >( )
364+ ) * size_of:: <FdSetElement >( ) ,
365+ size_of:: <FD_SET >( )
366+ ) ;
349367 assert_eq ! (
350368 fd_set_num_elements_for_fd_array(
351369 memoffset:: span_of!( FD_SET , fd_array) . len( ) / size_of:: <RawFd >( )
352370 ) * size_of:: <FdSetElement >( ) ,
353371 size_of:: <FD_SET >( )
354372 ) ;
373+
374+ // Don't create fd sets smaller than `FD_SET`.
375+ assert_eq ! (
376+ fd_set_num_elements_for_fd_array( 0 ) * size_of:: <FdSetElement >( ) ,
377+ size_of:: <FD_SET >( )
378+ ) ;
355379 }
356380
357381 #[ test]
0 commit comments