15 #include <crt_externs.h> 16 #define environ (*_NSGetEnviron()) 23 for (
char **
p =
cmd;
p &&
p[0]; ++
p)
24 size += 1 + strlen(*
p);
29 for (
char **
p =
cmd;
p &&
p[0]; ++
p) {
57 std::vector<char> temp_chars;
59 if (tmpdir.empty() || tmpdir ==
".") {
61 auto spath = current_path.string();
62 temp_chars.reserve(spath.size() + 30);
63 temp_chars.assign(spath.begin(), spath.end());
65 temp_chars.reserve(tmpdir.size() + 30);
66 temp_chars.assign(tmpdir.begin(), tmpdir.end());
69 if (temp_chars.back() !=
'/')
70 temp_chars.push_back(
'/');
73 temp_chars.insert(temp_chars.end(),
suffix.begin(),
suffix.end());
76 temp_chars.push_back(
'\0');
78 int fd = mkstemp(temp_chars.data());
80 throwStorageError(
"RemoteFile",
"Calling RemoteFile::local()",
"mkstemp()", errno);
82 temp.assign(temp_chars.begin(), temp_chars.end() - 1);
94 int rc = posix_spawnp(&pid,
cmd[0],
nullptr,
nullptr,
cmd, environ);
100 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"posix_spawnp()", errsave);
105 rcpid = waitpid(pid, &rc, 0);
106 while (rcpid == (pid_t)-1 && errno == EINTR);
108 if (rcpid == (pid_t)-1) {
111 unlink(
name.c_str());
112 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"waitpid()", errsave);
115 if (WIFEXITED(rc) && WEXITSTATUS(rc) == 0)
119 unlink(
name.c_str());
122 << (WIFEXITED(rc) ?
" exited with exit code " 123 : WIFSIGNALED(rc) ?
" died from signal " 124 :
" died for an obscure unknown reason with exit status ")
125 << (WIFEXITED(rc) ? WEXITSTATUS(rc)
126 : WIFSIGNALED(rc) ? WTERMSIG(rc)
128 ex.addContext(
"Calling RemoteFile::get()");
static std::unique_ptr< Storage > get(int localfd, const std::string &name, char **cmd, int mode)
void throwStorageError(const char *category, const char *context, const char *call, int error)
void abort(void) override
static int local(const std::string &tmpdir, std::string &temp)
static std::string join(char **cmd)
RemoteFile(IOFD fd, const std::string &name)
void close(void) override