aboutsummaryrefslogtreecommitdiff
path: root/src/os.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-11-05 10:56:42 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-11-05 10:56:42 -0500
commitf8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72 (patch)
treefc0da10e6a69eb167e7d994f348148917c8ef98b /src/os.cpp
parentce912e29640e0a3b39a5c304c86bdbb5fff67169 (diff)
parent973e0abe79abf33cb5e9f4550fe323cb93eb6ee1 (diff)
downloadzig-f8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72.tar.gz
zig-f8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72.zip
Merge remote-tracking branch 'origin/master' into llvm8
Diffstat (limited to 'src/os.cpp')
-rw-r--r--src/os.cpp44
1 files changed, 23 insertions, 21 deletions
diff --git a/src/os.cpp b/src/os.cpp
index b682429884..f01a99fc23 100644
--- a/src/os.cpp
+++ b/src/os.cpp
@@ -46,6 +46,7 @@ typedef SSIZE_T ssize_t;
#include <sys/wait.h>
#include <fcntl.h>
#include <limits.h>
+#include <spawn.h>
#endif
@@ -70,6 +71,12 @@ static clock_serv_t cclock;
#include <errno.h>
#include <time.h>
+// Apple doesn't provide the environ global variable
+#if defined(__APPLE__) && !defined(environ)
+#include <crt_externs.h>
+#define environ (*_NSGetEnviron())
+#endif
+
#if defined(ZIG_OS_POSIX)
static void populate_termination(Termination *term, int status) {
if (WIFEXITED(status)) {
@@ -88,25 +95,22 @@ static void populate_termination(Termination *term, int status) {
}
static void os_spawn_process_posix(const char *exe, ZigList<const char *> &args, Termination *term) {
- pid_t pid = fork();
- if (pid == -1)
- zig_panic("fork failed");
- if (pid == 0) {
- // child
- const char **argv = allocate<const char *>(args.length + 2);
- argv[0] = exe;
- argv[args.length + 1] = nullptr;
- for (size_t i = 0; i < args.length; i += 1) {
- argv[i + 1] = args.at(i);
- }
- execvp(exe, const_cast<char * const *>(argv));
- zig_panic("execvp failed: %s", strerror(errno));
- } else {
- // parent
- int status;
- waitpid(pid, &status, 0);
- populate_termination(term, status);
+ const char **argv = allocate<const char *>(args.length + 2);
+ argv[0] = exe;
+ argv[args.length + 1] = nullptr;
+ for (size_t i = 0; i < args.length; i += 1) {
+ argv[i + 1] = args.at(i);
}
+
+ pid_t pid;
+ int rc = posix_spawnp(&pid, exe, nullptr, nullptr, const_cast<char *const*>(argv), environ);
+ if (rc != 0) {
+ zig_panic("posix_spawn failed: %s", strerror(rc));
+ }
+
+ int status;
+ waitpid(pid, &status, 0);
+ populate_termination(term, status);
}
#endif
@@ -806,7 +810,7 @@ static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,
pid_t pid = fork();
if (pid == -1)
- zig_panic("fork failed");
+ zig_panic("fork failed: %s", strerror(errno));
if (pid == 0) {
// child
if (dup2(stdin_pipe[0], STDIN_FILENO) == -1)
@@ -1378,8 +1382,6 @@ int os_init(void) {
#if defined(ZIG_OS_WINDOWS)
_setmode(fileno(stdout), _O_BINARY);
_setmode(fileno(stderr), _O_BINARY);
-#endif
-#if defined(ZIG_OS_WINDOWS)
unsigned __int64 frequency;
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) {
win32_time_resolution = 1.0 / (double) frequency;