MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cbm_posix_spawn_apple

Function cbm_posix_spawn_apple

src/foundation/subprocess.c:971–1014  ·  view source on GitHub ↗

macOS: spawn instead of fork+exec. * * fork() duplicates the parent's whole address space bookkeeping, and an * ASan-instrumented parent carries an enormous shadow mapping. Past a * footprint threshold the child is killed (jetsam) BEFORE exec replaces the * image, so the call fails with the child already gone (ESRCH on reap) — a * spawn failure that looks like the launched tool crashing. The

Source from the content-addressed store, hash-verified

969 * because dup2 clears close-on-exec.
970 * posix_spawnp keeps execvp's PATH semantics for a bare tool name. */
971static int cbm_posix_spawn_apple(cbm_subprocess_t *process, int input, int output, pid_t *pid_out) {
972 posix_spawn_file_actions_t actions;
973 posix_spawnattr_t attr;
974 if (posix_spawn_file_actions_init(&actions) != 0) {
975 return -1;
976 }
977 if (posix_spawnattr_init(&attr) != 0) {
978 (void)posix_spawn_file_actions_destroy(&actions);
979 return -1;
980 }
981 sigset_t empty_mask;
982 sigset_t all_signals;
983 sigemptyset(&empty_mask);
984 sigfillset(&all_signals);
985 short flags = (short)(POSIX_SPAWN_SETPGROUP | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK |
986 POSIX_SPAWN_CLOEXEC_DEFAULT);
987 bool configured = posix_spawnattr_setflags(&attr, flags) == 0 &&
988 posix_spawnattr_setpgroup(&attr, 0) == 0 &&
989 posix_spawnattr_setsigmask(&attr, &empty_mask) == 0 &&
990 posix_spawnattr_setsigdefault(&attr, &all_signals) == 0 &&
991 posix_spawn_file_actions_adddup2(&actions, input, STDIN_FILENO) == 0 &&
992 posix_spawn_file_actions_adddup2(&actions, output, STDOUT_FILENO) == 0 &&
993 posix_spawn_file_actions_adddup2(&actions, output, STDERR_FILENO) == 0;
994 pid_t pid = -1;
995 int rc =
996 configured ? posix_spawnp(&pid, process->bin, &actions, &attr, process->argv, environ) : -1;
997 (void)posix_spawn_file_actions_destroy(&actions);
998 (void)posix_spawnattr_destroy(&attr);
999 if (configured && rc == 0 && pid > 0) {
1000 *pid_out = pid;
1001 return 0;
1002 }
1003 /* posix_spawn reports an unusable binary itself, where fork+exec instead
1004 * produces a child that exits 127. Callers (and tests) rely on the latter:
1005 * "spawn_failed" means the SPAWN mechanism failed, not that the tool was
1006 * missing. Fall back to fork+exec for exec-class errors so macOS and Linux
1007 * classify a bogus binary identically; the ASan-fork hazard does not apply
1008 * here, since this child exits immediately. */
1009 if (configured && (rc == ENOENT || rc == EACCES || rc == ENOEXEC || rc == EISDIR ||
1010 rc == ELOOP || rc == ENAMETOOLONG || rc == ENOTDIR)) {
1011 return 1;
1012 }
1013 return -1;
1014}
1015#endif
1016
1017static int cbm_subprocess_spawn_posix(cbm_subprocess_t *process) {

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected