@@ -343,21 +343,6 @@ impl Drop for PosixSpawnFileActions {
343343 }
344344}
345345
346- // The POSIX standard requires those `args` and `envp` to be of type `*const *mut [c_char]`,
347- // but implementations won't modify them, making the `mut` type redundant. Considering this,
348- // Nix does not expose this mutability, but we have to change the interface when calling the
349- // underlying libc interfaces , this helper function does the conversion job.
350- //
351- // SAFETY:
352- // It is safe to add the mutability in types as implementations won't mutable them.
353- unsafe fn to_exec_array < S : AsRef < CStr > > ( args : & [ S ] ) -> Vec < * mut libc:: c_char > {
354- use std:: iter:: once;
355- args. iter ( )
356- . map ( |s| s. as_ref ( ) . as_ptr ( ) . cast_mut ( ) )
357- . chain ( once ( std:: ptr:: null_mut ( ) ) )
358- . collect ( )
359- }
360-
361346/// Create a new child process from the specified process image. See
362347/// [posix_spawn](https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html).
363348pub fn posix_spawn < P , SA , SE > (
@@ -374,19 +359,24 @@ where
374359{
375360 let mut pid = 0 ;
376361
377- let ret = unsafe {
378- let args_p = to_exec_array ( args) ;
379- let env_p = to_exec_array ( envp) ;
380-
362+ let ret = {
381363 path. with_nix_path ( |c_str| {
382- libc:: posix_spawn (
383- & mut pid as * mut libc:: pid_t ,
384- c_str. as_ptr ( ) ,
385- & file_actions. fa as * const libc:: posix_spawn_file_actions_t ,
386- & attr. attr as * const libc:: posix_spawnattr_t ,
387- args_p. as_ptr ( ) ,
388- env_p. as_ptr ( ) ,
389- )
364+ let args_p = crate :: c_slice_to_pointers ( args) ;
365+ let env_p = crate :: c_slice_to_pointers ( envp) ;
366+
367+ // SAFETY: The POSIX standard specifies `argv` and `envp` as `*const *mut c_char`,
368+ // but also states that these arrays and their strings shall not be modified,
369+ // so passing immutable data is sound.
370+ unsafe {
371+ libc:: posix_spawn (
372+ & mut pid as * mut libc:: pid_t ,
373+ c_str. as_ptr ( ) ,
374+ & file_actions. fa as * const libc:: posix_spawn_file_actions_t ,
375+ & attr. attr as * const libc:: posix_spawnattr_t ,
376+ args_p. as_ptr ( ) as * const * mut _ ,
377+ env_p. as_ptr ( ) as * const * mut _ ,
378+ )
379+ }
390380 } ) ?
391381 } ;
392382
@@ -408,18 +398,23 @@ pub fn posix_spawnp<SA: AsRef<CStr>, SE: AsRef<CStr>>(
408398) -> Result < Pid > {
409399 let mut pid = 0 ;
410400
411- let ret = unsafe {
412- let args_p = to_exec_array ( args) ;
413- let env_p = to_exec_array ( envp) ;
414-
415- libc:: posix_spawnp (
416- & mut pid as * mut libc:: pid_t ,
417- path. as_ptr ( ) ,
418- & file_actions. fa as * const libc:: posix_spawn_file_actions_t ,
419- & attr. attr as * const libc:: posix_spawnattr_t ,
420- args_p. as_ptr ( ) ,
421- env_p. as_ptr ( ) ,
422- )
401+ let ret = {
402+ let args_p = crate :: c_slice_to_pointers ( args) ;
403+ let env_p = crate :: c_slice_to_pointers ( envp) ;
404+
405+ // SAFETY: The POSIX standard specifies `argv` and `envp` as `*const *mut c_char`,
406+ // but also states that these arrays and their strings shall not be modified,
407+ // so passing immutable data is sound.
408+ unsafe {
409+ libc:: posix_spawnp (
410+ & mut pid as * mut libc:: pid_t ,
411+ path. as_ptr ( ) ,
412+ & file_actions. fa as * const libc:: posix_spawn_file_actions_t ,
413+ & attr. attr as * const libc:: posix_spawnattr_t ,
414+ args_p. as_ptr ( ) as * const * mut _ ,
415+ env_p. as_ptr ( ) as * const * mut _ ,
416+ )
417+ }
423418 } ;
424419
425420 if ret != 0 {
0 commit comments