@@ -75,6 +75,7 @@ static int as_execvpe(const char *path, const char *file, char *const argv[],
7575 return -1 ;
7676}
7777
78+ #if !HAVE_RFORK
7879// In the child process, resets the signal mask to defaults. Also clears any
7980// signal handlers first so nothing funny happens.
8081static void reset_signals_child (void )
@@ -88,6 +89,7 @@ static void reset_signals_child(void)
8889 sigaction (nr , & sa , NULL );
8990 sigprocmask (SIG_SETMASK , & sigmask , NULL );
9091}
92+ #endif
9193
9294struct child_args {
9395 const char * path ;
@@ -116,7 +118,10 @@ static int child_main(void* args)
116118 return 0 ;
117119 }
118120
121+ // RFSPAWN has reset all signal actions in the child to default
122+ #if !HAVE_RFORK
119123 reset_signals_child ();
124+ #endif
120125
121126 for (int n = 0 ; n < opts -> num_fds ; n ++ ) {
122127 if (src_fds [n ] == opts -> fds [n ].fd ) {
@@ -134,7 +139,7 @@ static int child_main(void* args)
134139 as_execvpe (path , opts -> exe , opts -> args , opts -> env ? opts -> env : environ );
135140
136141child_failed :
137- #if HAVE_CLONE
142+ #if HAVE_CLONE || HAVE_RFORK
138143 * pipe_end = 1 ;
139144#else
140145 (void )write (* pipe_end , & (char ){1 }, 1 ); // shouldn't be able to fail
@@ -156,11 +161,16 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
156161 .detach = detach ,
157162 };
158163
159- #if HAVE_CLONE
164+ #if HAVE_CLONE || HAVE_RFORK
160165 const size_t stack_size = 0x8000 ;
161166 void * stack = mmap (NULL , stack_size , PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK , -1 , 0 );
162167 if (stack == MAP_FAILED )
163168 goto done ;
169+ #endif
170+
171+ #if HAVE_RFORK
172+ fres = rfork_thread (RFSPAWN , (int8_t * )stack + stack_size , child_main , & child_args );
173+ #elif HAVE_CLONE
164174 fres = clone (child_main , (int8_t * )stack + stack_size , CLONE_VM | CLONE_VFORK | SIGCHLD , & child_args );
165175#else
166176 int p [2 ] = {-1 , -1 };
@@ -186,7 +196,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
186196 goto done ;
187197 }
188198
189- #if HAVE_CLONE
199+ #if HAVE_CLONE || HAVE_RFORK
190200 r = child_args .pipe_end ;
191201#else
192202 if (fres == 0 ) {
@@ -209,7 +219,7 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
209219 }
210220
211221done :
212- #if HAVE_CLONE
222+ #if HAVE_CLONE || HAVE_RFORK
213223 munmap (stack , stack_size );
214224#else
215225 SAFE_CLOSE (p [0 ]);
@@ -224,14 +234,18 @@ static pid_t spawn_process_inner(const char *path, struct mp_subprocess_opts *op
224234static pid_t spawn_process (const char * path , struct mp_subprocess_opts * opts ,
225235 int src_fds [])
226236{
237+ #if !HAVE_RFORK
227238 sigset_t sigmask , oldmask ;
228239
229240 sigfillset (& sigmask );
230241 pthread_sigmask (SIG_BLOCK , & sigmask , & oldmask );
242+ #endif
231243
232244 pid_t fres = spawn_process_inner (path , opts , src_fds , opts -> detach );
233245
246+ #if !HAVE_RFORK
234247 pthread_sigmask (SIG_SETMASK , & oldmask , NULL );
248+ #endif
235249
236250 return fres ;
237251}
0 commit comments