13 #include <crt_externs.h> 14 #define environ (*_NSGetEnviron()) 21 for (
char **
p =
cmd;
p &&
p[0]; ++
p)
22 size += 1 + strlen(*
p);
27 for (
char **
p =
cmd;
p &&
p[0]; ++
p) {
55 if (tmpdir.empty() || tmpdir ==
".") {
56 size_t len = pathconf(
".", _PC_PATH_MAX);
60 temp.reserve(len + 32);
64 temp.reserve(tmpdir.size() + 32);
70 temp +=
"storage-factory-local-XXXXXX";
73 int fd = mkstemp(&
temp[0]);
75 throwStorageError(
"RemoteFile",
"Calling RemoteFile::local()",
"mkstemp()", errno);
87 int rc = posix_spawnp(&pid,
cmd[0],
nullptr,
nullptr,
cmd, environ);
93 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"posix_spawnp()", errsave);
98 rcpid = waitpid(pid, &rc, 0);
99 while (rcpid == (pid_t)-1 && errno == EINTR);
101 if (rcpid == (pid_t)-1) {
104 unlink(
name.c_str());
105 throwStorageError(
"RemoteFile",
"Calling RemoteFile::get()",
"waitpid()", errsave);
108 if (WIFEXITED(rc) && WEXITSTATUS(rc) == 0)
112 unlink(
name.c_str());
115 << (WIFEXITED(rc) ?
" exited with exit code " 116 : WIFSIGNALED(rc) ?
" died from signal " 117 :
" died for an obscure unknown reason with exit status ")
118 << (WIFEXITED(rc) ? WEXITSTATUS(rc)
119 : WIFSIGNALED(rc) ? WTERMSIG(rc)
121 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 free(void *ptr) noexcept
void abort(void) override
static int local(const std::string &tmpdir, std::string &temp)
static std::string join(char **cmd)
void * malloc(size_t size) noexcept
RemoteFile(IOFD fd, const std::string &name)
void close(void) override