Skip to content

Commit f67d866

Browse files
authored
Merge pull request #110 from bbockelm/posc_enoent
Return an ENOENT if the parent directory does not exist.
2 parents 727f94e + 7e8d9e2 commit f67d866

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/Posc.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,27 @@ int PoscFile::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env) {
743743
return wrapDF.Open(path, Oflag, Mode, env);
744744
}
745745

746+
// Ensure the parent directory exists and is a directory; this is needed
747+
// because the underlying open() takes care of it in the non-POSC case.
748+
std::filesystem::path path_fs(path);
749+
auto parent_path = path_fs.parent_path();
750+
if (!parent_path.empty()) {
751+
struct stat sb;
752+
auto rv = m_oss.Stat(parent_path.c_str(), &sb, 0, &env);
753+
if (rv != 0) {
754+
m_log.Log(LogMask::Debug, "POSC",
755+
"Failing file open as parent path does not exist",
756+
parent_path.c_str());
757+
return -ENOENT;
758+
}
759+
if (!S_ISDIR(sb.st_mode)) {
760+
m_log.Log(LogMask::Debug, "POSC",
761+
"Failing file open as parent path is not a directory",
762+
parent_path.c_str());
763+
return -ENOENT;
764+
}
765+
}
766+
746767
if (env.secEnv()) {
747768
CopySecEntity(*env.secEnv());
748769
}

test/posc_tests.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,41 @@ TEST_F(TestPosc, TempfileUpdate) {
294294
ASSERT_EQ(rv, -ENOENT) << "Unexpected error when stating POSC file: "
295295
<< strerror(errno);
296296
}
297+
298+
TEST_F(TestPosc, CreateENOENT) {
299+
XrdSysLogger logger(2, 0);
300+
XrdOucEnv env;
301+
302+
XrdVERSIONINFODEF(XrdOssDefault, Oss, XrdVNUMBER, XrdVERSION);
303+
304+
XrdOss *default_oss =
305+
XrdOssDefaultSS(&logger, GetConfigFile().c_str(), XrdOssDefault);
306+
307+
ASSERT_NE(default_oss, nullptr) << "Failed to get Posc OSS instance";
308+
309+
std::unique_ptr<XrdSysError> log(new XrdSysError(&logger, "posc_"));
310+
PoscFileSystem *posc_fs_raw;
311+
try {
312+
posc_fs_raw = new PoscFileSystem(default_oss, std::move(log),
313+
GetConfigFile().c_str(), &env);
314+
} catch (const std::exception &e) {
315+
FAIL() << "Failed to create PoscFileSystem: " << e.what();
316+
}
317+
std::unique_ptr<PoscFileSystem> posc_fs(posc_fs_raw);
318+
319+
std::unique_ptr<XrdOssDF> fp(posc_fs->newFile());
320+
ASSERT_NE(fp, nullptr) << "Failed to create new file object";
321+
322+
auto rv = fp->Open("/subdir/testfile.txt", O_CREAT | O_RDWR, 0644, env);
323+
ASSERT_NE(rv, 0) << "Open should have failed";
324+
ASSERT_EQ(rv, -ENOENT)
325+
<< "Open on non-existent path should have resulted in ENOENT: "
326+
<< strerror(-rv);
327+
328+
posc_fs->Mkdir("/subdir", 0755, 1, &env);
329+
330+
rv = fp->Open("/subdir/testfile.txt", O_CREAT | O_RDWR, 0644, env);
331+
ASSERT_EQ(rv, 0) << "Open on newly created directory failed: "
332+
<< strerror(-rv);
333+
ASSERT_EQ(fp->Close(), 0) << "Failed to close file";
334+
}

0 commit comments

Comments
 (0)