@@ -322,14 +322,23 @@ unsafe fn members(groups: *mut *mut c_char) -> Vec<OsString> {
322
322
/// ```
323
323
pub fn get_user_by_uid ( uid : uid_t ) -> Option < User > {
324
324
let mut passwd = unsafe { mem:: zeroed :: < c_passwd > ( ) } ;
325
- let mut buf = vec ! [ 0 ; 2048 ] ; // TODO: Retry with larger buffer sizes
325
+ let mut buf = vec ! [ 0 ; 2048 ] ;
326
326
let mut result = ptr:: null_mut :: < c_passwd > ( ) ;
327
327
328
328
#[ cfg( feature = "logging" ) ]
329
329
trace ! ( "Running getpwuid_r for user #{}" , uid) ;
330
330
331
- unsafe {
332
- libc:: getpwuid_r ( uid, & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result) ;
331
+ loop {
332
+ let r = unsafe {
333
+ libc:: getpwuid_r ( uid, & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result)
334
+ } ;
335
+
336
+ if r != libc:: ERANGE {
337
+ break ;
338
+ }
339
+
340
+ let newsize = buf. len ( ) . checked_mul ( 2 ) ?;
341
+ buf. resize ( newsize, 0 ) ;
333
342
}
334
343
335
344
if result. is_null ( ) {
@@ -375,14 +384,23 @@ pub fn get_user_by_name<S: AsRef<OsStr> + ?Sized>(username: &S) -> Option<User>
375
384
} ;
376
385
377
386
let mut passwd = unsafe { mem:: zeroed :: < c_passwd > ( ) } ;
378
- let mut buf = vec ! [ 0 ; 2048 ] ; // TODO: Retry with larger buffer sizes
387
+ let mut buf = vec ! [ 0 ; 2048 ] ;
379
388
let mut result = ptr:: null_mut :: < c_passwd > ( ) ;
380
389
381
390
#[ cfg( feature = "logging" ) ]
382
391
trace ! ( "Running getpwnam_r for user {:?}" , username. as_ref( ) ) ;
383
392
384
- unsafe {
385
- libc:: getpwnam_r ( username. as_ptr ( ) , & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result) ;
393
+ loop {
394
+ let r = unsafe {
395
+ libc:: getpwnam_r ( username. as_ptr ( ) , & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result)
396
+ } ;
397
+
398
+ if r != libc:: ERANGE {
399
+ break ;
400
+ }
401
+
402
+ let newsize = buf. len ( ) . checked_mul ( 2 ) ?;
403
+ buf. resize ( newsize, 0 ) ;
386
404
}
387
405
388
406
if result. is_null ( ) {
@@ -419,14 +437,23 @@ pub fn get_user_by_name<S: AsRef<OsStr> + ?Sized>(username: &S) -> Option<User>
419
437
/// ```
420
438
pub fn get_group_by_gid ( gid : gid_t ) -> Option < Group > {
421
439
let mut passwd = unsafe { mem:: zeroed :: < c_group > ( ) } ;
422
- let mut buf = vec ! [ 0 ; 2048 ] ; // TODO: Retry with larger buffer sizes
440
+ let mut buf = vec ! [ 0 ; 2048 ] ;
423
441
let mut result = ptr:: null_mut :: < c_group > ( ) ;
424
442
425
443
#[ cfg( feature = "logging" ) ]
426
444
trace ! ( "Running getgruid_r for group #{}" , gid) ;
427
445
428
- unsafe {
429
- libc:: getgrgid_r ( gid, & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result) ;
446
+ loop {
447
+ let r = unsafe {
448
+ libc:: getgrgid_r ( gid, & mut passwd, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result)
449
+ } ;
450
+
451
+ if r != libc:: ERANGE {
452
+ break ;
453
+ }
454
+
455
+ let newsize = buf. len ( ) . checked_mul ( 2 ) ?;
456
+ buf. resize ( newsize, 0 ) ;
430
457
}
431
458
432
459
if result. is_null ( ) {
@@ -472,14 +499,23 @@ pub fn get_group_by_name<S: AsRef<OsStr> + ?Sized>(groupname: &S) -> Option<Grou
472
499
} ;
473
500
474
501
let mut group = unsafe { mem:: zeroed :: < c_group > ( ) } ;
475
- let mut buf = vec ! [ 0 ; 2048 ] ; // TODO: Retry with larger buffer sizes
502
+ let mut buf = vec ! [ 0 ; 2048 ] ;
476
503
let mut result = ptr:: null_mut :: < c_group > ( ) ;
477
504
478
505
#[ cfg( feature = "logging" ) ]
479
506
trace ! ( "Running getgrnam_r for group {:?}" , groupname. as_ref( ) ) ;
480
507
481
- unsafe {
482
- libc:: getgrnam_r ( groupname. as_ptr ( ) , & mut group, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result) ;
508
+ loop {
509
+ let r = unsafe {
510
+ libc:: getgrnam_r ( groupname. as_ptr ( ) , & mut group, buf. as_mut_ptr ( ) , buf. len ( ) , & mut result)
511
+ } ;
512
+
513
+ if r != libc:: ERANGE {
514
+ break ;
515
+ }
516
+
517
+ let newsize = buf. len ( ) . checked_mul ( 2 ) ?;
518
+ buf. resize ( newsize, 0 ) ;
483
519
}
484
520
485
521
if result. is_null ( ) {
0 commit comments