79 if (data.submitDir[0] !=
'/')
80 data.submitDir = gSystem->WorkingDirectory () + (
"/" + data.submitDir);
83 const std::regex identityEndExpr {
"(/$)|(/\\.$)"};
84 while (std::regex_search (data.submitDir,
match, identityEndExpr))
85 data.submitDir.replace (
match.position(0),
match.length(0),
"");
86 const std::regex relativeEndExpr {
"/\\.\\.$"};
87 if (std::regex_search (data.submitDir,
match, relativeEndExpr))
89 ANA_MSG_ERROR (
"submit directory can not end in \"..\": " + data.submitDir);
90 return ::StatusCode::FAILURE;
99 const std::regex identityExpr {
"(/\\./)|(//)|(^/\\.\\./)"};
100 while (std::regex_search (data.submitDir,
match, identityExpr))
101 data.submitDir.replace (
match.position(0),
match.length(0),
"/");
102 const std::regex relativeExpr {
"/[^/]+/\\.\\./"};
103 while (std::regex_search (data.submitDir,
match, relativeExpr))
104 data.submitDir.replace (
match.position(0),
match.length(0),
"/");
106 if (data.submitDir.find (
"/pnfs/") == 0)
108 ANA_MSG_ERROR (
"can not place submit directory on pnfs: " + data.submitDir);
109 return ::StatusCode::FAILURE;
121 if (mode ==
"no-clobber")
123 else if (mode ==
"overwrite")
125 else if (mode ==
"unique")
127 else if (mode ==
"unique-link")
132 ANA_MSG_ERROR (
"known modes: no-clobber, overwrite, unique, unique-link");
133 return ::StatusCode::FAILURE;
141 ANA_MSG_ERROR (
"can't specify both an explicit submit-dir mode and optRemoveSubmitDir");
142 return ::StatusCode::FAILURE;
151 ANA_MSG_DEBUG (
"using submit-dir mode: " <<
unsigned (data.submitDirMode));
153 bool success {
false};
155 std::string submitDir;
156 std::size_t hash {0};
157 while (success ==
false && tries < 10)
161 switch (data.submitDirMode)
165 submitDir = data.submitDir;
173 if (gettimeofday (&tv,
nullptr) == -1 ||
174 localtime_r (&tv.tv_sec, &tvSplit) ==
nullptr)
178 return ::StatusCode::FAILURE;
180 const std::string uniqueDateFormat {
183 char timeString [160];
184 if (strftime (timeString,
sizeof (timeString),
185 uniqueDateFormat.c_str(), &tvSplit) == 0)
187 ANA_MSG_ERROR (
"failed to format the unique date, please check optUniqueDateFormat: " << uniqueDateFormat);
188 return ::StatusCode::FAILURE;
192 boost::hash_combine (hash, std::hash<pid_t>() (getpid()));
193 boost::hash_combine (hash, std::hash<suseconds_t>() (tv.tv_usec));
194 std::size_t hash16 {hash};
195 while (hash16 > 0xffff)
196 hash16 = (hash16&0xffff) ^ (hash16 >> 16);
207 submitDir = data.submitDir + timeString +
208 std::format(
"{:04x}", hash16);
214 if (::mkdir (submitDir.c_str(), 0777) == 0)
219 const int myerrno {errno};
220 if (myerrno == EEXIST)
222 switch (data.submitDirMode)
225 ANA_MSG_ERROR (
"cowardly refusing to overwrite " << submitDir);
226 ANA_MSG_ERROR (
"change the name or remove file/directory already there");
227 return ::StatusCode::FAILURE;
233 return ::StatusCode::FAILURE;
247 reportErrno (myerrno);
249 return ::StatusCode::FAILURE;
256 ANA_MSG_INFO (
"created submission directory " + submitDir);
257 switch (data.submitDirMode)
267 if (unlink (data.submitDir.c_str()) == -1 && errno != ENOENT)
271 return ::StatusCode::FAILURE;
274 std::string
file = submitDir.substr (submitDir.rfind (
'/')+1);
275 if (symlink (
file.c_str(), data.submitDir.c_str()) == -1)
278 ANA_MSG_ERROR (
"failed to create symlink at: " << data.submitDir);
279 return ::StatusCode::FAILURE;
281 ANA_MSG_INFO (
"created sym-link at: " << data.submitDir);
285 data.submitDir = submitDir;
288 ANA_MSG_ERROR (
"tried " << tries <<
" times to create directory and failed: " << data.submitDir);
290 return ::StatusCode::FAILURE;
299 return ::StatusCode::SUCCESS;
static const std::string optSubmitDirMode
the submit-dir mode (allowed values: "no-clobber", "overwrite", "unique", "unique-link")