A file descriptor closer that uses HANDLE_EINTR.
- A new flavor of ScopedFdCloser which wraps close() with HANDLE_EINTR,
which will retry closing the file descriptor if the last close attempt
was interrupted by EINTR. This appears to be a recommended practice
per POSIX documentation.
- Both ScopedFdCloser and ScopedEintrSafeFdCloser ensure a successful
close() prior to resetting the file descriptor.
- Better use of HANDLE_EINTR elsewhere: just realized that this macro
returns the value of the last evaluation of its argument.
BUG=chromium-os:25397
TEST=Image builds properly; GPIO functionality works (x86-alex).
Change-Id: I3425bb580499c7138cd31917011662d33ffab8a6
Reviewed-on: https://gerrit.chromium.org/gerrit/17079
Reviewed-by: Andrew de los Reyes <adlr@chromium.org>
Reviewed-by: Darin Petkov <petkov@chromium.org>
Commit-Ready: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/update_attempter.cc b/update_attempter.cc
index 210e78a..bdf0105 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -760,20 +760,18 @@
// Open device for reading.
string dutflaga_value_dev_name = dutflaga_dev_name + "/value";
- int dutflaga_fd;
- HANDLE_EINTR((dutflaga_fd = open(dutflaga_value_dev_name.c_str(), 0)));
+ int dutflaga_fd = HANDLE_EINTR(open(dutflaga_value_dev_name.c_str(), 0));
if (dutflaga_fd < 0) {
PLOG(ERROR) << "opening dutflaga GPIO device file failed";
return false;
}
- ScopedFdCloser dutflaga_fd_closer(&dutflaga_fd);
+ ScopedEintrSafeFdCloser dutflaga_fd_closer(&dutflaga_fd);
// Read the dut_flaga GPIO signal. We attempt to read more than---but expect
// to receive exactly---two characters: a '0' or '1', and a newline. This is
// to ensure that the GPIO device returns a legible result.
char buf[3];
- int ret;
- HANDLE_EINTR((ret = read(dutflaga_fd, buf, 3)));
+ int ret = HANDLE_EINTR(read(dutflaga_fd, buf, 3));
if (ret != 2) {
if (ret < 0)
PLOG(ERROR) << "reading dutflaga GPIO status failed";
diff --git a/utils.h b/utils.h
index b0b28a8..728d992 100644
--- a/utils.h
+++ b/utils.h
@@ -12,6 +12,7 @@
#include <string>
#include <vector>
+#include <base/eintr_wrapper.h>
#include <ext2fs/ext2fs.h>
#include <glib.h>
@@ -276,8 +277,8 @@
explicit ScopedFdCloser(int* fd) : fd_(fd), should_close_(true) {}
~ScopedFdCloser() {
if (should_close_ && fd_ && (*fd_ >= 0)) {
- close(*fd_);
- *fd_ = -1;
+ if (!close(*fd_))
+ *fd_ = -1;
}
}
void set_should_close(bool should_close) { should_close_ = should_close; }
@@ -287,6 +288,23 @@
DISALLOW_COPY_AND_ASSIGN(ScopedFdCloser);
};
+// An EINTR-immune file descriptor closer.
+class ScopedEintrSafeFdCloser {
+ public:
+ explicit ScopedEintrSafeFdCloser(int* fd) : fd_(fd), should_close_(true) {}
+ ~ScopedEintrSafeFdCloser() {
+ if (should_close_ && fd_ && (*fd_ >= 0)) {
+ if (!HANDLE_EINTR(close(*fd_)))
+ *fd_ = -1;
+ }
+ }
+ void set_should_close(bool should_close) { should_close_ = should_close; }
+ private:
+ int* fd_;
+ bool should_close_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedEintrSafeFdCloser);
+};
+
// Utility class to close a file system
class ScopedExt2fsCloser {
public: