From 0d609c9e0208d2ea90dfa55681c8977ad92cba4f Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 4 Aug 2017 23:30:22 +0100 Subject: Improve FileHandle's compatibility with a raw descriptor --- libadhocutil/fileUtils.cpp | 10 ++++++++++ libadhocutil/fileUtils.h | 15 +++++++++++++++ libadhocutil/unittests/testFileUtils.cpp | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/libadhocutil/fileUtils.cpp b/libadhocutil/fileUtils.cpp index d114d30..23fce0e 100644 --- a/libadhocutil/fileUtils.cpp +++ b/libadhocutil/fileUtils.cpp @@ -12,6 +12,11 @@ namespace AdHoc { return *pp; } + FileHandle::FileHandle(int d) : + fh(d) + { + } + FileHandle::FileHandle(const boost::filesystem::path & path, int flags) : fh(open(path.c_str(), flags)) { @@ -33,6 +38,11 @@ namespace AdHoc { close(fh); } + FileHandle::operator int() const + { + return fh; + } + FileHandleStat::FileHandleStat(const boost::filesystem::path & path) : FileHandle(path) { diff --git a/libadhocutil/fileUtils.h b/libadhocutil/fileUtils.h index 6ab20d3..4df8c97 100644 --- a/libadhocutil/fileUtils.h +++ b/libadhocutil/fileUtils.h @@ -21,6 +21,12 @@ namespace AdHoc { */ class DLL_PUBLIC FileHandle { public: + /** + * Construct from an existing file descriptor. + * @param fd An open file descriptor. + */ + FileHandle(int fd); + /** * Open a new file handle. * @param path Path of file to open. @@ -38,6 +44,15 @@ namespace AdHoc { virtual ~FileHandle(); + FileHandle(const FileHandle &) = delete; + void operator=(const FileHandle &) = delete; + + /** + * Implicit conversion back to raw Unix file descriptor. + * @return The container file descriptor. + */ + operator int() const; + /// The file handle. const int fh; }; diff --git a/libadhocutil/unittests/testFileUtils.cpp b/libadhocutil/unittests/testFileUtils.cpp index 2a5ab60..0e1cb79 100644 --- a/libadhocutil/unittests/testFileUtils.cpp +++ b/libadhocutil/unittests/testFileUtils.cpp @@ -5,6 +5,14 @@ #include #include +BOOST_AUTO_TEST_CASE( raw ) +{ + int f = open("/proc/self/exe", O_RDONLY); + BOOST_REQUIRE(f != -1); + AdHoc::FileUtils::FileHandle fh(f); + BOOST_REQUIRE_EQUAL(f, fh); +} + BOOST_AUTO_TEST_CASE( memmap ) { AdHoc::FileUtils::MemMap f(rootDir / "testFileUtils.cpp"); @@ -13,6 +21,16 @@ BOOST_AUTO_TEST_CASE( memmap ) BOOST_REQUIRE_EQUAL(0, memcmp(f.data, "#define BOOST_TEST_MODULE FileUtils", 35)); } +BOOST_AUTO_TEST_CASE( openmode ) +{ + boost::filesystem::remove(binDir / "test.file"); + BOOST_REQUIRE_THROW({ + AdHoc::FileUtils::FileHandle fh(binDir / "test.file", O_RDONLY, S_IRWXU); + }, AdHoc::SystemExceptionOn); + AdHoc::FileUtils::FileHandle fh(binDir / "test.file", O_CREAT, S_IRWXU); + boost::filesystem::remove(binDir / "test.file"); +} + BOOST_AUTO_TEST_CASE( openfail ) { BOOST_REQUIRE_THROW({ -- cgit v1.2.3