summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 21:37:31 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 21:37:31 +0000
commit157c61b07b3ce5e308db6230da9d93ff74a16ca3 (patch)
tree7a627dd3c11b684852e2a3ffe84bcfc079bf1316
parent105414ec43286c5ba9953eaf66f147a9a1a6afd5 (diff)
downloadchromium_src-157c61b07b3ce5e308db6230da9d93ff74a16ca3.zip
chromium_src-157c61b07b3ce5e308db6230da9d93ff74a16ca3.tar.gz
chromium_src-157c61b07b3ce5e308db6230da9d93ff74a16ca3.tar.bz2
POSIX: Add a macro for handling EINTR.
On POSIX systems, system calls can be interrupted by signals. In this case, they'll return EINTR, indicating that the system call needs to be restarted. (The situation is a little more complicated than this with SA_RESTART, but you can read man 7 signal if you like.) The short of it is that you need to catch EINTR and restart the call for these system calls: * read, readv, write, writev, ioctl * open() when dealing with a fifo * wait* * Anything socket based (send*, recv*, connect, accept etc) * flock and lock control with fcntl * mq_ functions which can block * futex * sem_wait (and timed wait) * pause, sigsuspend, sigtimedwait, sigwaitinfo * poll, epoll_wait, select and 'p' versions of the same * msgrcv, msgsnd, semop, semtimedop * close (although, on Linux, EINTR won't happen here) * any sleep functions (careful, you need to handle this are restart with different arguments) We've been a little sloppy with this until now. This patch adds a macro for dealing with this and corrects every case of these system calls (that I found). The macro is HANDLE_EINTR in base/eintr_wrapper.h. It's safe to include on Windows and is a no-op there. On POSIX, it uses GCC magic to return the correct type based on the expression and restarts the system call if it throws EINTR. And you can use it like: HANDLE_EINTR(close(fd)); Or: ssize_t bytes_read = HANDLE_EINTR(read(fd, buffer, len)); *BEWARE* that it will evaluate the argument multiple times, so this is not safe: HANDLE_EINTR(close(FireMissiles())); http://groups.google.com/group/chromium-dev/browse_thread/thread/41a35b2a457d73a0 http://codereview.chromium.org/100225 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15102 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/debug_util_posix.cc5
-rw-r--r--base/directory_watcher_inotify.cc24
-rw-r--r--base/eintr_wrapper.h33
-rw-r--r--base/file_descriptor_shuffle.cc20
-rw-r--r--base/file_util_linux.cc11
-rw-r--r--base/file_util_posix.cc23
-rw-r--r--base/message_pump_glib.cc5
-rw-r--r--base/message_pump_libevent.cc5
-rw-r--r--base/process_util_linux.cc3
-rw-r--r--base/process_util_mac.mm3
-rw-r--r--base/process_util_posix.cc40
-rw-r--r--base/process_util_unittest.cc22
-rw-r--r--chrome/browser/debugger/devtools_remote_listen_socket.cc3
-rw-r--r--chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc21
-rw-r--r--chrome/browser/process_singleton_linux.cc4
-rw-r--r--chrome/browser/renderer_host/render_widget_helper.cc5
-rw-r--r--chrome/common/file_descriptor_set_posix.cc5
-rw-r--r--chrome/common/file_descriptor_set_unittest.cc7
-rw-r--r--chrome/common/ipc_channel_posix.cc109
-rw-r--r--chrome/common/ipc_send_fds_test.cc5
-rw-r--r--chrome/common/process_watcher_posix.cc8
-rw-r--r--chrome/common/transport_dib_mac.cc4
-rw-r--r--net/base/file_stream_posix.cc27
-rw-r--r--net/base/listen_socket.cc8
-rw-r--r--net/base/listen_socket_unittest.cc12
-rw-r--r--net/base/tcp_client_socket_libevent.cc18
-rw-r--r--net/base/telnet_server.cc3
27 files changed, 221 insertions, 212 deletions
diff --git a/base/debug_util_posix.cc b/base/debug_util_posix.cc
index ced59c8..34cc45c 100644
--- a/base/debug_util_posix.cc
+++ b/base/debug_util_posix.cc
@@ -15,6 +15,7 @@
#include <unistd.h>
#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/string_piece.h"
@@ -85,8 +86,8 @@ bool DebugUtil::BeingDebugged() {
// This simplifies and speeds up things considerably.
char buf[1024];
- ssize_t num_read = read(status_fd, buf, sizeof(buf));
- close(status_fd);
+ ssize_t num_read = HANDLE_EINTR(read(status_fd, buf, sizeof(buf)));
+ HANDLE_EINTR(close(status_fd));
if (num_read <= 0)
return false;
diff --git a/base/directory_watcher_inotify.cc b/base/directory_watcher_inotify.cc
index a17e1e4..86e7bd9 100644
--- a/base/directory_watcher_inotify.cc
+++ b/base/directory_watcher_inotify.cc
@@ -16,6 +16,7 @@
#include <utility>
#include <vector>
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/hash_tables.h"
#include "base/lock.h"
@@ -100,11 +101,10 @@ class InotifyReaderTask : public Task {
FD_SET(shutdown_fd_, &rfds);
// Wait until some inotify events are available.
- int select_result = select(std::max(inotify_fd_, shutdown_fd_) + 1,
- &rfds, NULL, NULL, NULL);
+ int select_result =
+ HANDLE_EINTR(select(std::max(inotify_fd_, shutdown_fd_) + 1,
+ &rfds, NULL, NULL, NULL));
if (select_result < 0) {
- if (errno == EINTR)
- continue;
DLOG(WARNING) << "select failed: " << strerror(errno);
return;
}
@@ -114,7 +114,8 @@ class InotifyReaderTask : public Task {
// Adjust buffer size to current event queue size.
int buffer_size;
- int ioctl_result = ioctl(inotify_fd_, FIONREAD, &buffer_size);
+ int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd_, FIONREAD,
+ &buffer_size));
if (ioctl_result != 0) {
DLOG(WARNING) << "ioctl failed: " << strerror(errno);
@@ -123,10 +124,8 @@ class InotifyReaderTask : public Task {
std::vector<char> buffer(buffer_size);
- ssize_t bytes_read;
- do {
- bytes_read = read(inotify_fd_, &buffer[0], buffer_size);
- } while (bytes_read < 0 && errno == EINTR);
+ ssize_t bytes_read = HANDLE_EINTR(read(inotify_fd_, &buffer[0],
+ buffer_size));
if (bytes_read < 0) {
DLOG(WARNING) << "read from inotify fd failed: " << strerror(errno);
@@ -188,12 +187,7 @@ InotifyReader::~InotifyReader() {
if (valid_) {
// Write to the self-pipe so that the select call in InotifyReaderTask
// returns.
- ssize_t bytes_written;
- do {
- bytes_written = write(shutdown_pipe_[1], "", 1);
- if (bytes_written == 0)
- continue;
- } while (bytes_written == -1 && errno == EINTR);
+ HANDLE_EINTR(write(shutdown_pipe_[1], "", 1));
thread_.Stop();
}
if (inotify_fd_ >= 0)
diff --git a/base/eintr_wrapper.h b/base/eintr_wrapper.h
new file mode 100644
index 0000000..a3fb1e4
--- /dev/null
+++ b/base/eintr_wrapper.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This provides a wrapper around system calls which may be interrupted by a
+// signal and return EINTR. See man 7 signal.
+//
+// On Windows, this wrapper macro does nothing.
+
+#ifndef BASE_EINTR_WRAPPER_H_
+#define BASE_EINTR_WRAPPER_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_POSIX)
+
+#include <errno.h>
+
+#define HANDLE_EINTR(x) ({ \
+ typeof(x) __eintr_result__; \
+ do { \
+ __eintr_result__ = x; \
+ } while (__eintr_result__ == -1 && errno == EINTR); \
+ __eintr_result__;\
+})
+
+#else
+
+#define HANDLE_EINTR(x) x
+
+#endif // OS_POSIX
+
+#endif // !BASE_EINTR_WRAPPER_H_
diff --git a/base/file_descriptor_shuffle.cc b/base/file_descriptor_shuffle.cc
index 1426155..28447c9 100644
--- a/base/file_descriptor_shuffle.cc
+++ b/base/file_descriptor_shuffle.cc
@@ -7,6 +7,7 @@
#include <errno.h>
#include <unistd.h>
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
namespace base {
@@ -64,29 +65,16 @@ bool PerformInjectiveMultimap(const InjectiveMultimap& m_in,
}
bool FileDescriptorTableInjection::Duplicate(int* result, int fd) {
- do {
- *result = dup(fd);
- } while(*result == -1 && errno == EINTR);
-
+ *result = HANDLE_EINTR(dup(fd));
return *result >= 0;
}
bool FileDescriptorTableInjection::Move(int src, int dest) {
- int result;
-
- do {
- result = dup2(src, dest);
- } while (result == -1 && errno == EINTR);
-
- return result != -1;
+ return HANDLE_EINTR(dup2(src, dest)) != -1;
}
void FileDescriptorTableInjection::Close(int fd) {
- int result;
-
- do {
- result = close(fd);
- } while (result == -1 && errno == EINTR);
+ HANDLE_EINTR(close(fd));
}
} // namespace base
diff --git a/base/file_util_linux.cc b/base/file_util_linux.cc
index d595fe1..0f9795e 100644
--- a/base/file_util_linux.cc
+++ b/base/file_util_linux.cc
@@ -9,6 +9,7 @@
#include <string>
#include <vector>
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/string_util.h"
@@ -44,7 +45,7 @@ bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
bool result = true;
while (result) {
- ssize_t bytes_read = read(infile, &buffer[0], buffer.size());
+ ssize_t bytes_read = HANDLE_EINTR(read(infile, &buffer[0], buffer.size()));
if (bytes_read < 0) {
result = false;
break;
@@ -54,10 +55,10 @@ bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
// Allow for partial writes
ssize_t bytes_written_per_read = 0;
do {
- ssize_t bytes_written_partial = write(
+ ssize_t bytes_written_partial = HANDLE_EINTR(write(
outfile,
&buffer[bytes_written_per_read],
- bytes_read - bytes_written_per_read);
+ bytes_read - bytes_written_per_read));
if (bytes_written_partial < 0) {
result = false;
break;
@@ -66,9 +67,9 @@ bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
} while (bytes_written_per_read < bytes_read);
}
- if (close(infile) < 0)
+ if (HANDLE_EINTR(close(infile)) < 0)
result = false;
- if (close(outfile) < 0)
+ if (HANDLE_EINTR(close(outfile)) < 0)
result = false;
return result;
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 1835d3a..06f3c1a 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -22,6 +22,7 @@
#include <fstream>
#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/string_util.h"
@@ -335,11 +336,11 @@ bool GetFileCreationLocalTime(const std::string& filename,
bool ReadFromFD(int fd, char* buffer, size_t bytes) {
size_t total_read = 0;
while (total_read < bytes) {
- ssize_t bytes_read = read(fd, buffer + total_read, bytes - total_read);
- if (bytes_read > 0)
- total_read += bytes_read;
- else if (bytes_read == 0 || errno != EINTR)
+ ssize_t bytes_read =
+ HANDLE_EINTR(read(fd, buffer + total_read, bytes - total_read));
+ if (bytes_read <= 0)
break;
+ total_read += bytes_read;
}
return total_read == bytes;
}
@@ -453,8 +454,8 @@ int ReadFile(const FilePath& filename, char* data, int size) {
if (fd < 0)
return -1;
- int ret_value = read(fd, data, size);
- close(fd);
+ int ret_value = HANDLE_EINTR(read(fd, data, size));
+ HANDLE_EINTR(close(fd));
return ret_value;
}
@@ -466,17 +467,17 @@ int WriteFile(const FilePath& filename, const char* data, int size) {
// Allow for partial writes
ssize_t bytes_written_total = 0;
do {
- ssize_t bytes_written_partial = write(fd,
- data + bytes_written_total,
- size - bytes_written_total);
+ ssize_t bytes_written_partial =
+ HANDLE_EINTR(write(fd, data + bytes_written_total,
+ size - bytes_written_total));
if (bytes_written_partial < 0) {
- close(fd);
+ HANDLE_EINTR(close(fd));
return -1;
}
bytes_written_total += bytes_written_partial;
} while (bytes_written_total < size);
- close(fd);
+ HANDLE_EINTR(close(fd));
return bytes_written_total;
}
diff --git a/base/message_pump_glib.cc b/base/message_pump_glib.cc
index c18bfd3..da40f26 100644
--- a/base/message_pump_glib.cc
+++ b/base/message_pump_glib.cc
@@ -7,6 +7,7 @@
#include <fcntl.h>
#include <math.h>
+#include "base/eintr_wrapper.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/platform_thread.h"
@@ -177,7 +178,7 @@ void MessagePumpForUI::HandleDispatch() {
// poll will tell us whether there was data, so this read shouldn't block.
if (wakeup_gpollfd_.revents & G_IO_IN) {
char msg;
- if (read(wakeup_pipe_read_, &msg, 1) != 1 || msg != '!') {
+ if (HANDLE_EINTR(read(wakeup_pipe_read_, &msg, 1)) != 1 || msg != '!') {
NOTREACHED() << "Error reading from the wakeup pipe.";
}
}
@@ -222,7 +223,7 @@ void MessagePumpForUI::ScheduleWork() {
// variables as we would then need locks all over. This ensures that if
// we are sleeping in a poll that we will wake up.
char msg = '!';
- if (write(wakeup_pipe_write_, &msg, 1) != 1) {
+ if (HANDLE_EINTR(write(wakeup_pipe_write_, &msg, 1)) != 1) {
NOTREACHED() << "Could not write to the UI message loop wakeup pipe!";
}
}
diff --git a/base/message_pump_libevent.cc b/base/message_pump_libevent.cc
index f2681f3..a940081 100644
--- a/base/message_pump_libevent.cc
+++ b/base/message_pump_libevent.cc
@@ -7,6 +7,7 @@
#include <errno.h>
#include <fcntl.h>
+#include "eintr_wrapper.h"
#include "base/logging.h"
#include "base/scoped_nsautorelease_pool.h"
#include "base/scoped_ptr.h"
@@ -87,7 +88,7 @@ void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) {
// Remove and discard the wakeup byte.
char buf;
- int nread = read(socket, &buf, 1);
+ int nread = HANDLE_EINTR(read(socket, &buf, 1));
DCHECK_EQ(nread, 1);
// Tell libevent to break out of inner loop.
event_base_loopbreak(that->event_base_);
@@ -272,7 +273,7 @@ void MessagePumpLibevent::Quit() {
void MessagePumpLibevent::ScheduleWork() {
// Tell libevent (in a threadsafe way) that it should break out of its loop.
char buf = 0;
- int nwrite = write(wakeup_pipe_in_, &buf, 1);
+ int nwrite = HANDLE_EINTR(write(wakeup_pipe_in_, &buf, 1));
DCHECK(nwrite == 1 || errno == EAGAIN)
<< "[nwrite:" << nwrite << "] [errno:" << errno << "]";
}
diff --git a/base/process_util_linux.cc b/base/process_util_linux.cc
index f8e8a04..b542e6f 100644
--- a/base/process_util_linux.cc
+++ b/base/process_util_linux.cc
@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include "base/eintr_wrapper.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_tokenizer.h"
@@ -55,7 +56,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
exit(127);
} else {
if (wait)
- waitpid(pid, 0, 0);
+ HANDLE_EINTR(waitpid(pid, 0, 0));
if (process_handle)
*process_handle = pid;
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index f489bd0..bcdaffe 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -14,6 +14,7 @@
#include <string>
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/time.h"
@@ -76,7 +77,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
retval = false;
} else {
if (wait)
- waitpid(pid, 0, 0);
+ HANDLE_EINTR(waitpid(pid, 0, 0));
if (process_handle)
*process_handle = pid;
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index c0e792b..e66576a 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -17,6 +17,7 @@
#include <set>
#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/platform_thread.h"
#include "base/process_util.h"
@@ -69,7 +70,7 @@ bool KillProcess(ProcessHandle process_id, int exit_code, bool wait) {
int tries = 60;
// The process may not end immediately due to pending I/O
while (tries-- > 0) {
- int pid = waitpid(process_id, NULL, WNOHANG);
+ int pid = HANDLE_EINTR(waitpid(process_id, NULL, WNOHANG));
if (pid == process_id)
break;
@@ -139,10 +140,7 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
if (saved_fds.find(fd) != saved_fds.end())
continue;
- int result;
- do {
- result = close(fd);
- } while (result == -1 && errno == EINTR);
+ HANDLE_EINTR(close(fd));
}
return;
}
@@ -161,10 +159,7 @@ void CloseSuperfluousFds(const base::InjectiveMultimap& saved_mapping) {
if (saved_fds.find(fd) != saved_fds.end())
continue;
- int result;
- do {
- result = close(fd);
- } while (result == -1 && errno == EINTR);
+ HANDLE_EINTR(close(fd));
}
}
@@ -226,7 +221,7 @@ void RaiseProcessToHighPriority() {
bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
int status;
- const int result = waitpid(handle, &status, WNOHANG);
+ const int result = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
if (result == -1) {
LOG(ERROR) << "waitpid failed pid:" << handle << " errno:" << errno;
if (child_exited)
@@ -262,11 +257,9 @@ bool DidProcessCrash(bool* child_exited, ProcessHandle handle) {
bool WaitForExitCode(ProcessHandle handle, int* exit_code) {
int status;
- while (waitpid(handle, &status, 0) == -1) {
- if (errno != EINTR) {
- NOTREACHED();
- return false;
- }
+ if (HANDLE_EINTR(waitpid(handle, &status, 0)) == -1) {
+ NOTREACHED();
+ return false;
}
if (WIFEXITED(status)) {
@@ -305,7 +298,7 @@ int WaitpidWithTimeout(ProcessHandle handle, int wait_milliseconds,
// This function is used primarily for unit tests, if we want to use it in
// the application itself it would probably be best to examine other routes.
int status = -1;
- pid_t ret_pid = waitpid(handle, &status, WNOHANG);
+ pid_t ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
static const int64 kQuarterSecondInMicroseconds = kMicrosecondsPerSecond/4;
// If the process hasn't exited yet, then sleep and try again.
@@ -325,7 +318,7 @@ int WaitpidWithTimeout(ProcessHandle handle, int wait_milliseconds,
// usleep() will return 0 and set errno to EINTR on receipt of a signal
// such as SIGCHLD.
usleep(sleep_time_usecs);
- ret_pid = waitpid(handle, &status, WNOHANG);
+ ret_pid = HANDLE_EINTR(waitpid(handle, &status, WNOHANG));
}
if (success)
@@ -340,7 +333,7 @@ bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) {
bool waitpid_success;
int status;
if (wait_milliseconds == base::kNoTimeout)
- waitpid_success = (waitpid(handle, &status, 0) != -1);
+ waitpid_success = (HANDLE_EINTR(waitpid(handle, &status, 0)) != -1);
else
status = WaitpidWithTimeout(handle, wait_milliseconds, &waitpid_success);
if (status != -1) {
@@ -463,16 +456,13 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
char buffer[256];
std::string buf_output;
- ssize_t bytes_read = 0;
while (true) {
- bytes_read = read(pipe_fd[0], buffer, sizeof(buffer));
- if (bytes_read == 0)
- break;
- if (bytes_read == -1 && errno != EINTR)
+ ssize_t bytes_read =
+ HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
+ if (bytes_read <= 0)
break;
- if (bytes_read > 0)
- buf_output.append(buffer, bytes_read);
+ buf_output.append(buffer, bytes_read);
}
output->swap(buf_output);
close(pipe_fd[0]);
diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc
index 76b705d..30a2c07 100644
--- a/base/process_util_unittest.cc
+++ b/base/process_util_unittest.cc
@@ -5,6 +5,7 @@
#define _CRT_SECURE_NO_WARNINGS
#include "base/command_line.h"
+#include "base/eintr_wrapper.h"
#include "base/file_path.h"
#include "base/multiprocess_test.h"
#include "base/path_service.h"
@@ -191,7 +192,7 @@ MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) {
int max_files = GetMaxFilesOpenInProcess();
for (int i = STDERR_FILENO + 1; i < max_files; i++) {
if (i != kChildPipe) {
- if (close(i) != -1) {
+ if (HANDLE_EINTR(close(i)) != -1) {
LOG(WARNING) << "Leaked FD " << i;
num_open_files += 1;
}
@@ -206,9 +207,10 @@ MULTIPROCESS_TEST_MAIN(ProcessUtilsLeakFDChildProcess) {
#endif // defined(OS_LINUX)
num_open_files -= expected_num_open_fds;
- int written = write(write_pipe, &num_open_files, sizeof(num_open_files));
+ int written = HANDLE_EINTR(write(write_pipe, &num_open_files,
+ sizeof(num_open_files)));
DCHECK_EQ(static_cast<size_t>(written), sizeof(num_open_files));
- close(write_pipe);
+ HANDLE_EINTR(close(write_pipe));
return 0;
}
@@ -233,12 +235,12 @@ TEST_F(ProcessUtilTest, FDRemapping) {
fd_mapping_vec,
false);
ASSERT_NE(static_cast<ProcessHandle>(NULL), handle);
- close(pipe_write_fd);
+ HANDLE_EINTR(close(pipe_write_fd));
// Read number of open files in client process from pipe;
int num_open_files = -1;
- ssize_t bytes_read = read(pipe_read_fd, &num_open_files,
- sizeof(num_open_files));
+ ssize_t bytes_read =
+ HANDLE_EINTR(read(pipe_read_fd, &num_open_files, sizeof(num_open_files)));
ASSERT_EQ(bytes_read, static_cast<ssize_t>(sizeof(num_open_files)));
// Make sure 0 fds are leaked to the client.
@@ -246,10 +248,10 @@ TEST_F(ProcessUtilTest, FDRemapping) {
EXPECT_TRUE(WaitForSingleProcess(handle, 1000));
base::CloseProcessHandle(handle);
- close(fds[0]);
- close(sockets[0]);
- close(sockets[1]);
- close(dev_null);
+ HANDLE_EINTR(close(fds[0]));
+ HANDLE_EINTR(close(sockets[0]));
+ HANDLE_EINTR(close(sockets[1]));
+ HANDLE_EINTR(close(dev_null));
}
TEST_F(ProcessUtilTest, GetAppOutput) {
diff --git a/chrome/browser/debugger/devtools_remote_listen_socket.cc b/chrome/browser/debugger/devtools_remote_listen_socket.cc
index 11d38dc..5b7bb21 100644
--- a/chrome/browser/debugger/devtools_remote_listen_socket.cc
+++ b/chrome/browser/debugger/devtools_remote_listen_socket.cc
@@ -21,6 +21,7 @@
#include "third_party/libevent/event.h"
#endif
+#include "base/eintr_wrapper.h"
#include "base/string_util.h"
#include "chrome/browser/debugger/devtools_remote.h"
#include "chrome/browser/debugger/devtools_remote_message.h"
@@ -103,7 +104,7 @@ void DevToolsRemoteListenSocket::Read() {
char buf[kReadBufSize];
int len;
do {
- len = recv(socket_, buf, kReadBufSize, 0);
+ len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
if (len == SOCKET_ERROR) {
#if defined(OS_WIN)
int err = WSAGetLastError();
diff --git a/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc b/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc
index 8a78e9f..efa0642 100644
--- a/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc
+++ b/chrome/browser/debugger/devtools_remote_listen_socket_unittest.cc
@@ -6,6 +6,7 @@
#include <fcntl.h>
+#include "base/eintr_wrapper.h"
#include "net/base/net_util.h"
#include "testing/platform_test.h"
@@ -79,8 +80,9 @@ void DevToolsRemoteListenSocketTester::SetUp() {
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr(kLoopback);
client.sin_port = htons(kTestPort);
- int ret = connect(test_socket_,
- reinterpret_cast<sockaddr*>(&client), sizeof(client));
+ int ret = HANDLE_EINTR(connect(test_socket_,
+ reinterpret_cast<sockaddr*>(&client),
+ sizeof(client)));
ASSERT_NE(ret, SOCKET_ERROR);
net::SetNonBlocking(test_socket_);
@@ -93,7 +95,7 @@ void DevToolsRemoteListenSocketTester::TearDown() {
#if defined(OS_WIN)
closesocket(test_socket_);
#elif defined(OS_POSIX)
- close(test_socket_);
+ HANDLE_EINTR(close(test_socket_));
#endif
ASSERT_TRUE(NextAction(kDefaultTimeoutMs));
ASSERT_EQ(ACTION_CLOSE, last_action_.type());
@@ -177,7 +179,7 @@ int DevToolsRemoteListenSocketTester::ClearTestSocket() {
int len_ret = 0;
int time_out = 0;
do {
- int len = recv(test_socket_, buf, kReadBufSize, 0);
+ int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0));
#if defined(OS_WIN)
if (len == SOCKET_ERROR) {
int err = WSAGetLastError();
@@ -248,7 +250,7 @@ void DevToolsRemoteListenSocketTester::HandleMessage(
bool DevToolsRemoteListenSocketTester::Send(SOCKET sock,
const std::string& str) {
int len = static_cast<int>(str.length());
- int send_len = send(sock, str.data(), len, 0);
+ int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0));
if (send_len == SOCKET_ERROR) {
LOG(ERROR) << "send failed: " << errno;
return false;
@@ -317,14 +319,7 @@ void DevToolsRemoteListenSocketTester::TestServerSend() {
PlatformThread::Sleep(10); // sleep for 10ms
const int buf_len = 200;
char buf[buf_len+1];
- int recv_len;
- do {
- recv_len = recv(test_socket_, buf, buf_len, 0);
-#if defined(OS_POSIX)
- } while (recv_len == SOCKET_ERROR && errno == EINTR);
-#else
- } while (false);
-#endif
+ int recv_len = HANDLE_EINTR(recv(test_socket_, buf, buf_len, 0));
ASSERT_NE(recv_len, SOCKET_ERROR);
buf[recv_len] = 0;
ASSERT_STREQ(buf, kChromeDevToolsHandshake);
diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
index 4fba373..fcd64259 100644
--- a/chrome/browser/process_singleton_linux.cc
+++ b/chrome/browser/process_singleton_linux.cc
@@ -9,6 +9,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/common/chrome_constants.h"
@@ -25,7 +26,8 @@ bool ProcessSingleton::NotifyOtherProcess() {
sockaddr_un addr;
SetupSocket(&sock, &addr);
- if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) < 0 &&
+ if (HANDLE_EINTR(connect(sock, reinterpret_cast<sockaddr*>(&addr),
+ sizeof(addr))) < 0 &&
(errno == ENOENT || errno == ECONNREFUSED)) {
return false; // Tell the caller there's nobody to notify.
}
diff --git a/chrome/browser/renderer_host/render_widget_helper.cc b/chrome/browser/renderer_host/render_widget_helper.cc
index 4432352..d738a75 100644
--- a/chrome/browser/renderer_host/render_widget_helper.cc
+++ b/chrome/browser/renderer_host/render_widget_helper.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/renderer_host/render_widget_helper.h"
+#include "base/eintr_wrapper.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/renderer_host/render_process_host.h"
@@ -311,7 +312,7 @@ void RenderWidgetHelper::FreeTransportDIB(TransportDIB::Id dib_id) {
i = allocated_dibs_.find(dib_id);
if (i != allocated_dibs_.end()) {
- close(i->second);
+ HANDLE_EINTR(close(i->second));
allocated_dibs_.erase(i);
} else {
DLOG(WARNING) << "Renderer asked us to free unknown transport DIB";
@@ -321,7 +322,7 @@ void RenderWidgetHelper::FreeTransportDIB(TransportDIB::Id dib_id) {
void RenderWidgetHelper::ClearAllocatedDIBs() {
for (std::map<TransportDIB::Id, int>::iterator
i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) {
- close(i->second);
+ HANDLE_EINTR(close(i->second));
}
allocated_dibs_.clear();
diff --git a/chrome/common/file_descriptor_set_posix.cc b/chrome/common/file_descriptor_set_posix.cc
index b57c007..1be7aa8 100644
--- a/chrome/common/file_descriptor_set_posix.cc
+++ b/chrome/common/file_descriptor_set_posix.cc
@@ -4,6 +4,7 @@
#include "chrome/common/file_descriptor_set_posix.h"
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
FileDescriptorSet::FileDescriptorSet()
@@ -26,7 +27,7 @@ FileDescriptorSet::~FileDescriptorSet() {
for (unsigned i = consumed_descriptor_highwater_;
i < descriptors_.size(); ++i) {
if (descriptors_[i].auto_close)
- close(descriptors_[i].fd);
+ HANDLE_EINTR(close(descriptors_[i].fd));
}
}
@@ -97,7 +98,7 @@ void FileDescriptorSet::CommitAll() {
for (std::vector<base::FileDescriptor>::iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
if (i->auto_close)
- close(i->fd);
+ HANDLE_EINTR(close(i->fd));
}
descriptors_.clear();
consumed_descriptor_highwater_ = 0;
diff --git a/chrome/common/file_descriptor_set_unittest.cc b/chrome/common/file_descriptor_set_unittest.cc
index 89144a5..7cd9d5f 100644
--- a/chrome/common/file_descriptor_set_unittest.cc
+++ b/chrome/common/file_descriptor_set_unittest.cc
@@ -8,6 +8,7 @@
#include <fcntl.h>
#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
#include "chrome/common/file_descriptor_set_posix.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -140,8 +141,8 @@ TEST(FileDescriptorSet, DontClose) {
const int duped = dup(fd);
ASSERT_GE(duped, 0);
- close(duped);
- close(fd);
+ HANDLE_EINTR(close(duped));
+ HANDLE_EINTR(close(fd));
}
TEST(FileDescriptorSet, DoClose) {
@@ -153,5 +154,5 @@ TEST(FileDescriptorSet, DoClose) {
const int duped = dup(fd);
ASSERT_EQ(duped, -1);
- close(fd);
+ HANDLE_EINTR(close(fd));
}
diff --git a/chrome/common/ipc_channel_posix.cc b/chrome/common/ipc_channel_posix.cc
index 83f1ed4..522a6bc 100644
--- a/chrome/common/ipc_channel_posix.cc
+++ b/chrome/common/ipc_channel_posix.cc
@@ -16,6 +16,7 @@
#include <map>
#include "base/command_line.h"
+#include "base/eintr_wrapper.h"
#include "base/lock.h"
#include "base/logging.h"
#include "base/process_util.h"
@@ -139,7 +140,7 @@ bool CreateServerFifo(const std::string &pipe_name, int* server_listen_fd) {
// Make socket non-blocking
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
- close(fd);
+ HANDLE_EINTR(close(fd));
return false;
}
@@ -157,14 +158,14 @@ bool CreateServerFifo(const std::string &pipe_name, int* server_listen_fd) {
// Bind the socket.
if (bind(fd, reinterpret_cast<const sockaddr*>(&unix_addr),
unix_addr_len) != 0) {
- close(fd);
+ HANDLE_EINTR(close(fd));
return false;
}
// Start listening on the socket.
const int listen_queue_length = 1;
if (listen(fd, listen_queue_length) != 0) {
- close(fd);
+ HANDLE_EINTR(close(fd));
return false;
}
@@ -176,11 +177,11 @@ bool CreateServerFifo(const std::string &pipe_name, int* server_listen_fd) {
bool ServerAcceptFifoConnection(int server_listen_fd, int* server_socket) {
DCHECK(server_socket);
- int accept_fd = accept(server_listen_fd, NULL, 0);
+ int accept_fd = HANDLE_EINTR(accept(server_listen_fd, NULL, 0));
if (accept_fd < 0)
return false;
if (fcntl(accept_fd, F_SETFL, O_NONBLOCK) == -1) {
- close(accept_fd);
+ HANDLE_EINTR(close(accept_fd));
return false;
}
@@ -202,7 +203,7 @@ bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) {
// Make socket non-blocking
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
LOG(ERROR) << "fcntl failed";
- close(fd);
+ HANDLE_EINTR(close(fd));
return false;
}
@@ -215,13 +216,9 @@ bool ClientConnectToFifo(const std::string &pipe_name, int* client_socket) {
size_t server_unix_addr_len = offsetof(struct sockaddr_un, sun_path) +
strlen(server_unix_addr.sun_path) + 1;
- int ret_val = -1;
- do {
- ret_val = connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr),
- server_unix_addr_len);
- } while (ret_val == -1 && errno == EINTR);
- if (ret_val != 0) {
- close(fd);
+ if (HANDLE_EINTR(connect(fd, reinterpret_cast<sockaddr*>(&server_unix_addr),
+ server_unix_addr_len)) != 0) {
+ HANDLE_EINTR(close(fd));
return false;
}
@@ -290,8 +287,8 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
// Set both ends to be non-blocking.
if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
- close(pipe_fds[0]);
- close(pipe_fds[1]);
+ HANDLE_EINTR(close(pipe_fds[0]));
+ HANDLE_EINTR(close(pipe_fds[1]));
return false;
}
pipe_ = pipe_fds[0];
@@ -367,9 +364,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
// Read from pipe.
// recvmsg() returns 0 if the connection has closed or EAGAIN if no data
// is waiting on the pipe.
- do {
- bytes_read = recvmsg(pipe_, &msg, MSG_DONTWAIT);
- } while (bytes_read == -1 && errno == EINTR);
+ bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT));
if (bytes_read < 0) {
if (errno == EAGAIN) {
@@ -388,7 +383,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
if (client_pipe_ != -1) {
Singleton<PipeMap>()->Remove(pipe_name_);
- close(client_pipe_);
+ HANDLE_EINTR(close(client_pipe_));
client_pipe_ = -1;
}
@@ -427,7 +422,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
<< " cmsg_len:" << cmsg->cmsg_len
<< " fd:" << pipe_;
for (unsigned i = 0; i < num_wire_fds; ++i)
- close(wire_fds[i]);
+ HANDLE_EINTR(close(wire_fds[i]));
return false;
}
break;
@@ -500,7 +495,7 @@ bool Channel::ChannelImpl::ProcessIncomingMessages() {
<< " fds_i:" << fds_i;
// close the existing file descriptors so that we don't leak them
for (unsigned i = fds_i; i < num_fds; ++i)
- close(fds[i]);
+ HANDLE_EINTR(close(fds[i]));
input_overflow_fds_.clear();
// abort the connection
return false;
@@ -564,40 +559,38 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
DCHECK(amt_to_write != 0);
const char *out_bytes = reinterpret_cast<const char*>(msg->data()) +
message_send_bytes_written_;
- ssize_t bytes_written = -1;
- do {
- struct msghdr msgh = {0};
- struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write};
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- char buf[CMSG_SPACE(
- sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))];
-
- if (message_send_bytes_written_ == 0 &&
- !msg->file_descriptor_set()->empty()) {
- // This is the first chunk of a message which has descriptors to send
- struct cmsghdr *cmsg;
- const unsigned num_fds = msg->file_descriptor_set()->size();
-
- DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE);
-
- msgh.msg_control = buf;
- msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);
- cmsg = CMSG_FIRSTHDR(&msgh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
- msg->file_descriptor_set()->GetDescriptors(
- reinterpret_cast<int*>(CMSG_DATA(cmsg)));
- msgh.msg_controllen = cmsg->cmsg_len;
-
- msg->header()->num_fds = num_fds;
- }
- bytes_written = sendmsg(pipe_, &msgh, MSG_DONTWAIT);
- if (bytes_written > 0)
- msg->file_descriptor_set()->CommitAll();
- } while (bytes_written == -1 && errno == EINTR);
+ struct msghdr msgh = {0};
+ struct iovec iov = {const_cast<char*>(out_bytes), amt_to_write};
+ msgh.msg_iov = &iov;
+ msgh.msg_iovlen = 1;
+ char buf[CMSG_SPACE(
+ sizeof(int[FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE]))];
+
+ if (message_send_bytes_written_ == 0 &&
+ !msg->file_descriptor_set()->empty()) {
+ // This is the first chunk of a message which has descriptors to send
+ struct cmsghdr *cmsg;
+ const unsigned num_fds = msg->file_descriptor_set()->size();
+
+ DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE);
+
+ msgh.msg_control = buf;
+ msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);
+ cmsg = CMSG_FIRSTHDR(&msgh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
+ msg->file_descriptor_set()->GetDescriptors(
+ reinterpret_cast<int*>(CMSG_DATA(cmsg)));
+ msgh.msg_controllen = cmsg->cmsg_len;
+
+ msg->header()->num_fds = num_fds;
+ }
+
+ ssize_t bytes_written = HANDLE_EINTR(sendmsg(pipe_, &msgh, MSG_DONTWAIT));
+ if (bytes_written > 0)
+ msg->file_descriptor_set()->CommitAll();
if (bytes_written < 0 && errno != EAGAIN) {
LOG(ERROR) << "pipe error: " << strerror(errno);
@@ -731,7 +724,7 @@ void Channel::ChannelImpl::Close() {
server_listen_connection_watcher_.StopWatchingFileDescriptor();
if (server_listen_pipe_ != -1) {
- close(server_listen_pipe_);
+ HANDLE_EINTR(close(server_listen_pipe_));
server_listen_pipe_ = -1;
}
@@ -739,12 +732,12 @@ void Channel::ChannelImpl::Close() {
read_watcher_.StopWatchingFileDescriptor();
write_watcher_.StopWatchingFileDescriptor();
if (pipe_ != -1) {
- close(pipe_);
+ HANDLE_EINTR(close(pipe_));
pipe_ = -1;
}
if (client_pipe_ != -1) {
Singleton<PipeMap>()->Remove(pipe_name_);
- close(client_pipe_);
+ HANDLE_EINTR(close(client_pipe_));
client_pipe_ = -1;
}
@@ -760,7 +753,7 @@ void Channel::ChannelImpl::Close() {
// Close any outstanding, received file descriptors
for (std::vector<int>::iterator
i = input_overflow_fds_.begin(); i != input_overflow_fds_.end(); ++i) {
- close(*i);
+ HANDLE_EINTR(close(*i));
}
input_overflow_fds_.clear();
}
diff --git a/chrome/common/ipc_send_fds_test.cc b/chrome/common/ipc_send_fds_test.cc
index 747892d..24cc870e 100644
--- a/chrome/common/ipc_send_fds_test.cc
+++ b/chrome/common/ipc_send_fds_test.cc
@@ -14,6 +14,7 @@ extern "C" {
#include <fcntl.h>
#include <sys/stat.h>
+#include "base/eintr_wrapper.h"
#include "base/message_loop.h"
#include "chrome/common/ipc_channel.h"
#include "chrome/common/ipc_message_utils.h"
@@ -122,7 +123,7 @@ MULTIPROCESS_TEST_MAIN(RunTestDescriptorClientSandboxed) {
struct stat st;
const int fd = open(kDevZeroPath, O_RDONLY);
fstat(fd, &st);
- close(fd);
+ HANDLE_EINTR(close(fd));
// Enable the Sandbox.
char* error_buff = NULL;
@@ -165,7 +166,7 @@ MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) {
struct stat st;
const int fd = open(kDevZeroPath, O_RDONLY);
fstat(fd, &st);
- close(fd);
+ HANDLE_EINTR(close(fd));
return TestDescriptorClient(st.st_ino);
}
diff --git a/chrome/common/process_watcher_posix.cc b/chrome/common/process_watcher_posix.cc
index ef73521..f1ae4f4 100644
--- a/chrome/common/process_watcher_posix.cc
+++ b/chrome/common/process_watcher_posix.cc
@@ -9,12 +9,13 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include "base/eintr_wrapper.h"
#include "base/platform_thread.h"
// Return true if the given child is dead. This will also reap the process.
// Doesn't block.
static bool IsChildDead(pid_t child) {
- const int result = waitpid(child, NULL, WNOHANG);
+ const int result = HANDLE_EINTR(waitpid(child, NULL, WNOHANG));
if (result == -1) {
NOTREACHED();
} else if (result > 0) {
@@ -52,10 +53,7 @@ class BackgroundReaper : public PlatformThread::Delegate {
if (kill(child_, SIGKILL) == 0) {
// SIGKILL is uncatchable. Since the signal was delivered, we can
// just wait for the process to die now in a blocking manner.
- int result;
- do {
- result = waitpid(child_, NULL, 0);
- } while (result == -1 && errno == EINTR);
+ HANDLE_EINTR(waitpid(child_, NULL, 0));
} else {
LOG(ERROR) << "While waiting for " << child_ << " to terminate we"
<< " failed to deliver a SIGKILL signal (" << errno << ").";
diff --git a/chrome/common/transport_dib_mac.cc b/chrome/common/transport_dib_mac.cc
index 4ac44fc..b4c7a2a7 100644
--- a/chrome/common/transport_dib_mac.cc
+++ b/chrome/common/transport_dib_mac.cc
@@ -6,6 +6,8 @@
#include <unistd.h>
#include <sys/stat.h>
+
+#include "base/eintr_wrapper.h"
#include "base/shared_memory.h"
TransportDIB::TransportDIB()
@@ -41,7 +43,7 @@ TransportDIB* TransportDIB::Map(TransportDIB::Handle handle) {
if (!dib->shared_memory_.Map(st.st_size)) {
delete dib;
- close(handle.fd);
+ HANDLE_EINTR(close(handle.fd));
return false;
}
diff --git a/net/base/file_stream_posix.cc b/net/base/file_stream_posix.cc
index d1b70eb..8fca162 100644
--- a/net/base/file_stream_posix.cc
+++ b/net/base/file_stream_posix.cc
@@ -14,6 +14,7 @@
#include <errno.h>
#include "base/basictypes.h"
+#include "base/eintr_wrapper.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
@@ -51,30 +52,20 @@ int ReadFile(base::PlatformFile file, char* buf, int buf_len) {
// read(..., 0) returns 0 to indicate end-of-file.
// Loop in the case of getting interrupted by a signal.
- for (;;) {
- ssize_t res = read(file, buf, static_cast<size_t>(buf_len));
- if (res == static_cast<ssize_t>(-1)) {
- if (errno == EINTR)
- continue;
- return MapErrorCode(errno);
- }
- return static_cast<int>(res);
- }
+ ssize_t res = HANDLE_EINTR(read(file, buf, static_cast<size_t>(buf_len)));
+ if (res == static_cast<ssize_t>(-1))
+ return MapErrorCode(errno);
+ return static_cast<int>(res);
}
// WriteFile() is a simple wrapper around write() that handles EINTR signals and
// calls MapErrorCode() to map errno to net error codes. It tries to write to
// completion.
int WriteFile(base::PlatformFile file, const char* buf, int buf_len) {
- while (true) {
- ssize_t res = write(file, buf, buf_len);
- if (res == -1) {
- if (errno == EINTR)
- continue;
- return MapErrorCode(errno);
- }
- return res;
- }
+ ssize_t res = HANDLE_EINTR(write(file, buf, buf_len));
+ if (res == -1)
+ return MapErrorCode(errno);
+ return res;
}
// BackgroundReadTask is a simple task that reads a file and then runs
diff --git a/net/base/listen_socket.cc b/net/base/listen_socket.cc
index a172e46..a9d16ef 100644
--- a/net/base/listen_socket.cc
+++ b/net/base/listen_socket.cc
@@ -16,6 +16,7 @@
#include "third_party/libevent/event.h"
#endif
+#include "base/eintr_wrapper.h"
#include "net/base/net_util.h"
#include "net/base/listen_socket.h"
@@ -93,7 +94,8 @@ void ListenSocket::Listen() {
SOCKET ListenSocket::Accept(SOCKET s) {
sockaddr_in from;
socklen_t from_len = sizeof(from);
- SOCKET conn = accept(s, reinterpret_cast<sockaddr*>(&from), &from_len);
+ SOCKET conn =
+ HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len));
if (conn != INVALID_SOCKET) {
net::SetNonBlocking(conn);
}
@@ -119,7 +121,7 @@ void ListenSocket::Read() {
char buf[kReadBufSize + 1]; // +1 for null termination
int len;
do {
- len = recv(socket_, buf, kReadBufSize, 0);
+ len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
if (len == SOCKET_ERROR) {
#if defined(OS_WIN)
int err = WSAGetLastError();
@@ -188,7 +190,7 @@ void ListenSocket::WatchSocket(WaitState state) {
}
void ListenSocket::SendInternal(const char* bytes, int len) {
- int sent = send(socket_, bytes, len, 0);
+ int sent = HANDLE_EINTR(send(socket_, bytes, len, 0));
if (sent == SOCKET_ERROR) {
#if defined(OS_WIN)
int err = WSAGetLastError();
diff --git a/net/base/listen_socket_unittest.cc b/net/base/listen_socket_unittest.cc
index b08edc2..584d086 100644
--- a/net/base/listen_socket_unittest.cc
+++ b/net/base/listen_socket_unittest.cc
@@ -6,6 +6,7 @@
#include <fcntl.h>
+#include "base/eintr_wrapper.h"
#include "net/base/net_util.h"
#include "testing/platform_test.h"
@@ -57,8 +58,9 @@ void ListenSocketTester::SetUp() {
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr(kLoopback);
client.sin_port = htons(kTestPort);
- int ret = connect(test_socket_,
- reinterpret_cast<sockaddr*>(&client), sizeof(client));
+ int ret =
+ HANDLE_EINTR(connect(test_socket_, reinterpret_cast<sockaddr*>(&client),
+ sizeof(client)));
ASSERT_NE(ret, SOCKET_ERROR);
net::SetNonBlocking(test_socket_);
@@ -154,7 +156,7 @@ int ListenSocketTester::ClearTestSocket() {
int len_ret = 0;
int time_out = 0;
do {
- int len = recv(test_socket_, buf, kReadBufSize, 0);
+ int len = HANDLE_EINTR(recv(test_socket_, buf, kReadBufSize, 0));
#if defined(OS_WIN)
if (len == SOCKET_ERROR) {
int err = WSAGetLastError();
@@ -219,7 +221,7 @@ void ListenSocketTester::DidClose(ListenSocket *sock) {
bool ListenSocketTester::Send(SOCKET sock, const std::string& str) {
int len = static_cast<int>(str.length());
- int send_len = send(sock, str.data(), len, 0);
+ int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0));
if (send_len == SOCKET_ERROR) {
LOG(ERROR) << "send failed: " << errno;
return false;
@@ -273,7 +275,7 @@ void ListenSocketTester::TestServerSend() {
char buf[buf_len+1];
int recv_len;
do {
- recv_len = recv(test_socket_, buf, buf_len, 0);
+ recv_len = HANDLE_EINTR(recv(test_socket_, buf, buf_len, 0));
#if defined(OS_POSIX)
} while (recv_len == SOCKET_ERROR && errno == EINTR);
#else
diff --git a/net/base/tcp_client_socket_libevent.cc b/net/base/tcp_client_socket_libevent.cc
index f6672c4..3e23f1c 100644
--- a/net/base/tcp_client_socket_libevent.cc
+++ b/net/base/tcp_client_socket_libevent.cc
@@ -9,6 +9,7 @@
#include <netdb.h>
#include <sys/socket.h>
+#include "base/eintr_wrapper.h"
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/trace_event.h"
@@ -93,7 +94,8 @@ int TCPClientSocketLibevent::Connect(CompletionCallback* callback) {
if (rv != OK)
return rv;
- if (!connect(socket_, ai->ai_addr, static_cast<int>(ai->ai_addrlen))) {
+ if (!HANDLE_EINTR(connect(socket_, ai->ai_addr,
+ static_cast<int>(ai->ai_addrlen)))) {
TRACE_EVENT_END("socket.connect", this, "");
// Connected without waiting!
return OK;
@@ -147,7 +149,7 @@ bool TCPClientSocketLibevent::IsConnected() const {
// Check if connection is alive.
char c;
- int rv = recv(socket_, &c, 1, MSG_PEEK);
+ int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK));
if (rv == 0)
return false;
if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
@@ -163,7 +165,7 @@ bool TCPClientSocketLibevent::IsConnectedAndIdle() const {
// Check if connection is alive and we haven't received any data
// unexpectedly.
char c;
- int rv = recv(socket_, &c, 1, MSG_PEEK);
+ int rv = HANDLE_EINTR(recv(socket_, &c, 1, MSG_PEEK));
if (rv >= 0)
return false;
if (errno != EAGAIN && errno != EWOULDBLOCK)
@@ -183,7 +185,7 @@ int TCPClientSocketLibevent::Read(IOBuffer* buf,
DCHECK_GT(buf_len, 0);
TRACE_EVENT_BEGIN("socket.read", this, "");
- int nread = read(socket_, buf->data(), buf_len);
+ int nread = HANDLE_EINTR(read(socket_, buf->data(), buf_len));
if (nread >= 0) {
TRACE_EVENT_END("socket.read", this, StringPrintf("%d bytes", nread));
return nread;
@@ -217,7 +219,7 @@ int TCPClientSocketLibevent::Write(IOBuffer* buf,
DCHECK_GT(buf_len, 0);
TRACE_EVENT_BEGIN("socket.write", this, "");
- int nwrite = write(socket_, buf->data(), buf_len);
+ int nwrite = HANDLE_EINTR(write(socket_, buf->data(), buf_len));
if (nwrite >= 0) {
TRACE_EVENT_END("socket.write", this, StringPrintf("%d bytes", nwrite));
return nwrite;
@@ -309,7 +311,8 @@ void TCPClientSocketLibevent::DidCompleteConnect() {
void TCPClientSocketLibevent::DidCompleteRead() {
int bytes_transferred;
- bytes_transferred = read(socket_, read_buf_->data(), read_buf_len_);
+ bytes_transferred = HANDLE_EINTR(read(socket_, read_buf_->data(),
+ read_buf_len_));
int result;
if (bytes_transferred >= 0) {
@@ -330,7 +333,8 @@ void TCPClientSocketLibevent::DidCompleteRead() {
void TCPClientSocketLibevent::DidCompleteWrite() {
int bytes_transferred;
- bytes_transferred = write(socket_, write_buf_->data(), write_buf_len_);
+ bytes_transferred = HANDLE_EINTR(write(socket_, write_buf_->data(),
+ write_buf_len_));
int result;
if (bytes_transferred >= 0) {
diff --git a/net/base/telnet_server.cc b/net/base/telnet_server.cc
index 8cd2451..51ebf35 100644
--- a/net/base/telnet_server.cc
+++ b/net/base/telnet_server.cc
@@ -17,6 +17,7 @@
#include "base/message_pump_libevent.h"
#endif
+#include "base/eintr_wrapper.h"
#include "net/base/telnet_server.h"
#if defined(OS_POSIX)
@@ -250,7 +251,7 @@ void TelnetServer::Read() {
char buf[kReadBufSize + 1];
int len;
do {
- len = recv(socket_, buf, kReadBufSize, 0);
+ len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0));
#if defined(OS_WIN)
if (len == SOCKET_ERROR) {