1*03689974SAlex Brachet //===------- ExecuteFunction implementation for Unix-like Systems ---------===// 2*03689974SAlex Brachet // 3*03689974SAlex Brachet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*03689974SAlex Brachet // See https://llvm.org/LICENSE.txt for license information. 5*03689974SAlex Brachet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*03689974SAlex Brachet // 7*03689974SAlex Brachet //===----------------------------------------------------------------------===// 8*03689974SAlex Brachet 9*03689974SAlex Brachet #include "ExecuteFunction.h" 10*03689974SAlex Brachet #include "llvm/Support/raw_ostream.h" 11*03689974SAlex Brachet #include <cassert> 12*03689974SAlex Brachet #include <cstdlib> 13*03689974SAlex Brachet #include <signal.h> 14*03689974SAlex Brachet #include <sys/wait.h> 15*03689974SAlex Brachet #include <unistd.h> 16*03689974SAlex Brachet 17*03689974SAlex Brachet namespace __llvm_libc { 18*03689974SAlex Brachet namespace testutils { 19*03689974SAlex Brachet 20*03689974SAlex Brachet bool ProcessStatus::exitedNormally() { return WIFEXITED(PlatformDefined); } 21*03689974SAlex Brachet 22*03689974SAlex Brachet int ProcessStatus::getExitCode() { 23*03689974SAlex Brachet assert(exitedNormally() && "Abnormal termination, no exit code"); 24*03689974SAlex Brachet return WEXITSTATUS(PlatformDefined); 25*03689974SAlex Brachet } 26*03689974SAlex Brachet 27*03689974SAlex Brachet int ProcessStatus::getFatalSignal() { 28*03689974SAlex Brachet if (exitedNormally()) 29*03689974SAlex Brachet return 0; 30*03689974SAlex Brachet return WTERMSIG(PlatformDefined); 31*03689974SAlex Brachet } 32*03689974SAlex Brachet 33*03689974SAlex Brachet ProcessStatus invokeInSubprocess(FunctionCaller *Func) { 34*03689974SAlex Brachet // Don't copy the buffers into the child process and print twice. 35*03689974SAlex Brachet llvm::outs().flush(); 36*03689974SAlex Brachet llvm::errs().flush(); 37*03689974SAlex Brachet pid_t Pid = ::fork(); 38*03689974SAlex Brachet if (!Pid) { 39*03689974SAlex Brachet (*Func)(); 40*03689974SAlex Brachet std::exit(0); 41*03689974SAlex Brachet } 42*03689974SAlex Brachet 43*03689974SAlex Brachet int WStatus; 44*03689974SAlex Brachet ::waitpid(Pid, &WStatus, 0); 45*03689974SAlex Brachet delete Func; 46*03689974SAlex Brachet return {WStatus}; 47*03689974SAlex Brachet } 48*03689974SAlex Brachet 49*03689974SAlex Brachet const char *signalAsString(int Signum) { return ::strsignal(Signum); } 50*03689974SAlex Brachet 51*03689974SAlex Brachet } // namespace testutils 52*03689974SAlex Brachet } // namespace __llvm_libc 53