From 103eb0ce5e0dd7b379ae5f3c3f96954755e94eca Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Wed, 1 Mar 2017 04:53:24 -0800 Subject: [PATCH] Mac: add new mac_spawn.cpp to project to facilitate replacing system() calls with posix_spawn() calls as instructed by Apple, since system() is deprecated in mac OS 10.10. --- lib/mac/mac_spawn.cpp | 150 ++++++++++++++++++++++ mac_build/boinc.xcodeproj/project.pbxproj | 6 + 2 files changed, 156 insertions(+) create mode 100644 lib/mac/mac_spawn.cpp 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