70 {
72 {
74 {
76
77
78 if (
data.submitDir[0] !=
'/')
79 data.submitDir = gSystem->WorkingDirectory () + (
"/" +
data.submitDir);
80
81
82 const std::regex identityEndExpr {"(/$)|(/\\.$)"};
83 while (std::regex_search (
data.submitDir,
match, identityEndExpr))
85 const std::regex relativeEndExpr {"/\\.\\.$"};
86 if (std::regex_search (
data.submitDir,
match, relativeEndExpr))
87 {
89 return ::StatusCode::FAILURE;
90 }
91
92
93
94
95
96
97
98 const std::regex identityExpr {"(/\\./)|(//)|(^/\\.\\./)"};
99 while (std::regex_search (
data.submitDir,
match, identityExpr))
101 const std::regex relativeExpr {"/[^/]+/\\.\\./"};
102 while (std::regex_search (
data.submitDir,
match, relativeExpr))
104
105 if (
data.submitDir.find (
"/pnfs/") == 0)
106 {
108 return ::StatusCode::FAILURE;
109 }
110
112 }
113 break;
114
116 {
119 {
120 if (mode == "no-clobber")
122 else if (mode == "overwrite")
124 else if (mode == "unique")
126 else if (mode == "unique-link")
128 else
129 {
131 ANA_MSG_ERROR (
"known modes: no-clobber, overwrite, unique, unique-link");
132 return ::StatusCode::FAILURE;
133 }
134 }
135
137 {
139 {
140 ANA_MSG_ERROR (
"can't specify both an explicit submit-dir mode and optRemoveSubmitDir");
141 return ::StatusCode::FAILURE;
142 }
144 }
145 }
146 break;
147
149 {
151
152 bool success {false};
153 unsigned tries {0};
155 std::size_t
hash {0};
156 while (success == false && tries < 10)
157 {
158 tries += 1;
159
160 switch (
data.submitDirMode)
161 {
165 break;
166
169 {
170 timeval tv;
171 tm tvSplit;
172 if (gettimeofday (&tv, nullptr) == -1 ||
173 localtime_r (&tv.tv_sec, &tvSplit) == nullptr)
174 {
175 reportErrno ();
177 return ::StatusCode::FAILURE;
178 }
179 const std::string uniqueDateFormat {
181 "-%Y-%m-%d-%H%M-")};
183 strftime (timeString, sizeof (timeString),
184 uniqueDateFormat.c_str(), &tvSplit);
185
186
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);
192
193
194
195
196
197
198
199
200
201
203 std::format("{:04x}", hash16);
205 }
206 break;
207 }
208
209 if (::mkdir (
submitDir.c_str(), 0777) == 0)
210 {
211 success = true;
212 } else
213 {
214 const int myerrno {errno};
215 if (myerrno == EEXIST)
216 {
217 switch (
data.submitDirMode)
218 {
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;
224 if (tries > 1)
225 {
228 return ::StatusCode::FAILURE;
229 }
231 gSystem->Exec (("rm -rf " + submitDir).c_str());
232 break;
235
236
237 break;
238 }
239 } else
240 {
241 reportErrno (myerrno);
243 return ::StatusCode::FAILURE;
244 }
245 }
246 }
247
248 if (success)
249 {
250 ANA_MSG_INFO (
"created submission directory " + submitDir);
251 switch (
data.submitDirMode)
252 {
256
257 break;
258
260 {
261 if (unlink (
data.submitDir.c_str()) == -1 && errno != ENOENT)
262 {
263 reportErrno ();
265 return ::StatusCode::FAILURE;
266 }
267
269 if (symlink (
file.c_str(),
data.submitDir.c_str()) == -1)
270 {
271 reportErrno ();
273 return ::StatusCode::FAILURE;
274 }
276 }
277 break;
278 }
280 } else
281 {
282 ANA_MSG_ERROR (
"tried " << tries <<
" times to create directory and failed: " <<
data.submitDir);
284 return ::StatusCode::FAILURE;
285 }
286 }
287 break;
288
289 default:
290
291 break;
292 }
293 return ::StatusCode::SUCCESS;
294 }
char data[hepevt_bytes_allocation_ATLAS]
static const std::string optSubmitDirMode
the submit-dir mode (allowed values: "no-clobber", "overwrite", "unique", "unique-link")
static const std::string optUniqueDateFormat
the date-format to use when generating unique submission directory names
static const std::string optRemoveSubmitDir
description: the name of the option for overwriting the submission directory.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
@ OVERWRITE
create the directory as is, removing existing directories if needed
@ UNIQUE_LINK
append a unique suffix to the directory name and place a symbolic link in place of the originally req...
@ NO_CLOBBER
create the directory as is, raise an error if it already exists
@ UNIQUE
append a unique suffix to the directory name
@ updateSubmitDir
update the submitDir variable to be an absolute path
@ extractOptions
extract any options into ManagerData for which it is appropriate
@ createSubmitDir
create the submission directory