From: Aravind Anbudurai Date: Wed, 3 May 2017 22:33:31 +0000 (-0700) Subject: Helper utility to construct, returns an Expected<..> X-Git-Tag: v2017.05.08.00~13 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=919d544e2482da913110b018b572232cdc17718a;p=folly.git Helper utility to construct, returns an Expected<..> Summary: folly::File's throwing constructor results in many try-catches in the callsites or bugs where the exception is not caught. This is a helper method to return an Expected with system_error wrapped into an exception_wrapper. Reviewed By: yfeldblum Differential Revision: D4995702 fbshipit-source-id: be0e22b37c21c35bf157ada598916b05dfd32631 --- diff --git a/folly/File.cpp b/folly/File.cpp index 4df3274e..be44ce57 100644 --- a/folly/File.cpp +++ b/folly/File.cpp @@ -31,14 +31,9 @@ namespace folly { -File::File() - : fd_(-1) - , ownsFd_(false) -{} - -File::File(int fd, bool ownsFd) - : fd_(fd) - , ownsFd_(ownsFd) { +File::File() noexcept : fd_(-1), ownsFd_(false) {} + +File::File(int fd, bool ownsFd) noexcept : fd_(fd), ownsFd_(ownsFd) { CHECK_GE(fd, -1) << "fd must be -1 or non-negative"; CHECK(fd != -1 || !ownsFd) << "cannot own -1"; } diff --git a/folly/File.h b/folly/File.h index e936ca87..af662096 100644 --- a/folly/File.h +++ b/folly/File.h @@ -21,7 +21,10 @@ #include #include +#include +#include +#include #include #include #include @@ -36,13 +39,13 @@ class File { /** * Creates an empty File object, for late initialization. */ - File(); + File() noexcept; /** * Create a File object from an existing file descriptor. * Takes ownership of the file descriptor if ownsFd is true. */ - explicit File(int fd, bool ownsFd = false); + explicit File(int fd, bool ownsFd = false) noexcept; /** * Open and create a file object. Throws on error. @@ -52,6 +55,20 @@ class File { const std::string& name, int flags = O_RDONLY, mode_t mode = 0666); explicit File(StringPiece name, int flags = O_RDONLY, mode_t mode = 0666); + /** + * All the constructors that are not noexcept can throw std::system_error. + * This is a helper method to use folly::Expected to chain a file open event + * to something else you want to do with the open fd. + */ + template + static Expected makeFile(Args&&... args) noexcept { + try { + return File(std::forward(args)...); + } catch (const std::system_error& se) { + return makeUnexpected(exception_wrapper(std::current_exception(), se)); + } + } + ~File(); /** diff --git a/folly/test/FileTest.cpp b/folly/test/FileTest.cpp index 73ccf0e3..7aec67ba 100644 --- a/folly/test/FileTest.cpp +++ b/folly/test/FileTest.cpp @@ -135,3 +135,13 @@ TEST(File, Truthy) { EXPECT_TRUE(false); } } + +TEST(File, HelperCtor) { + File::makeFile(StringPiece("/etc/hosts")).then([](File&& f) { + char buf = 'x'; + EXPECT_NE(-1, f.fd()); + EXPECT_EQ(1, ::read(f.fd(), &buf, 1)); + f.close(); + EXPECT_EQ(-1, f.fd()); + }); +}