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