@@ -2465,25 +2465,36 @@ impl User {
2465
2465
* mut * mut libc:: passwd ) -> libc:: c_int )
2466
2466
-> Option < Result < Self > >
2467
2467
{
2468
- let mut cbuf = Vec :: with_capacity ( PWGRP_BUFSIZE ) ;
2468
+ let bufsize = match sysconf ( SysconfVar :: GETPW_R_SIZE_MAX ) {
2469
+ Ok ( Some ( n) ) => n as usize ,
2470
+ Ok ( None ) | Err ( _) => 1024 as usize ,
2471
+ } ;
2472
+
2473
+ let mut cbuf = Vec :: with_capacity ( bufsize) ;
2469
2474
let mut pwd = mem:: MaybeUninit :: < libc:: passwd > :: uninit ( ) ;
2470
2475
let mut res = ptr:: null_mut ( ) ;
2471
2476
2472
- let error = unsafe {
2473
- Errno :: clear ( ) ;
2474
- f ( pwd. as_mut_ptr ( ) , cbuf. as_mut_ptr ( ) , cbuf. capacity ( ) , & mut res)
2475
- } ;
2476
-
2477
- let pwd = unsafe { pwd. assume_init ( ) } ;
2477
+ loop {
2478
+ let error = unsafe {
2479
+ Errno :: clear ( ) ;
2480
+ f ( pwd. as_mut_ptr ( ) , cbuf. as_mut_ptr ( ) , cbuf. capacity ( ) , & mut res)
2481
+ } ;
2478
2482
2479
- if error == 0 {
2480
- if ! res. is_null ( ) {
2481
- Some ( Ok ( User :: from ( & pwd) ) )
2483
+ if error == 0 {
2484
+ if res. is_null ( ) {
2485
+ return None ;
2486
+ } else {
2487
+ let pwd = unsafe { pwd. assume_init ( ) } ;
2488
+ return Some ( Ok ( User :: from ( & pwd) ) ) ;
2489
+ }
2490
+ } else if Errno :: last ( ) == Errno :: ERANGE {
2491
+ // Trigger the internal buffer resizing logic of `Vec` by requiring
2492
+ // more space than the current capacity.
2493
+ unsafe { cbuf. set_len ( cbuf. capacity ( ) ) ; }
2494
+ cbuf. reserve ( 1 ) ;
2482
2495
} else {
2483
- None
2496
+ return Some ( Err ( Error :: Sys ( Errno :: last ( ) ) ) ) ;
2484
2497
}
2485
- } else {
2486
- Some ( Err ( Error :: Sys ( Errno :: last ( ) ) ) )
2487
2498
}
2488
2499
}
2489
2500
@@ -2573,25 +2584,36 @@ impl Group {
2573
2584
* mut * mut libc:: group ) -> libc:: c_int )
2574
2585
-> Option < Result < Self > >
2575
2586
{
2576
- let mut cbuf = Vec :: with_capacity ( PWGRP_BUFSIZE ) ;
2587
+ let bufsize = match sysconf ( SysconfVar :: GETGR_R_SIZE_MAX ) {
2588
+ Ok ( Some ( n) ) => n as usize ,
2589
+ Ok ( None ) | Err ( _) => 1024 as usize ,
2590
+ } ;
2591
+
2592
+ let mut cbuf = Vec :: with_capacity ( bufsize) ;
2577
2593
let mut grp = mem:: MaybeUninit :: < libc:: group > :: uninit ( ) ;
2578
2594
let mut res = ptr:: null_mut ( ) ;
2579
2595
2580
- let error = unsafe {
2581
- Errno :: clear ( ) ;
2582
- f ( grp. as_mut_ptr ( ) , cbuf. as_mut_ptr ( ) , cbuf. capacity ( ) , & mut res)
2583
- } ;
2584
-
2585
- let grp = unsafe { grp. assume_init ( ) } ;
2596
+ loop {
2597
+ let error = unsafe {
2598
+ Errno :: clear ( ) ;
2599
+ f ( grp. as_mut_ptr ( ) , cbuf. as_mut_ptr ( ) , cbuf. capacity ( ) , & mut res)
2600
+ } ;
2586
2601
2587
- if error == 0 {
2588
- if !res. is_null ( ) {
2589
- Some ( Ok ( Group :: from ( & grp) ) )
2602
+ if error == 0 {
2603
+ if res. is_null ( ) {
2604
+ return None ;
2605
+ } else {
2606
+ let grp = unsafe { grp. assume_init ( ) } ;
2607
+ return Some ( Ok ( Group :: from ( & grp) ) ) ;
2608
+ }
2609
+ } else if Errno :: last ( ) == Errno :: ERANGE {
2610
+ // Trigger the internal buffer resizing logic of `Vec` by requiring
2611
+ // more space than the current capacity.
2612
+ unsafe { cbuf. set_len ( cbuf. capacity ( ) ) ; }
2613
+ cbuf. reserve ( 1 ) ;
2590
2614
} else {
2591
- None
2615
+ return Some ( Err ( Error :: Sys ( Errno :: last ( ) ) ) ) ;
2592
2616
}
2593
- } else {
2594
- Some ( Err ( Error :: Sys ( Errno :: last ( ) ) ) )
2595
2617
}
2596
2618
}
2597
2619
0 commit comments