21 extern "C" char **environ;
25 static std::mutex SignalMutex;
28 static int ActiveThreadCount = 0;
29 static struct sigaction OldSigIntAction;
30 static struct sigaction OldSigQuitAction;
31 static sigset_t OldBlockedSignalsSet;
40 posix_spawnattr_t SpawnAttributes;
41 if (posix_spawnattr_init(&SpawnAttributes))
46 std::lock_guard<std::mutex>
Lock(SignalMutex);
47 if (ActiveThreadCount == 0) {
48 static struct sigaction IgnoreSignalAction;
49 sigset_t BlockedSignalsSet;
50 memset(&IgnoreSignalAction, 0,
sizeof(IgnoreSignalAction));
51 IgnoreSignalAction.sa_handler = SIG_IGN;
53 if (sigaction(SIGINT, &IgnoreSignalAction, &OldSigIntAction) == -1) {
54 Printf(
"Failed to ignore SIGINT\n");
55 (void)posix_spawnattr_destroy(&SpawnAttributes);
58 if (sigaction(SIGQUIT, &IgnoreSignalAction, &OldSigQuitAction) == -1) {
59 Printf(
"Failed to ignore SIGQUIT\n");
61 (void)sigaction(SIGINT, &OldSigIntAction, NULL);
62 (void)posix_spawnattr_destroy(&SpawnAttributes);
66 (void)sigemptyset(&BlockedSignalsSet);
67 (void)sigaddset(&BlockedSignalsSet, SIGCHLD);
68 if (sigprocmask(SIG_BLOCK, &BlockedSignalsSet, &OldBlockedSignalsSet) ==
70 Printf(
"Failed to block SIGCHLD\n");
72 (void)sigaction(SIGQUIT, &OldSigQuitAction, NULL);
73 (void)sigaction(SIGINT, &OldSigIntAction, NULL);
74 (void)posix_spawnattr_destroy(&SpawnAttributes);
87 sigset_t DefaultSigSet;
88 (void)sigemptyset(&DefaultSigSet);
89 (void)sigaddset(&DefaultSigSet, SIGQUIT);
90 (void)sigaddset(&DefaultSigSet, SIGINT);
91 (void)posix_spawnattr_setsigdefault(&SpawnAttributes, &DefaultSigSet);
93 (void)posix_spawnattr_setsigmask(&SpawnAttributes, &OldBlockedSignalsSet);
94 short SpawnFlags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
95 (void)posix_spawnattr_setflags(&SpawnAttributes, SpawnFlags);
98 char **Environ = environ;
99 const char *CommandCStr = Command.c_str();
100 const char *Argv[] = {
"sh",
"-c", CommandCStr, NULL};
101 int ErrorCode = 0, ProcessStatus = 0;
103 ErrorCode = posix_spawn(&Pid,
"/bin/sh", NULL, &SpawnAttributes,
104 (
char *
const *)Argv, Environ);
105 (void)posix_spawnattr_destroy(&SpawnAttributes);
107 pid_t SavedPid = Pid;
110 Pid = waitpid(SavedPid, &ProcessStatus, 0);
111 }
while (Pid == -1 && errno == EINTR);
116 }
else if (ErrorCode == ENOMEM || ErrorCode == EAGAIN) {
121 ProcessStatus = W_EXITCODE(127, 0);
127 std::lock_guard<std::mutex>
Lock(SignalMutex);
129 if (ActiveThreadCount == 0) {
130 bool FailedRestore =
false;
131 if (sigaction(SIGINT, &OldSigIntAction, NULL) == -1) {
132 Printf(
"Failed to restore SIGINT handling\n");
133 FailedRestore =
true;
135 if (sigaction(SIGQUIT, &OldSigQuitAction, NULL) == -1) {
136 Printf(
"Failed to restore SIGQUIT handling\n");
137 FailedRestore =
true;
139 if (sigprocmask(SIG_BLOCK, &OldBlockedSignalsSet, NULL) == -1) {
140 Printf(
"Failed to unblock SIGCHLD\n");
141 FailedRestore =
true;
147 return ProcessStatus;
152 #endif // LIBFUZZER_APPLE
void Printf(const char *Fmt,...)
int ExecuteCommand(const std::string &Command)