| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f0c0d69 commit 97f5003
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,5 @@ | |||
| 1 | 1 | /* | |
| 2 | - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. | ||
| 2 | + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | 4 | * | |
| 5 | 5 | * The Universal Permissive License (UPL), Version 1.0 | |
@@ -303,7 +303,7 @@ static int forkExec(VirtualFrame frame, Object[] args, Object executableList, bo | |||
| 303 | 303 | gil.release(true); | |
| 304 | 304 | try { | |
| 305 | 305 | return posixLib.forkExec(context.getPosixSupport(), executables, processArgs, cwd, env == null ? null : (Object[]) env, stdinRead, stdinWrite, stdoutRead, stdoutWrite, stderrRead, | |
| 306 | - stderrWrite, errPipeRead, errPipeWrite, closeFds, restoreSignals, callSetsid, fdsToKeep); | ||
| 306 | + stderrWrite, errPipeRead, errPipeWrite, closeFds, restoreSignals, callSetsid, fdsToKeep, allowVFork); | ||
| 307 | 307 | } catch (PosixException e) { | |
| 308 | 308 | gil.acquire(); | |
| 309 | 309 | throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2445,7 +2445,7 @@ public void unsetenv(Object name) { | |||
| 2445 | 2445 | @ExportMessage | |
| 2446 | 2446 | @TruffleBoundary | |
| 2447 | 2447 | public int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, int stderrReadFd, int stderrWriteFd, | |
| 2448 | - int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, | ||
| 2448 | + int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, boolean allowVFork, | ||
| 2449 | 2449 | @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode) throws PosixException { | |
| 2450 | 2450 | if (PythonImageBuildOptions.WITHOUT_PLATFORM_ACCESS) { | |
| 2451 | 2451 | throw new UnsupportedPosixFeatureException("forkExec was excluded"); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1114,13 +1114,13 @@ public void mmapWriteBytes(Object mmap, long index, byte[] bytes, int length, | |||
| 1114 | 1114 | ||
| 1115 | 1115 | @ExportMessage | |
| 1116 | 1116 | final int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, int stderrReadFd, int stderrWriteFd, | |
| 1117 | - int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, | ||
| 1117 | + int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, boolean allowVFork, | ||
| 1118 | 1118 | @CachedLibrary("this.delegate") PosixSupportLibrary lib) throws PosixException { | |
| 1119 | - logEnter("forkExec", "%s, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d, %d, %b, %b, %b, %s", executables, args, cwd, env, stdinReadFd, stdinWriteFd, stdoutReadFd, stdoutWriteFd, stderrReadFd, | ||
| 1120 | - stderrWriteFd, errPipeReadFd, errPipeWriteFd, closeFds, restoreSignals, callSetsid, fdsToKeep); | ||
| 1119 | + logEnter("forkExec", "%s, %s, %s, %s, %d, %d, %d, %d, %d, %d, %d, %d, %b, %b, %b, %s, %b", executables, args, cwd, env, stdinReadFd, stdinWriteFd, stdoutReadFd, stdoutWriteFd, stderrReadFd, | ||
| 1120 | + stderrWriteFd, errPipeReadFd, errPipeWriteFd, closeFds, restoreSignals, callSetsid, fdsToKeep, allowVFork); | ||
| 1121 | 1121 | try { | |
| 1122 | 1122 | return logExit("forkExec", "%d", lib.forkExec(delegate, executables, args, cwd, env, stdinReadFd, stdinWriteFd, stdoutReadFd, stdoutWriteFd, stderrReadFd, stderrWriteFd, errPipeReadFd, | |
| 1123 | - errPipeWriteFd, closeFds, restoreSignals, callSetsid, fdsToKeep)); | ||
| 1123 | + errPipeWriteFd, closeFds, restoreSignals, callSetsid, fdsToKeep, allowVFork)); | ||
| 1124 | 1124 | } catch (PosixException e) { | |
| 1125 | 1125 | throw logException("forkExec", e); | |
| 1126 | 1126 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -442,10 +442,10 @@ abstract static class PosixNativeFunctionInvoker { | |||
| 442 | 442 | ||
| 443 | 443 | @DowncallSignature(returnType = SINT32, argumentTypes = { | |
| 444 | 444 | POINTER, POINTER, SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, | |
| 445 | - SINT32, SINT32, SINT32, SINT32, SINT32, POINTER, SINT64 | ||
| 445 | + SINT32, SINT32, SINT32, SINT32, SINT32, SINT32, POINTER, SINT64 | ||
| 446 | 446 | }) | |
| 447 | 447 | abstract int fork_exec(long data, long offsets, int offsetsLen, int argsPos, int envPos, int cwdPos, int stdinRdFd, int stdinWrFd, int stdoutRdFd, int stdoutWrFd, int stderrRdFd, | |
| 448 | - int stderrWrFd, int errPipeRdFd, int errPipeWrFd, int closeFds, int restoreSignals, int callSetsid, long fdsToKeep, long fdsToKeepLen); | ||
| 448 | + int stderrWrFd, int errPipeRdFd, int errPipeWrFd, int closeFds, int restoreSignals, int callSetsid, int allowVFork, long fdsToKeep, long fdsToKeepLen); | ||
| 449 | 449 | ||
| 450 | 450 | @DowncallSignature(returnType = VOID, argumentTypes = {POINTER, POINTER, SINT32}) | |
| 451 | 451 | abstract void call_execv(long data, long offsets, int offsetsLen); | |
@@ -1845,7 +1845,7 @@ public void unsetenv(Object name) throws PosixException { | |||
| 1845 | 1845 | ||
| 1846 | 1846 | @ExportMessage | |
| 1847 | 1847 | public int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, int stderrReadFd, int stderrWriteFd, | |
| 1848 | - int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep) throws PosixException { | ||
| 1848 | + int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, boolean allowVFork) throws PosixException { | ||
| 1849 | 1849 | ||
| 1850 | 1850 | // The following strings and string arrays need to be present in the native function: | |
| 1851 | 1851 | // - char** of executable names ('\0'-terminated strings with an extra NULL at the end) | |
@@ -1943,6 +1943,7 @@ public int forkExec(Object[] executables, Object[] args, Object cwd, Object[] en | |||
| 1943 | 1943 | closeFds ? 1 : 0, | |
| 1944 | 1944 | restoreSignals ? 1 : 0, | |
| 1945 | 1945 | callSetsid ? 1 : 0, | |
| 1946 | + allowVFork ? 1 : 0, | ||
| 1946 | 1947 | nativeFdsToKeep, fdsToKeep.length); | |
| 1947 | 1948 | if (res == -1) { | |
| 1948 | 1949 | throw getErrnoAndThrowPosixException(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -355,7 +355,8 @@ public record OpenPtyResult(int masterFd, int slaveFd) { | |||
| 355 | 355 | public abstract void unsetenv(Object receiver, Object name) throws PosixException; | |
| 356 | 356 | ||
| 357 | 357 | public abstract int forkExec(Object receiver, Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, | |
| 358 | - int stderrReadFd, int stderrWriteFd, int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep) throws PosixException; | ||
| 358 | + int stderrReadFd, int stderrWriteFd, int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, | ||
| 359 | + boolean allowVFork) throws PosixException; | ||
| 359 | 360 | ||
| 360 | 361 | // args.length must be > 0 | |
| 361 | 362 | public abstract void execv(Object receiver, Object pathname, Object[] args) throws PosixException; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -807,11 +807,11 @@ final void unsetenv(Object name, | |||
| 807 | 807 | ||
| 808 | 808 | @ExportMessage | |
| 809 | 809 | final int forkExec(Object[] executables, Object[] args, Object cwd, Object[] env, int stdinReadFd, int stdinWriteFd, int stdoutReadFd, int stdoutWriteFd, int stderrReadFd, int stderrWriteFd, | |
| 810 | - int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, | ||
| 810 | + int errPipeReadFd, int errPipeWriteFd, boolean closeFds, boolean restoreSignals, boolean callSetsid, int[] fdsToKeep, boolean allowVFork, | ||
| 811 | 811 | @CachedLibrary("this.nativePosixSupport") PosixSupportLibrary nativeLib) throws PosixException { | |
| 812 | 812 | checkNotInPreInitialization(); | |
| 813 | 813 | return nativeLib.forkExec(nativePosixSupport, executables, args, cwd, env, stdinReadFd, stdinWriteFd, stdoutReadFd, stdoutWriteFd, stderrReadFd, stderrWriteFd, errPipeReadFd, errPipeWriteFd, | |
| 814 | - closeFds, restoreSignals, callSetsid, fdsToKeep); | ||
| 814 | + closeFds, restoreSignals, callSetsid, fdsToKeep, allowVFork); | ||
| 815 | 815 | } | |
| 816 | 816 | ||
| 817 | 817 | @ExportMessage | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,15 +11,34 @@ | |||
| 11 | 11 | #include <fcntl.h> | |
| 12 | 12 | #include <sys/types.h> | |
| 13 | 13 | #include <sys/stat.h> | |
| 14 | + #if defined(__linux__) | ||
| 15 | + #include <sys/syscall.h> | ||
| 16 | + #endif | ||
| 14 | 17 | #include <dirent.h> | |
| 15 | 18 | #include <errno.h> | |
| 16 | 19 | #include <assert.h> | |
| 17 | 20 | #include <string.h> | |
| 21 | + #include <limits.h> | ||
| 22 | + #include <signal.h> | ||
| 18 | 23 | ||
| 19 | 24 | // These definitions emulate CPython's equivalents so that the copy&pasted code below works without too many changes | |
| 20 | 25 | #define HAVE_DIRFD 1 | |
| 21 | 26 | #define HAVE_SETSID 1 | |
| 22 | 27 | ||
| 28 | + #if defined(__GNUC__) || defined(__clang__) | ||
| 29 | + #define Py_NO_INLINE __attribute__((noinline)) | ||
| 30 | + #elif defined(_MSC_VER) | ||
| 31 | + #define Py_NO_INLINE __declspec(noinline) | ||
| 32 | + #else | ||
| 33 | + #define Py_NO_INLINE | ||
| 34 | + #endif | ||
| 35 | + | ||
| 36 | + #if defined(__linux__) | ||
| 37 | + /* If this is ever expanded to non-Linux platforms, verify what calls are | ||
| 38 | + * allowed after vfork(). Ex: setsid() may be disallowed on macOS? */ | ||
| 39 | + #define VFORK_USABLE 1 | ||
| 40 | + #endif | ||
| 41 | + | ||
| 23 | 42 | int32_t set_inheritable(int32_t fd, int32_t inheritable); | |
| 24 | 43 | ||
| 25 | 44 | // TODO JDK also handles EINTR for dup2 calls | |
@@ -176,6 +195,47 @@ _close_fds_by_brute_force(long start_fd, int *fds_to_keep, ssize_t num_fds_to_ke | |||
| 176 | 195 | } | |
| 177 | 196 | } | |
| 178 | 197 | ||
| 198 | + #if defined(__linux__) && defined(SYS_getdents64) | ||
| 199 | + struct linux_dirent64 { | ||
| 200 | + unsigned long long d_ino; | ||
| 201 | + long long d_off; | ||
| 202 | + unsigned short d_reclen; | ||
| 203 | + unsigned char d_type; | ||
| 204 | + char d_name[256]; | ||
| 205 | + }; | ||
| 206 | + | ||
| 207 | + static void | ||
| 208 | + _close_open_fds_safe(long start_fd, int *fds_to_keep, ssize_t fds_to_keep_len) | ||
| 209 | + { | ||
| 210 | + int fd_dir_fd = open(FD_DIR, O_RDONLY); | ||
| 211 | + if (fd_dir_fd == -1) { | ||
| 212 | + _close_fds_by_brute_force(start_fd, fds_to_keep, fds_to_keep_len); | ||
| 213 | + return; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + char buffer[sizeof(struct linux_dirent64)]; | ||
| 217 | + int bytes; | ||
| 218 | + while ((bytes = syscall(SYS_getdents64, fd_dir_fd, (struct linux_dirent64 *)buffer, sizeof(buffer))) > 0) { | ||
| 219 | + struct linux_dirent64 *entry; | ||
| 220 | + int offset; | ||
| 221 | + for (offset = 0; offset < bytes; offset += entry->d_reclen) { | ||
| 222 | + int fd; | ||
| 223 | + entry = (struct linux_dirent64 *)(buffer + offset); | ||
| 224 | + if ((fd = _pos_int_from_ascii(entry->d_name)) < 0) | ||
| 225 | + continue; | ||
| 226 | + if (fd != fd_dir_fd && fd >= start_fd && | ||
| 227 | + !_is_fd_in_sorted_fd_sequence(fd, fds_to_keep, fds_to_keep_len)) { | ||
| 228 | + close(fd); | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + close(fd_dir_fd); | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + #define _close_open_fds _close_open_fds_safe | ||
| 236 | + | ||
| 237 | + #else | ||
| 238 | + | ||
| 179 | 239 | /* Close all open file descriptors from start_fd and higher. | |
| 180 | 240 | * Do not close any in the sorted py_fds_to_keep tuple. | |
| 181 | 241 | * | |
@@ -242,6 +302,36 @@ _close_open_fds_maybe_unsafe(long start_fd, int* fds_to_keep, ssize_t fds_to_kee | |||
| 242 | 302 | ||
| 243 | 303 | #define _close_open_fds _close_open_fds_maybe_unsafe | |
| 244 | 304 | ||
| 305 | + #endif | ||
| 306 | + | ||
| 307 | + #ifdef VFORK_USABLE | ||
| 308 | + static void | ||
| 309 | + reset_signal_handlers(const sigset_t *child_sigmask) | ||
| 310 | + { | ||
| 311 | + struct sigaction sa_dfl = {.sa_handler = SIG_DFL}; | ||
| 312 | + for (int sig = 1; sig < _NSIG; sig++) { | ||
| 313 | + if (sig == SIGKILL || sig == SIGSTOP) { | ||
| 314 | + continue; | ||
| 315 | + } | ||
| 316 | + if (sigismember(child_sigmask, sig) == 1) { | ||
| 317 | + continue; | ||
| 318 | + } | ||
| 319 | + | ||
| 320 | + struct sigaction sa; | ||
| 321 | + if (sigaction(sig, NULL, &sa) == -1) { | ||
| 322 | + continue; | ||
| 323 | + } | ||
| 324 | + | ||
| 325 | + void *h = (sa.sa_flags & SA_SIGINFO ? (void *)sa.sa_sigaction : | ||
| 326 | + (void *)sa.sa_handler); | ||
| 327 | + if (h == SIG_IGN || h == SIG_DFL) { | ||
| 328 | + continue; | ||
| 329 | + } | ||
| 330 | + (void) sigaction(sig, &sa_dfl, NULL); | ||
| 331 | + } | ||
| 332 | + } | ||
| 333 | + #endif | ||
| 334 | + | ||
| 245 | 335 | /* | |
| 246 | 336 | * This function is code executed in the child process immediately after fork | |
| 247 | 337 | * to set things up and call exec(). | |
@@ -252,8 +342,11 @@ _close_open_fds_maybe_unsafe(long start_fd, int* fds_to_keep, ssize_t fds_to_kee | |||
| 252 | 342 | * | |
| 253 | 343 | * This restriction is documented at | |
| 254 | 344 | * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html. | |
| 345 | + * | ||
| 346 | + * If this function is called after vfork(), even more care must be taken. | ||
| 347 | + * The child shares the parent's address space until execve() or _exit(). | ||
| 255 | 348 | */ | |
| 256 | - static void | ||
| 349 | + Py_NO_INLINE static void | ||
| 257 | 350 | child_exec(char *const exec_array[], | |
| 258 | 351 | char *const argv[], | |
| 259 | 352 | char *const envp[], | |
@@ -264,6 +357,7 @@ child_exec(char *const exec_array[], | |||
| 264 | 357 | int errpipe_read, int errpipe_write, | |
| 265 | 358 | int close_fds, int restore_signals, | |
| 266 | 359 | int call_setsid, | |
| 360 | + const void *child_sigmask, | ||
| 267 | 361 | int *fds_to_keep, | |
| 268 | 362 | ssize_t fds_to_keep_len) | |
| 269 | 363 | { | |
@@ -338,6 +432,15 @@ child_exec(char *const exec_array[], | |||
| 338 | 432 | if (restore_signals) | |
| 339 | 433 | _Py_RestoreSignals(); | |
| 340 | 434 | ||
| 435 | + #ifdef VFORK_USABLE | ||
| 436 | + if (child_sigmask) { | ||
| 437 | + reset_signal_handlers((const sigset_t *)child_sigmask); | ||
| 438 | + if ((errno = pthread_sigmask(SIG_SETMASK, child_sigmask, NULL))) { | ||
| 439 | + goto error; | ||
| 440 | + } | ||
| 441 | + } | ||
| 442 | + #endif | ||
| 443 | + | ||
| 341 | 444 | #ifdef HAVE_SETSID | |
| 342 | 445 | if (call_setsid) | |
| 343 | 446 | POSIX_CALL(setsid()); | |
@@ -394,6 +497,49 @@ child_exec(char *const exec_array[], | |||
| 394 | 497 | _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg)); | |
| 395 | 498 | } | |
| 396 | 499 | ||
| 500 | + Py_NO_INLINE static pid_t | ||
| 501 | + do_fork_exec(char *const exec_list[], | ||
| 502 | + char *const argv[], | ||
| 503 | + char *const envp[], | ||
| 504 | + const char *cwd, | ||
| 505 | + int stdinRdFd, int stdinWrFd, | ||
| 506 | + int stdoutRdFd, int stdoutWrFd, | ||
| 507 | + int stderrRdFd, int stderrWrFd, | ||
| 508 | + int errPipeRdFd, int errPipeWrFd, | ||
| 509 | + int closeFds, int restoreSignals, | ||
| 510 | + int callSetsid, | ||
| 511 | + const void *childSigmask, | ||
| 512 | + int *fdsToKeep, int64_t fdsToKeepLen) | ||
| 513 | + { | ||
| 514 | + pid_t pid; | ||
| 515 | + #ifdef VFORK_USABLE | ||
| 516 | + if (childSigmask) { | ||
| 517 | + pid = vfork(); | ||
| 518 | + } else | ||
| 519 | + #endif | ||
| 520 | + { | ||
| 521 | + pid = fork(); | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + if (pid != 0) { | ||
| 525 | + return pid; | ||
| 526 | + } | ||
| 527 | + | ||
| 528 | + child_exec( | ||
| 529 | + exec_list, argv, envp, cwd, | ||
| 530 | + stdinRdFd, stdinWrFd, | ||
| 531 | + stdoutRdFd, stdoutWrFd, | ||
| 532 | + stderrRdFd, stderrWrFd, | ||
| 533 | + errPipeRdFd, errPipeWrFd, | ||
| 534 | + closeFds, | ||
| 535 | + restoreSignals, | ||
| 536 | + callSetsid, | ||
| 537 | + childSigmask, | ||
| 538 | + fdsToKeep, fdsToKeepLen | ||
| 539 | + ); | ||
| 540 | + _exit(255); | ||
| 541 | + } | ||
| 542 | + | ||
| 397 | 543 | ||
| 398 | 544 | /* | |
| 399 | 545 | * data, offsets, offsetsLen, argsPos, envPos, cwdPos - see comment in NativePosixSupport.forkExec() | |
@@ -412,6 +558,7 @@ child_exec(char *const exec_array[], | |||
| 412 | 558 | * (if nonzero, then errPipeWrFd must be in fdsToKeep) | |
| 413 | 559 | * restoreSignals - currently not used | |
| 414 | 560 | * callSetsid - if nonzero, the child calls setsid before exec() | |
| 561 | + * allowVFork - if nonzero, use vfork() instead of fork() where it is safe and supported | ||
| 415 | 562 | * fdsToKeep, fdsToKeepLen - a sorted list of fds to keep open (the child clears their O_CLOEXEC) | |
| 416 | 563 | */ | |
| 417 | 564 | int32_t fork_exec( | |
@@ -423,6 +570,7 @@ int32_t fork_exec( | |||
| 423 | 570 | int32_t closeFds, | |
| 424 | 571 | int32_t restoreSignals, | |
| 425 | 572 | int32_t callSetsid, | |
| 573 | + int32_t allowVFork, | ||
| 426 | 574 | int32_t *fdsToKeep, int64_t fdsToKeepLen | |
| 427 | 575 | ) { | |
| 428 | 576 | ||
@@ -437,20 +585,41 @@ int32_t fork_exec( | |||
| 437 | 585 | char **envp = envPos == -1 ? NULL : strings + envPos; | |
| 438 | 586 | char *cwd = cwdPos == -1 ? NULL : strings[cwdPos]; | |
| 439 | 587 | ||
| 440 | - pid_t pid = fork(); | ||
| 441 | - if (pid == 0) { | ||
| 442 | - child_exec( | ||
| 443 | - exec_list, argv, envp, cwd, | ||
| 444 | - stdinRdFd, stdinWrFd, | ||
| 445 | - stdoutRdFd, stdoutWrFd, | ||
| 446 | - stderrRdFd, stderrWrFd, | ||
| 447 | - errPipeRdFd, errPipeWrFd, | ||
| 448 | - closeFds, | ||
| 449 | - restoreSignals, | ||
| 450 | - callSetsid, | ||
| 451 | - fdsToKeep, fdsToKeepLen | ||
| 452 | - ); | ||
| 453 | - _exit(255); | ||
| 588 | + #ifdef VFORK_USABLE | ||
| 589 | + const void *oldSigmask = NULL; | ||
| 590 | + sigset_t oldSigs; | ||
| 591 | + if (allowVFork) { | ||
| 592 | + sigset_t allSigs; | ||
| 593 | + sigfillset(&allSigs); | ||
| 594 | + int err = pthread_sigmask(SIG_BLOCK, &allSigs, &oldSigs); | ||
| 595 | + if (err) { | ||
| 596 | + errno = err; | ||
| 597 | + return -1; | ||
| 598 | + } | ||
| 599 | + oldSigmask = &oldSigs; | ||
| 600 | + } | ||
| 601 | + #else | ||
| 602 | + const void *oldSigmask = NULL; | ||
| 603 | + #endif | ||
| 604 | + | ||
| 605 | + pid_t pid = do_fork_exec( | ||
| 606 | + exec_list, argv, envp, cwd, | ||
| 607 | + stdinRdFd, stdinWrFd, | ||
| 608 | + stdoutRdFd, stdoutWrFd, | ||
| 609 | + stderrRdFd, stderrWrFd, | ||
| 610 | + errPipeRdFd, errPipeWrFd, | ||
| 611 | + closeFds, | ||
| 612 | + restoreSignals, | ||
| 613 | + callSetsid, | ||
| 614 | + oldSigmask, | ||
| 615 | + fdsToKeep, fdsToKeepLen | ||
| 616 | + ); | ||
| 617 | + | ||
| 618 | + #ifdef VFORK_USABLE | ||
| 619 | + if (oldSigmask) { | ||
| 620 | + (void) pthread_sigmask(SIG_SETMASK, oldSigmask, NULL); | ||
| 454 | 621 | } | |
| 622 | + #endif | ||
| 623 | + | ||
| 455 | 624 | return pid; | |
| 456 | 625 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments