CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RemoteFile.cc
Go to the documentation of this file.
4 #include <sys/wait.h>
5 #include <sys/types.h>
6 #include <cerrno>
7 #include <cassert>
8 #include <spawn.h>
9 #include <unistd.h>
10 #include <ostream>
11 #include <cstring>
12 #if __APPLE__
13 # include <crt_externs.h>
14 # define environ (*_NSGetEnviron())
15 #endif
16 
17 static std::string
18 join (char **cmd)
19 {
20  size_t size = 0;
21  for (char **p = cmd; p && p[0]; ++p)
22  size += 1 + strlen(*p);
23 
24  std::string result;
25  result.reserve (size);
26 
27  for (char **p = cmd; p && p[0]; ++p)
28  {
29  if (p != cmd)
30  result += ' ';
31  result += *p;
32  }
33 
34  return result;
35 }
36 
37 RemoteFile::RemoteFile (IOFD fd, const std::string &name)
38  : File (fd),
39  name_ (name)
40 {}
41 
42 void
44 { unlink (name_.c_str()); }
45 
46 void
48 { remove(); File::close (); }
49 
50 void
52 { remove(); File::abort (); }
53 
54 int
55 RemoteFile::local (const std::string &tmpdir, std::string &temp)
56 {
57  // Download temporary files to the current directory by default.
58  // This is better for grid jobs as the current directory is
59  // likely to have more space, and is more optimised for
60  // large files, and is cleaned up after the job.
61  if (tmpdir.empty () || tmpdir == ".")
62  {
63  size_t len = pathconf (".", _PC_PATH_MAX);
64  char *buf = (char *) malloc (len);
65  getcwd (buf, len);
66 
67  temp.reserve (len + 32);
68  temp = buf;
69  free (buf);
70  }
71  else
72  {
73  temp.reserve (tmpdir.size() + 32);
74  temp = tmpdir;
75  }
76  if (temp[temp.size()-1] != '/')
77  temp += '/';
78 
79  temp += "storage-factory-local-XXXXXX";
80  temp.c_str(); // null terminate for mkstemp
81 
82  int fd = mkstemp (&temp[0]);
83  if (fd == -1)
84  throwStorageError("RemoteFile::local()", "mkstemp()", errno);
85 
86  return fd;
87 }
88 
89 Storage *
90 RemoteFile::get (int localfd, const std::string &name, char **cmd, int mode)
91 {
92  // FIXME: On write, create a temporary local file open for write;
93  // on close, trigger transfer to destination. If opening existing
94  // file for write, may need to first download.
95  assert (! (mode & (IOFlags::OpenWrite | IOFlags::OpenCreate)));
96 
97  pid_t pid = -1;
98  int rc = posix_spawnp (&pid, cmd[0], 0, 0, cmd, environ);
99 
100  if (rc == -1)
101  {
102  ::close (localfd);
103  unlink (name.c_str());
104  throwStorageError ("RemoteFile::get()", "posix_spawnp()", rc);
105  }
106 
107  pid_t rcpid;
108  do
109  rcpid = waitpid(pid, &rc, 0);
110  while (rcpid == (pid_t) -1 && errno == EINTR);
111 
112  if (rcpid == (pid_t) -1)
113  {
114  ::close (localfd);
115  unlink (name.c_str());
116  throwStorageError ("RemoteFile::get()", "waitpid()", errno);
117  }
118 
119  if (WIFEXITED(rc) && WEXITSTATUS(rc) == 0)
120  return new RemoteFile (localfd, name);
121  else
122  {
123  ::close (localfd);
124  unlink (name.c_str());
125  throw cms::Exception("RemoteFile::get()")
126  << "'" << join(cmd) << "'"
127  << (WIFEXITED(rc) ? " exited with exit code "
128  : WIFSIGNALED(rc) ? " died from signal "
129  : " died for an obscure unknown reason with exit status ")
130  << (WIFEXITED(rc) ? WEXITSTATUS(rc)
131  : WIFSIGNALED(rc) ? WTERMSIG(rc)
132  : rc);
133  }
134 }
RemoteFile(IOFD fd, const std::string &name)
Definition: RemoteFile.cc:37
void throwStorageError(const char *context, const char *call, int error)
Definition: Throw.cc:7
Definition: Storage.h:8
void remove(void)
Definition: RemoteFile.cc:43
virtual void abort(void)
Definition: RemoteFile.cc:51
static int local(const std::string &tmpdir, std::string &temp)
Definition: RemoteFile.cc:55
virtual void abort(void)
Definition: File.cc:292
virtual void close(void)
Definition: RemoteFile.cc:47
tuple result
Definition: query.py:137
string cmd
Definition: asciidump.py:19
std::string name_
Definition: RemoteFile.h:23
static Storage * get(int localfd, const std::string &name, char **cmd, int mode)
Definition: RemoteFile.cc:90
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
int mode
Definition: AMPTWrapper.h:139
int IOFD
Definition: IOTypes.h:22
virtual IOFD fd(void) const
Definition: IOChannel.cc:73
Definition: File.h:11
virtual void close(void)
Definition: File.cc:277
tuple size
Write out results.