diff --git a/lib/mac/mac_spawn.cpp b/lib/mac/mac_spawn.cpp
new file mode 100644
index 0000000000..a213951801
--- /dev/null
+++ b/lib/mac/mac_spawn.cpp
@@ -0,0 +1,150 @@
+// This file is part of BOINC.
+// http://boinc.berkeley.edu
+// Copyright (C) 2017 University of California
+//
+// BOINC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// BOINC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with BOINC. If not, see .
+
+// system() is deprecated in Mac OS 10.10.
+// Apple says to call posix_spawn instead.
+
+#define VERBOSE_SPAWN 0 /* for debugging callPosixSpawn */
+
+#include
+#include
+
+#define NOT_IN_TOKEN 0
+#define IN_SINGLE_QUOTED_TOKEN 1
+#define IN_DOUBLE_QUOTED_TOKEN 2
+#define IN_UNQUOTED_TOKEN 3
+
+static int parse_posic_spawn_command_line(char* p, char** argv) {
+ int state = NOT_IN_TOKEN;
+ int argc=0;
+
+ while (*p) {
+ switch(state) {
+ case NOT_IN_TOKEN:
+ if (isspace(*p)) {
+ } else if (*p == '\'') {
+ p++;
+ argv[argc++] = p;
+ state = IN_SINGLE_QUOTED_TOKEN;
+ break;
+ } else if (*p == '\"') {
+ p++;
+ argv[argc++] = p;
+ state = IN_DOUBLE_QUOTED_TOKEN;
+ break;
+ } else {
+ argv[argc++] = p;
+ state = IN_UNQUOTED_TOKEN;
+ }
+ break;
+ case IN_SINGLE_QUOTED_TOKEN:
+ if (*p == '\'') {
+ if (*(p-1) == '\\') break;
+ *p = 0;
+ state = NOT_IN_TOKEN;
+ }
+ break;
+ case IN_DOUBLE_QUOTED_TOKEN:
+ if (*p == '\"') {
+ if (*(p-1) == '\\') break;
+ *p = 0;
+ state = NOT_IN_TOKEN;
+ }
+ break;
+ case IN_UNQUOTED_TOKEN:
+ if (isspace(*p)) {
+ *p = 0;
+ state = NOT_IN_TOKEN;
+ }
+ break;
+ }
+ p++;
+ }
+ argv[argc] = 0;
+ return argc;
+}
+
+
+int callPosixSpawn(const char *cmdline) {
+ char command[1024];
+ char progName[1024];
+ char progPath[MAXPATHLEN];
+ char* argv[100];
+ int argc = 0;
+ char *p;
+ pid_t thePid = 0;
+ int result = 0;
+ int status = 0;
+ extern char **environ;
+
+ // Make a copy of cmdline because parse_posic_spawn_command_line modifies it
+ strlcpy(command, cmdline, sizeof(command));
+ argc = parse_posic_spawn_command_line(const_cast(command), argv);
+ strlcpy(progPath, argv[0], sizeof(progPath));
+ strlcpy(progName, argv[0], sizeof(progName));
+ p = strrchr(progName, '/');
+ if (p) {
+ argv[0] = p+1;
+ } else {
+ argv[0] = progName;
+ }
+
+#if VERBOSE_SPAWN
+ fprintf(stderr, "***********");
+ for (int i=0; i