13 #include <crt_externs.h>
14 #define environ (*_NSGetEnviron())
19 for (
char **
p =
cmd;
p &&
p[0]; ++
p)
20 size += 1 + strlen(*
p);
25 for (
char **
p =
cmd;
p &&
p[0]; ++
p) {
53 if (tmpdir.empty() || tmpdir ==
".") {
54 size_t len = pathconf(
".", _PC_PATH_MAX);
55 char *
buf = (
char *)malloc(len);
58 temp.reserve(len + 32);
62 temp.reserve(tmpdir.size() + 32);
68 temp +=
"storage-factory-local-XXXXXX";
71 int fd = mkstemp(&
temp[0]);
73 throwStorageError(
"RemoteFile",
"Calling RemoteFile::local()",
"mkstemp()", errno);
85 int rc = posix_spawnp(&pid,
cmd[0],
nullptr,
nullptr,
cmd, environ);
91 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"posix_spawnp()", errsave);
96 rcpid = waitpid(pid, &rc, 0);
97 while (rcpid == (pid_t)-1 && errno == EINTR);
99 if (rcpid == (pid_t)-1) {
102 unlink(
name.c_str());
103 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"waitpid()", errsave);
106 if (WIFEXITED(rc) && WEXITSTATUS(rc) == 0)
107 return std::unique_ptr<Storage>(static_cast<Storage *>(
new RemoteFile(localfd,
name)));
110 unlink(
name.c_str());
114 ?
" exited with exit code "
115 : WIFSIGNALED(rc) ?
" died from signal " :
" died for an obscure unknown reason with exit status ")
116 << (WIFEXITED(rc) ? WEXITSTATUS(rc) : WIFSIGNALED(rc) ? WTERMSIG(rc) : rc);
117 ex.addContext(
"Calling RemoteFile::get()");