@@ -81,6 +81,7 @@ static int as_execvpe(const char *path, const char *file, char *const argv[],
8181 return -1 ;
8282}
8383
84+ #if !HAVE_RFORK
8485// In the child process, resets the signal mask to defaults. Also clears any
8586// signal handlers first so nothing funny happens.
8687static void reset_signals_child (void )
@@ -94,6 +95,7 @@ static void reset_signals_child(void)
9495 sigemptyset (& sigmask );
9596 sigprocmask (SIG_SETMASK , & sigmask , NULL );
9697}
98+ #endif
9799
98100struct child_args {
99101 const char * path ;
@@ -122,7 +124,10 @@ static int child_main(void* args)
122124 return 0 ;
123125 }
124126
127+ // RFSPAWN has reset all signal actions in the child to default
128+ #if !HAVE_RFORK
125129 reset_signals_child ();
130+ #endif
126131
127132 for (int n = 0 ; n < opts -> num_fds ; n ++ ) {
128133 if (src_fds [n ] == opts -> fds [n ].fd ) {
@@ -140,7 +145,7 @@ static int child_main(void* args)
140145 as_execvpe (path , opts -> exe , opts -> args , opts -> env ? opts -> env : environ );
141146
142147child_failed :
143- #if HAVE_CLONE
148+ #if HAVE_CLONE || HAVE_RFORK
144149 * pipe_end = 1 ;
145150#else
146151 (void )write (* pipe_end , & (char ){1 }, 1 ); // shouldn't be able to fail
@@ -162,11 +167,16 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
162167 .detach = detach ,
163168 };
164169
165- #if HAVE_CLONE
170+ #if HAVE_CLONE || HAVE_RFORK
166171 const size_t stack_size = 0x8000 ;
167172 void * stack = mmap (NULL , stack_size , PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK , -1 , 0 );
168173 if (stack == MAP_FAILED )
169174 goto done ;
175+ #endif
176+
177+ #if HAVE_RFORK
178+ fres = rfork_thread (RFSPAWN , (int8_t * )stack + stack_size , child_main , & child_args );
179+ #elif HAVE_CLONE
170180 fres = clone (child_main , (int8_t * )stack + stack_size , CLONE_VM | CLONE_VFORK | SIGCHLD , & child_args );
171181#else
172182 int p [2 ] = {-1 , -1 };
@@ -192,7 +202,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
192202 goto done ;
193203 }
194204
195- #if HAVE_CLONE
205+ #if HAVE_CLONE || HAVE_RFORK
196206 r = child_args .pipe_end ;
197207#else
198208 if (fres == 0 ) {
@@ -215,7 +225,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
215225 }
216226
217227done :
218- #if HAVE_CLONE
228+ #if HAVE_CLONE || HAVE_RFORK
219229 munmap (stack , stack_size );
220230#else
221231 SAFE_CLOSE (p [0 ]);
@@ -230,14 +240,18 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
230240static pid_t spawn_process (const char * path , struct mp_subprocess_opts * opts ,
231241 int src_fds [])
232242{
243+ #if !HAVE_RFORK
233244 sigset_t sigmask , oldmask ;
234245
235246 sigfillset (& sigmask );
236247 pthread_sigmask (SIG_BLOCK , & sigmask , & oldmask );
248+ #endif
237249
238250 pid_t fres = spawn_process_inner (path , opts , src_fds , opts -> detach );
239251
252+ #if !HAVE_RFORK
240253 pthread_sigmask (SIG_SETMASK , & oldmask , NULL );
254+ #endif
241255
242256 return fres ;
243257}
0 commit comments