78 if (data.submitDir[0] !=
'/')
79 data.submitDir = gSystem->WorkingDirectory () + (
"/" + data.submitDir);
82 const std::regex identityEndExpr {
"(/$)|(/\\.$)"};
83 while (std::regex_search (data.submitDir,
match, identityEndExpr))
84 data.submitDir.replace (
match.position(0),
match.length(0),
"");
85 const std::regex relativeEndExpr {
"/\\.\\.$"};
86 if (std::regex_search (data.submitDir,
match, relativeEndExpr))
88 ANA_MSG_ERROR (
"submit directory can not end in \"..\": " + data.submitDir);
89 return ::StatusCode::FAILURE;
98 const std::regex identityExpr {
"(/\\./)|(//)|(^/\\.\\./)"};
99 while (std::regex_search (data.submitDir,
match, identityExpr))
100 data.submitDir.replace (
match.position(0),
match.length(0),
"/");
101 const std::regex relativeExpr {
"/[^/]+/\\.\\./"};
102 while (std::regex_search (data.submitDir,
match, relativeExpr))
103 data.submitDir.replace (
match.position(0),
match.length(0),
"/");
105 if (data.submitDir.find (
"/pnfs/") == 0)
107 ANA_MSG_ERROR (
"can not place submit directory on pnfs: " + data.submitDir);
108 return ::StatusCode::FAILURE;
120 if (mode ==
"no-clobber")
122 else if (mode ==
"overwrite")
124 else if (mode ==
"unique")
126 else if (mode ==
"unique-link")
131 ANA_MSG_ERROR (
"known modes: no-clobber, overwrite, unique, unique-link");
132 return ::StatusCode::FAILURE;
140 ANA_MSG_ERROR (
"can't specify both an explicit submit-dir mode and optRemoveSubmitDir");
141 return ::StatusCode::FAILURE;
150 ANA_MSG_DEBUG (
"using submit-dir mode: " <<
unsigned (data.submitDirMode));
152 bool success {
false};
154 std::string submitDir;
155 std::size_t hash {0};
156 while (success ==
false && tries < 10)
160 switch (data.submitDirMode)
164 submitDir = data.submitDir;
172 if (gettimeofday (&tv,
nullptr) == -1 ||
173 localtime_r (&tv.tv_sec, &tvSplit) ==
nullptr)
177 return ::StatusCode::FAILURE;
179 const std::string uniqueDateFormat {
182 char timeString [160];
183 strftime (timeString,
sizeof (timeString),
184 uniqueDateFormat.c_str(), &tvSplit);
187 boost::hash_combine (hash, std::hash<pid_t>() (getpid()));
188 boost::hash_combine (hash, std::hash<suseconds_t>() (tv.tv_usec));
189 std::size_t hash16 {hash};
190 while (hash16 > 0xffff)
191 hash16 = (hash16&0xffff) ^ (hash16 >> 16);
202 submitDir = data.submitDir + timeString +
203 std::format(
"{:04x}", hash16);
209 if (::mkdir (submitDir.c_str(), 0777) == 0)
214 const int myerrno {errno};
215 if (myerrno == EEXIST)
217 switch (data.submitDirMode)
220 ANA_MSG_ERROR (
"cowardly refusing to overwrite " << submitDir);
221 ANA_MSG_ERROR (
"change the name or remove file/directory already there");
222 return ::StatusCode::FAILURE;
228 return ::StatusCode::FAILURE;
231 gSystem->Exec ((
"rm -rf " + submitDir).c_str());
241 reportErrno (myerrno);
243 return ::StatusCode::FAILURE;
250 ANA_MSG_INFO (
"created submission directory " + submitDir);
251 switch (data.submitDirMode)
261 if (unlink (data.submitDir.c_str()) == -1 && errno != ENOENT)
265 return ::StatusCode::FAILURE;
268 std::string
file = submitDir.substr (submitDir.rfind (
'/')+1);
269 if (symlink (
file.c_str(), data.submitDir.c_str()) == -1)
272 ANA_MSG_ERROR (
"failed to create symlink at: " << data.submitDir);
273 return ::StatusCode::FAILURE;
275 ANA_MSG_INFO (
"created sym-link at: " << data.submitDir);
279 data.submitDir = submitDir;
282 ANA_MSG_ERROR (
"tried " << tries <<
" times to create directory and failed: " << data.submitDir);
284 return ::StatusCode::FAILURE;
293 return ::StatusCode::SUCCESS;
static const std::string optSubmitDirMode
the submit-dir mode (allowed values: "no-clobber", "overwrite", "unique", "unique-link")