13 #include <crt_externs.h>
14 #define environ (*_NSGetEnviron())
17 using namespace edm::storage;
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);
57 char *
buf = (
char *)malloc(len);
60 temp.reserve(len + 32);
64 temp.reserve(tmpdir.size() + 32);
67 if (temp[temp.size() - 1] !=
'/')
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)
109 return std::unique_ptr<Storage>(
static_cast<Storage *
>(
new RemoteFile(localfd, name)));
112 unlink(name.c_str());
114 ex <<
"'" <<
join(cmd) <<
"'"
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 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)
tuple size
Write out results.
void close(void) override