diff options
author | Shea Levy <shea@shealevy.com> | 2016-07-11T19·44-0400 |
---|---|---|
committer | Shea Levy <shea@shealevy.com> | 2016-07-11T19·44-0400 |
commit | cb5e7254b66a06b78a5659551a6f28fc67e52267 (patch) | |
tree | e367ff5e386fc16247034da60cf30aff61ebaea4 /src/libutil | |
parent | 8a41792d431d6578836fde04d1742dbba878f979 (diff) |
Modernize AutoCloseFD
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/archive.cc | 15 | ||||
-rw-r--r-- | src/libutil/hash.cc | 4 | ||||
-rw-r--r-- | src/libutil/util.cc | 63 | ||||
-rw-r--r-- | src/libutil/util.hh | 14 |
4 files changed, 42 insertions, 54 deletions
diff --git a/src/libutil/archive.cc b/src/libutil/archive.cc index c3e4c87a5599..edd4a881b485 100644 --- a/src/libutil/archive.cc +++ b/src/libutil/archive.cc @@ -42,14 +42,14 @@ static void dumpContents(const Path & path, size_t size, sink << "contents" << size; AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (fd == -1) throw SysError(format("opening file ‘%1%’") % path); + if (!fd) throw SysError(format("opening file ‘%1%’") % path); unsigned char buf[65536]; size_t left = size; while (left > 0) { size_t n = left > sizeof(buf) ? sizeof(buf) : left; - readFull(fd, buf, n); + readFull(fd.get(), buf, n); left -= n; sink(buf, n); } @@ -303,17 +303,16 @@ struct RestoreSink : ParseSink void createRegularFile(const Path & path) { Path p = dstPath + path; - fd.close(); fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_CLOEXEC, 0666); - if (fd == -1) throw SysError(format("creating file ‘%1%’") % p); + if (!fd) throw SysError(format("creating file ‘%1%’") % p); } void isExecutable() { struct stat st; - if (fstat(fd, &st) == -1) + if (fstat(fd.get(), &st) == -1) throw SysError("fstat"); - if (fchmod(fd, st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) + if (fchmod(fd.get(), st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1) throw SysError("fchmod"); } @@ -321,7 +320,7 @@ struct RestoreSink : ParseSink { #if HAVE_POSIX_FALLOCATE if (len) { - errno = posix_fallocate(fd, 0, len); + errno = posix_fallocate(fd.get(), 0, len); /* Note that EINVAL may indicate that the underlying filesystem doesn't support preallocation (e.g. on OpenSolaris). Since preallocation is just an @@ -334,7 +333,7 @@ struct RestoreSink : ParseSink void receiveContents(unsigned char * data, unsigned int len) { - writeFull(fd, data, len); + writeFull(fd.get(), data, len); } void createSymlink(const Path & path, const string & target) diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 69ea95852c3f..fa42587777cd 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -255,11 +255,11 @@ Hash hashFile(HashType ht, const Path & path) start(ht, ctx); AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (fd == -1) throw SysError(format("opening file ‘%1%’") % path); + if (!fd) throw SysError(format("opening file ‘%1%’") % path); unsigned char buf[8192]; ssize_t n; - while ((n = read(fd, buf, sizeof(buf)))) { + while ((n = read(fd.get(), buf, sizeof(buf)))) { checkInterrupt(); if (n == -1) throw SysError(format("reading file ‘%1%’") % path); update(ht, ctx, buf, n); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 4cc4649c98d0..f1e714a664a5 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -274,18 +274,18 @@ string readFile(int fd) string readFile(const Path & path, bool drain) { AutoCloseFD fd = open(path.c_str(), O_RDONLY | O_CLOEXEC); - if (fd == -1) + if (!fd) throw SysError(format("opening file ‘%1%’") % path); - return drain ? drainFD(fd) : readFile(fd); + return drain ? drainFD(fd.get()) : readFile(fd.get()); } void writeFile(const Path & path, const string & s) { AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0666); - if (fd == -1) + if (!fd) throw SysError(format("opening file ‘%1%’") % path); - writeFull(fd, s); + writeFull(fd.get(), s); } @@ -556,28 +556,24 @@ void AutoDelete::reset(const Path & p, bool recursive) { ////////////////////////////////////////////////////////////////////// -AutoCloseFD::AutoCloseFD() -{ - fd = -1; -} +AutoCloseFD::AutoCloseFD() : fd{-1} {} + + +AutoCloseFD::AutoCloseFD(int fd) : fd{fd} {} -AutoCloseFD::AutoCloseFD(int fd) +AutoCloseFD::AutoCloseFD(AutoCloseFD&& that) : fd{that.fd} { - this->fd = fd; + that.fd = -1; } -AutoCloseFD::AutoCloseFD(const AutoCloseFD & fd) +AutoCloseFD& AutoCloseFD::operator =(AutoCloseFD&& that) { - /* Copying an AutoCloseFD isn't allowed (who should get to close - it?). But as an edge case, allow copying of closed - AutoCloseFDs. This is necessary due to tiresome reasons - involving copy constructor use on default object values in STL - containers (like when you do `map[value]' where value isn't in - the map yet). */ - this->fd = fd.fd; - if (this->fd != -1) abort(); + close(); + fd = that.fd; + that.fd = -1; + return *this; } @@ -591,14 +587,7 @@ AutoCloseFD::~AutoCloseFD() } -void AutoCloseFD::operator =(int fd) -{ - if (this->fd != fd) close(); - this->fd = fd; -} - - -AutoCloseFD::operator int() const +int AutoCloseFD::get() const { return fd; } @@ -610,19 +599,17 @@ void AutoCloseFD::close() if (::close(fd) == -1) /* This should never happen. */ throw SysError(format("closing file descriptor %1%") % fd); - fd = -1; } } -bool AutoCloseFD::isOpen() +AutoCloseFD::operator bool() const { return fd != -1; } -/* Pass responsibility for closing this fd to the caller. */ -int AutoCloseFD::borrow() +int AutoCloseFD::release() { int oldFD = fd; fd = -1; @@ -899,10 +886,10 @@ string runProgram(Path program, bool searchPath, const Strings & args, /* Fork. */ Pid pid = startProcess([&]() { - if (dup2(out.writeSide, STDOUT_FILENO) == -1) + if (dup2(out.writeSide.get(), STDOUT_FILENO) == -1) throw SysError("dupping stdout"); if (!input.empty()) { - if (dup2(in.readSide, STDIN_FILENO) == -1) + if (dup2(in.readSide.get(), STDIN_FILENO) == -1) throw SysError("dupping stdin"); } @@ -917,16 +904,16 @@ string runProgram(Path program, bool searchPath, const Strings & args, throw SysError(format("executing ‘%1%’") % program); }); - out.writeSide.close(); + out.writeSide = -1; /* FIXME: This can deadlock if the input is too long. */ if (!input.empty()) { - in.readSide.close(); - writeFull(in.writeSide, input); - in.writeSide.close(); + in.readSide = -1; + writeFull(in.writeSide.get(), input); + in.writeSide = -1; } - string result = drainFD(out.readSide); + string result = drainFD(out.readSide.get()); /* Wait for the child to finish. */ int status = pid.wait(true); diff --git a/src/libutil/util.hh b/src/libutil/util.hh index ab43637a574c..819921dfff1e 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -164,16 +164,18 @@ public: class AutoCloseFD { int fd; + void close(); public: AutoCloseFD(); AutoCloseFD(int fd); - AutoCloseFD(const AutoCloseFD & fd); + AutoCloseFD(const AutoCloseFD & fd) = delete; + AutoCloseFD(AutoCloseFD&& fd); ~AutoCloseFD(); - void operator =(int fd); - operator int() const; - void close(); - bool isOpen(); - int borrow(); + AutoCloseFD& operator =(const AutoCloseFD & fd) = delete; + AutoCloseFD& operator =(AutoCloseFD&& fd); + int get() const; + explicit operator bool() const; + int release(); }; |