@@ -81,8 +81,6 @@ use std::fs::File;
8181use std:: ffi:: CStr ;
8282use std:: io;
8383use std:: ops:: RangeInclusive ;
84- #[ cfg( target_os = "linux" ) ]
85- use std:: sync:: OnceLock ;
8684use std:: {
8785 env,
8886 ffi:: { self , CString , OsString } ,
@@ -456,145 +454,49 @@ impl SpawnWorker {
456454 // if we're here then exec has failed
457455 let fexecve_error = std:: io:: Error :: last_os_error ( ) ;
458456
459- // When DD_SPAWN_WORKER_STABLE_TRAMPOLINE is set, write the trampoline to
460- // a stable per-process path so Valgrind can open it for debug symbols
461- // before exec completes. Default (unset): keep the random-path behaviour.
462- let stable_env_key = b"DD_SPAWN_WORKER_STABLE_TRAMPOLINE \0 " ;
463- let use_stable = {
464- let val = libc :: getenv ( stable_env_key . as_ptr ( ) as * const libc :: c_char ) ;
465- !val . is_null ( )
457+ let mut temp_path = [ 0u8 ; 256 ] ;
458+ let tmpdir = libc :: getenv ( "TMPDIR" . as_ptr ( ) as * const libc :: c_char )
459+ as * const libc :: c_char ;
460+ let tmpdir = if tmpdir . is_null ( ) {
461+ b"/tmp"
462+ } else {
463+ CStr :: from_ptr ( tmpdir ) . to_bytes ( )
466464 } ;
467-
468- if use_stable {
469- // Stack-allocated path /tmp/.dd-trampoline-<pid> — no heap post-fork.
470- let mut path_buf = [ 0u8 ; 48 ] ;
471- {
472- let prefix = b"/tmp/.dd-trampoline-" ;
473- path_buf[ ..prefix. len ( ) ] . copy_from_slice ( prefix) ;
474- let mut n = libc:: getpid ( ) as u32 ;
475- let mut digits = [ 0u8 ; 20 ] ;
476- let mut nd = 0usize ;
477- loop {
478- digits[ nd] = b'0' + ( n % 10 ) as u8 ;
479- nd += 1 ;
480- n /= 10 ;
481- if n == 0 {
482- break ;
483- }
484- }
485- digits[ ..nd] . reverse ( ) ;
486- path_buf[ prefix. len ( ) ..prefix. len ( ) + nd]
487- . copy_from_slice ( & digits[ ..nd] ) ;
488- }
489- let path_ptr = path_buf. as_ptr ( ) as * const libc:: c_char ;
490-
491- // Fork-safe atexit: recomputes path from getpid() so each process
492- // cleans up its own file.
493- extern "C" fn cleanup_trampoline ( ) {
494- unsafe {
495- let mut buf = [ 0u8 ; 48 ] ;
496- let prefix = b"/tmp/.dd-trampoline-" ;
497- buf[ ..prefix. len ( ) ] . copy_from_slice ( prefix) ;
498- let mut n = libc:: getpid ( ) as u32 ;
499- let mut digits = [ 0u8 ; 20 ] ;
500- let mut nd = 0usize ;
501- loop {
502- digits[ nd] = b'0' + ( n % 10 ) as u8 ;
503- nd += 1 ;
504- n /= 10 ;
505- if n == 0 {
506- break ;
507- }
508- }
509- digits[ ..nd] . reverse ( ) ;
510- buf[ prefix. len ( ) ..prefix. len ( ) + nd] . copy_from_slice ( & digits[ ..nd] ) ;
511- libc:: unlink ( buf. as_ptr ( ) as * const libc:: c_char ) ;
512- }
465+ if tmpdir. len ( ) < 220 {
466+ temp_path[ ..tmpdir. len ( ) ] . copy_from_slice ( tmpdir) ;
467+ let mut off = tmpdir. len ( ) ;
468+ let spawn_prefix = b"/dd-ipc-spawn_" ;
469+ temp_path[ off..off + spawn_prefix. len ( ) ] . copy_from_slice ( spawn_prefix) ;
470+ off += spawn_prefix. len ( ) ;
471+ for _ in 0 ..8 {
472+ temp_path[ off] = fastrand:: alphanumeric ( ) as u8 ;
473+ off += 1 ;
513474 }
514475
515- // Presence-only lock — after fork, the child inherits the state but
516- // cleanup_trampoline recomputes the path via getpid().
517- static ATEXIT_REGISTERED : OnceLock < ( ) > = OnceLock :: new ( ) ;
518-
476+ let path = Vec :: from_raw_parts ( temp_path. as_mut_ptr ( ) , off, off) ;
477+ let path = CString :: from_vec_with_nul_unchecked ( path) ;
478+ let path_ptr = path. as_ptr ( ) ;
519479 let tmpfd = libc:: open (
520480 path_ptr,
521- libc:: O_CREAT | libc:: O_EXCL | libc :: O_RDWR ,
481+ libc:: O_CREAT | libc:: O_RDWR ,
522482 libc:: S_IRWXU as libc:: c_uint ,
523483 ) ;
524- if tmpfd >= 0 {
525- let written = libc:: sendfile (
484+ if tmpfd < 0 {
485+ // We'll leak it, executing Drop of path is forbidden.
486+ std:: mem:: forget ( path) ;
487+ } else {
488+ libc:: sendfile (
526489 tmpfd,
527490 fd. as_raw_fd ( ) ,
528491 std:: ptr:: null_mut ( ) ,
529492 crate :: TRAMPOLINE_BIN . len ( ) ,
530493 ) ;
531494 libc:: close ( tmpfd) ;
532- if written < 0 || written as usize != crate :: TRAMPOLINE_BIN . len ( ) {
533- // Partial / failed write — remove corrupt file and fall
534- // through to the panic below.
535- libc:: unlink ( path_ptr) ;
536- } else {
537- ATEXIT_REGISTERED . get_or_init ( || {
538- libc:: atexit ( cleanup_trampoline) ;
539- } ) ;
540- // argv[1] is "" — trampoline skips unlink when *argv[1] == '\0'.
541- libc:: execve ( path_ptr, argv. as_ptr ( ) , envp. as_ptr ( ) ) ;
542- // execve failed — remove file so next attempt recreates it.
543- libc:: unlink ( path_ptr) ;
544- }
545- } else {
546- // O_EXCL failed: same-PID orphan (killed before atexit). Reuse it.
547- ATEXIT_REGISTERED . get_or_init ( || {
548- libc:: atexit ( cleanup_trampoline) ;
549- } ) ;
495+ argv. set ( 1 , path) ;
496+
550497 libc:: execve ( path_ptr, argv. as_ptr ( ) , envp. as_ptr ( ) ) ;
551- libc:: unlink ( path_ptr) ;
552- }
553- } else {
554- let mut temp_path = [ 0u8 ; 256 ] ;
555- let tmpdir = libc:: getenv ( "TMPDIR" . as_ptr ( ) as * const libc:: c_char )
556- as * const libc:: c_char ;
557- let tmpdir = if tmpdir. is_null ( ) {
558- b"/tmp"
559- } else {
560- CStr :: from_ptr ( tmpdir) . to_bytes ( )
561- } ;
562- if tmpdir. len ( ) < 220 {
563- temp_path[ ..tmpdir. len ( ) ] . copy_from_slice ( tmpdir) ;
564- let mut off = tmpdir. len ( ) ;
565- let spawn_prefix = b"/dd-ipc-spawn_" ;
566- temp_path[ off..off + spawn_prefix. len ( ) ] . copy_from_slice ( spawn_prefix) ;
567- off += spawn_prefix. len ( ) ;
568- for _ in 0 ..8 {
569- temp_path[ off] = fastrand:: alphanumeric ( ) as u8 ;
570- off += 1 ;
571- }
572-
573- let path = Vec :: from_raw_parts ( temp_path. as_mut_ptr ( ) , off, off) ;
574- let path = CString :: from_vec_with_nul_unchecked ( path) ;
575- let path_ptr = path. as_ptr ( ) ;
576- let tmpfd = libc:: open (
577- path_ptr,
578- libc:: O_CREAT | libc:: O_RDWR ,
579- libc:: S_IRWXU as libc:: c_uint ,
580- ) ;
581- if tmpfd < 0 {
582- // We'll leak it, executing Drop of path is forbidden.
583- std:: mem:: forget ( path) ;
584- } else {
585- libc:: sendfile (
586- tmpfd,
587- fd. as_raw_fd ( ) ,
588- std:: ptr:: null_mut ( ) ,
589- crate :: TRAMPOLINE_BIN . len ( ) ,
590- ) ;
591- libc:: close ( tmpfd) ;
592- argv. set ( 1 , path) ;
593-
594- libc:: execve ( path_ptr, argv. as_ptr ( ) , envp. as_ptr ( ) ) ;
595-
596- libc:: unlink ( temp_path. as_ptr ( ) as * const libc:: c_char ) ;
597- }
498+
499+ libc:: unlink ( temp_path. as_ptr ( ) as * const libc:: c_char ) ;
598500 }
599501 }
600502
0 commit comments