mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 14:43:32 +00:00
Handle EINTR on all IO operations
There have been spurious FileIOExceptions seen on some Mac OS machines. R=ager@google.com,whesse@google.com BUG= TEST= Review URL: http://codereview.chromium.org//9139011 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@3185 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
dea93d6568
commit
0122a33a76
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -39,7 +39,10 @@ static bool ListRecursively(const char* dir_name,
|
|||
static void ComputeFullPath(const char* dir_name,
|
||||
char* path,
|
||||
int* path_length) {
|
||||
char* abs_path = realpath(dir_name, path);
|
||||
char* abs_path;
|
||||
do {
|
||||
abs_path = realpath(dir_name, path);
|
||||
} while (abs_path == NULL && errno == EINTR);
|
||||
ASSERT(abs_path != NULL);
|
||||
*path_length = strlen(path);
|
||||
size_t written = snprintf(path + *path_length,
|
||||
|
@ -128,7 +131,10 @@ static bool ListRecursively(const char* dir_name,
|
|||
Dart_Port file_port,
|
||||
Dart_Port done_port,
|
||||
Dart_Port error_port) {
|
||||
DIR* dir_pointer = opendir(dir_name);
|
||||
DIR* dir_pointer;
|
||||
do {
|
||||
dir_pointer = opendir(dir_name);
|
||||
} while (dir_pointer == NULL && errno == EINTR);
|
||||
if (dir_pointer == NULL) {
|
||||
PostError(error_port, "Directory listing failed for: ", dir_name, errno);
|
||||
return false;
|
||||
|
@ -146,7 +152,9 @@ static bool ListRecursively(const char* dir_name,
|
|||
bool listing_error = false;
|
||||
dirent entry;
|
||||
dirent* result;
|
||||
while ((success = readdir_r(dir_pointer, &entry, &result)) == 0 &&
|
||||
while ((success = TEMP_FAILURE_RETRY(readdir_r(dir_pointer,
|
||||
&entry,
|
||||
&result))) == 0 &&
|
||||
result != NULL &&
|
||||
!listing_error) {
|
||||
switch (entry.d_type) {
|
||||
|
@ -173,7 +181,7 @@ static bool ListRecursively(const char* dir_name,
|
|||
"%s",
|
||||
entry.d_name);
|
||||
ASSERT(written == strlen(entry.d_name));
|
||||
int lstat_success = lstat(path, &entry_info);
|
||||
int lstat_success = TEMP_FAILURE_RETRY(lstat(path, &entry_info));
|
||||
if (lstat_success == -1) {
|
||||
listing_error = true;
|
||||
PostError(error_port, "Directory listing failed for: ", path, errno);
|
||||
|
@ -233,7 +241,7 @@ void Directory::List(const char* dir_name,
|
|||
|
||||
Directory::ExistsResult Directory::Exists(const char* dir_name) {
|
||||
struct stat entry_info;
|
||||
int lstat_success = lstat(dir_name, &entry_info);
|
||||
int lstat_success = TEMP_FAILURE_RETRY(lstat(dir_name, &entry_info));
|
||||
if (lstat_success == 0) {
|
||||
if ((entry_info.st_mode & S_IFMT) == S_IFDIR) {
|
||||
return EXISTS;
|
||||
|
@ -263,7 +271,7 @@ Directory::ExistsResult Directory::Exists(const char* dir_name) {
|
|||
bool Directory::Create(const char* dir_name) {
|
||||
// Create the directory with the permissions specified by the
|
||||
// process umask.
|
||||
return (mkdir(dir_name, 0777) == 0);
|
||||
return (TEMP_FAILURE_RETRY(mkdir(dir_name, 0777)) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -287,7 +295,10 @@ int Directory::CreateTemp(const char* const_template,
|
|||
} else {
|
||||
snprintf(*path, PATH_MAX, "/tmp/temp_dir1_XXXXXX");
|
||||
}
|
||||
char* result = mkdtemp(*path);
|
||||
char* result;
|
||||
do {
|
||||
result = mkdtemp(*path);
|
||||
} while (result == NULL && errno == EINTR);
|
||||
if (result == NULL) {
|
||||
SetOsErrorMessage(os_error_message, os_error_message_len);
|
||||
free(*path);
|
||||
|
@ -299,5 +310,5 @@ int Directory::CreateTemp(const char* const_template,
|
|||
|
||||
|
||||
bool Directory::Delete(const char* dir_name) {
|
||||
return (rmdir(dir_name) == 0);
|
||||
return (TEMP_FAILURE_RETRY(rmdir(dir_name)) == 0);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ EventHandlerImplementation::EventHandlerImplementation() {
|
|||
socket_map_ = reinterpret_cast<SocketData*>(calloc(socket_map_size_,
|
||||
sizeof(SocketData)));
|
||||
ASSERT(socket_map_ != NULL);
|
||||
result = pipe(interrupt_fds_);
|
||||
result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_));
|
||||
if (result != 0) {
|
||||
FATAL("Pipe creation failed");
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ EventHandlerImplementation::EventHandlerImplementation() {
|
|||
|
||||
EventHandlerImplementation::~EventHandlerImplementation() {
|
||||
free(socket_map_);
|
||||
close(interrupt_fds_[0]);
|
||||
close(interrupt_fds_[1]);
|
||||
TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
|
||||
TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
|
|||
} while (fd >= new_socket_map_size);
|
||||
size_t new_socket_map_bytes = new_socket_map_size * sizeof(SocketData);
|
||||
socket_map_ = reinterpret_cast<SocketData*>(realloc(socket_map_,
|
||||
new_socket_map_bytes));
|
||||
new_socket_map_bytes));
|
||||
ASSERT(socket_map_ != NULL);
|
||||
size_t socket_map_bytes = socket_map_size_ * sizeof(SocketData);
|
||||
memset(socket_map_ + socket_map_size_,
|
||||
|
@ -147,15 +147,16 @@ struct pollfd* EventHandlerImplementation::GetPollFds(intptr_t* pollfds_size) {
|
|||
|
||||
bool EventHandlerImplementation::GetInterruptMessage(InterruptMessage* msg) {
|
||||
int total_read = 0;
|
||||
int bytes_read = read(interrupt_fds_[0], msg, kInterruptMessageSize);
|
||||
int bytes_read =
|
||||
TEMP_FAILURE_RETRY(read(interrupt_fds_[0], msg, kInterruptMessageSize));
|
||||
if (bytes_read < 0) {
|
||||
return false;
|
||||
}
|
||||
total_read = bytes_read;
|
||||
while (total_read < kInterruptMessageSize) {
|
||||
bytes_read = read(interrupt_fds_[0],
|
||||
msg + total_read,
|
||||
kInterruptMessageSize - total_read);
|
||||
bytes_read = TEMP_FAILURE_RETRY(read(interrupt_fds_[0],
|
||||
msg + total_read,
|
||||
kInterruptMessageSize - total_read));
|
||||
if (bytes_read > 0) {
|
||||
total_read = total_read + bytes_read;
|
||||
}
|
||||
|
@ -255,11 +256,13 @@ intptr_t EventHandlerImplementation::GetPollEvents(struct pollfd* pollfd) {
|
|||
// recv to peek for whether the other end of the socket
|
||||
// actually closed.
|
||||
char buffer;
|
||||
ssize_t bytesPeeked = recv(sd->fd(), &buffer, 1, MSG_PEEK);
|
||||
ssize_t bytesPeeked =
|
||||
TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (bytesPeeked == 0) {
|
||||
event_mask = (1 << kCloseEvent);
|
||||
sd->MarkClosedRead();
|
||||
} else if (errno != EAGAIN) {
|
||||
} else if (errno != EWOULDBLOCK) {
|
||||
fprintf(stderr, "Error recv: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
@ -346,9 +349,10 @@ void* EventHandlerImplementation::Poll(void* args) {
|
|||
while (1) {
|
||||
pollfds = handler->GetPollFds(&pollfds_size);
|
||||
intptr_t millis = handler->GetTimeout();
|
||||
intptr_t result = poll(pollfds, pollfds_size, millis);
|
||||
intptr_t result = TEMP_FAILURE_RETRY(poll(pollfds, pollfds_size, millis));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (result == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
perror("Poll failed");
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -55,7 +55,7 @@ EventHandlerImplementation::EventHandlerImplementation() {
|
|||
socket_map_ = reinterpret_cast<SocketData*>(calloc(socket_map_size_,
|
||||
sizeof(SocketData)));
|
||||
ASSERT(socket_map_ != NULL);
|
||||
result = pipe(interrupt_fds_);
|
||||
result = TEMP_FAILURE_RETRY(pipe(interrupt_fds_));
|
||||
if (result != 0) {
|
||||
FATAL("Pipe creation failed");
|
||||
}
|
||||
|
@ -67,8 +67,8 @@ EventHandlerImplementation::EventHandlerImplementation() {
|
|||
|
||||
EventHandlerImplementation::~EventHandlerImplementation() {
|
||||
free(socket_map_);
|
||||
close(interrupt_fds_[0]);
|
||||
close(interrupt_fds_[1]);
|
||||
TEMP_FAILURE_RETRY(close(interrupt_fds_[0]));
|
||||
TEMP_FAILURE_RETRY(close(interrupt_fds_[1]));
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ SocketData* EventHandlerImplementation::GetSocketData(intptr_t fd) {
|
|||
} while (fd >= new_socket_map_size);
|
||||
size_t new_socket_map_bytes = new_socket_map_size * sizeof(SocketData);
|
||||
socket_map_ = reinterpret_cast<SocketData*>(realloc(socket_map_,
|
||||
new_socket_map_bytes));
|
||||
new_socket_map_bytes));
|
||||
ASSERT(socket_map_ != NULL);
|
||||
size_t socket_map_bytes = socket_map_size_ * sizeof(SocketData);
|
||||
memset(socket_map_ + socket_map_size_,
|
||||
|
@ -147,15 +147,16 @@ struct pollfd* EventHandlerImplementation::GetPollFds(intptr_t* pollfds_size) {
|
|||
|
||||
bool EventHandlerImplementation::GetInterruptMessage(InterruptMessage* msg) {
|
||||
int total_read = 0;
|
||||
int bytes_read = read(interrupt_fds_[0], msg, kInterruptMessageSize);
|
||||
int bytes_read =
|
||||
TEMP_FAILURE_RETRY(read(interrupt_fds_[0], msg, kInterruptMessageSize));
|
||||
if (bytes_read < 0) {
|
||||
return false;
|
||||
}
|
||||
total_read = bytes_read;
|
||||
while (total_read < kInterruptMessageSize) {
|
||||
bytes_read = read(interrupt_fds_[0],
|
||||
msg + total_read,
|
||||
kInterruptMessageSize - total_read);
|
||||
bytes_read = TEMP_FAILURE_RETRY(read(interrupt_fds_[0],
|
||||
msg + total_read,
|
||||
kInterruptMessageSize - total_read));
|
||||
if (bytes_read > 0) {
|
||||
total_read = total_read + bytes_read;
|
||||
}
|
||||
|
@ -253,11 +254,13 @@ intptr_t EventHandlerImplementation::GetPollEvents(struct pollfd* pollfd) {
|
|||
// recv to peek for whether the other end of the socket
|
||||
// actually closed.
|
||||
char buffer;
|
||||
ssize_t bytesPeeked = recv(sd->fd(), &buffer, 1, MSG_PEEK);
|
||||
ssize_t bytesPeeked =
|
||||
TEMP_FAILURE_RETRY(recv(sd->fd(), &buffer, 1, MSG_PEEK));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (bytesPeeked == 0) {
|
||||
event_mask = (1 << kCloseEvent);
|
||||
sd->MarkClosedRead();
|
||||
} else if (errno != EAGAIN) {
|
||||
} else if (errno != EWOULDBLOCK) {
|
||||
fprintf(stderr, "Error recv: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
@ -344,9 +347,10 @@ void* EventHandlerImplementation::Poll(void* args) {
|
|||
while (1) {
|
||||
pollfds = handler->GetPollFds(&pollfds_size);
|
||||
intptr_t millis = handler->GetTimeout();
|
||||
intptr_t result = poll(pollfds, pollfds_size, millis);
|
||||
intptr_t result = TEMP_FAILURE_RETRY(poll(pollfds, pollfds_size, millis));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (result == -1) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
if (errno != EWOULDBLOCK) {
|
||||
perror("Poll failed");
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
|
||||
bool FDUtils::SetNonBlocking(intptr_t fd) {
|
||||
intptr_t status;
|
||||
status = fcntl(fd, F_GETFL);
|
||||
status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
|
||||
if (status < 0) {
|
||||
perror("fcntl F_GETFL failed");
|
||||
return false;
|
||||
}
|
||||
status = (status | O_NONBLOCK);
|
||||
if (fcntl(fd, F_SETFL, status) < 0) {
|
||||
if (TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, status)) < 0) {
|
||||
perror("fcntl F_SETFL failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ bool FDUtils::SetNonBlocking(intptr_t fd) {
|
|||
|
||||
bool FDUtils::IsBlocking(intptr_t fd, bool* is_blocking) {
|
||||
intptr_t status;
|
||||
status = fcntl(fd, F_GETFL);
|
||||
status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
|
||||
if (status < 0) {
|
||||
perror("fcntl F_GETFL failed");
|
||||
return false;
|
||||
|
@ -40,7 +40,7 @@ bool FDUtils::IsBlocking(intptr_t fd, bool* is_blocking) {
|
|||
|
||||
intptr_t FDUtils::AvailableBytes(intptr_t fd) {
|
||||
size_t available;
|
||||
int result = ioctl(fd, FIONREAD, &available);
|
||||
int result = TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, &available));
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
@ -57,19 +57,19 @@ ssize_t FDUtils::ReadFromBlocking(int fd, void* buffer, size_t count) {
|
|||
size_t remaining = count;
|
||||
char* buffer_pos = reinterpret_cast<char*>(buffer);
|
||||
while (remaining > 0) {
|
||||
ssize_t bytes_read = read(fd, buffer_pos, remaining);
|
||||
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer_pos, remaining));
|
||||
if (bytes_read == 0) {
|
||||
return count - remaining;
|
||||
} else if (bytes_read == -1 && errno != EINTR) {
|
||||
// Error codes EAGAIN and EWOULDBLOCK should only happen for non
|
||||
// blocking file descriptors.
|
||||
ASSERT(errno != EAGAIN && errno != EWOULDBLOCK);
|
||||
} else if (bytes_read == -1) {
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
// Error code EWOULDBLOCK should only happen for non blocking
|
||||
// file descriptors.
|
||||
ASSERT(errno != EWOULDBLOCK);
|
||||
return -1;
|
||||
} else if (bytes_read > 0) {
|
||||
} else {
|
||||
ASSERT((bytes_read > 0));
|
||||
remaining -= bytes_read;
|
||||
buffer_pos += bytes_read;
|
||||
} else {
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
|
@ -85,19 +85,20 @@ ssize_t FDUtils::WriteToBlocking(int fd, const void* buffer, size_t count) {
|
|||
size_t remaining = count;
|
||||
char* buffer_pos = const_cast<char*>(reinterpret_cast<const char*>(buffer));
|
||||
while (remaining > 0) {
|
||||
ssize_t bytes_written = write(fd, buffer_pos, remaining);
|
||||
ssize_t bytes_written =
|
||||
TEMP_FAILURE_RETRY(write(fd, buffer_pos, remaining));
|
||||
if (bytes_written == 0) {
|
||||
return count - remaining;
|
||||
} else if (bytes_written == -1 && errno != EINTR) {
|
||||
// Error codes EAGAIN and EWOULDBLOCK should only happen for non
|
||||
// blocking file descriptors.
|
||||
ASSERT(errno != EAGAIN && errno != EWOULDBLOCK);
|
||||
} else if (bytes_written == -1) {
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
// Error code EWOULDBLOCK should only happen for non blocking
|
||||
// file descriptors.
|
||||
ASSERT(errno != EWOULDBLOCK);
|
||||
return -1;
|
||||
} else if (bytes_written > 0) {
|
||||
} else {
|
||||
ASSERT(bytes_written > 0);
|
||||
remaining -= bytes_written;
|
||||
buffer_pos += bytes_written;
|
||||
} else {
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
|||
|
||||
bool FDUtils::SetNonBlocking(intptr_t fd) {
|
||||
intptr_t status;
|
||||
status = fcntl(fd, F_GETFL);
|
||||
status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
|
||||
if (status < 0) {
|
||||
perror("fcntl F_GETFL failed");
|
||||
return false;
|
||||
}
|
||||
status = (status | O_NONBLOCK);
|
||||
if (fcntl(fd, F_SETFL, status) < 0) {
|
||||
if (TEMP_FAILURE_RETRY(fcntl(fd, F_SETFL, status)) < 0) {
|
||||
perror("fcntl F_SETFL failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ bool FDUtils::SetNonBlocking(intptr_t fd) {
|
|||
|
||||
bool FDUtils::IsBlocking(intptr_t fd, bool* is_blocking) {
|
||||
intptr_t status;
|
||||
status = fcntl(fd, F_GETFL);
|
||||
status = TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL));
|
||||
if (status < 0) {
|
||||
perror("fcntl F_GETFL failed");
|
||||
return false;
|
||||
|
@ -40,7 +40,7 @@ bool FDUtils::IsBlocking(intptr_t fd, bool* is_blocking) {
|
|||
|
||||
intptr_t FDUtils::AvailableBytes(intptr_t fd) {
|
||||
size_t available;
|
||||
int result = ioctl(fd, FIONREAD, &available);
|
||||
int result = TEMP_FAILURE_RETRY(ioctl(fd, FIONREAD, &available));
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
@ -57,19 +57,19 @@ ssize_t FDUtils::ReadFromBlocking(int fd, void* buffer, size_t count) {
|
|||
size_t remaining = count;
|
||||
char* buffer_pos = reinterpret_cast<char*>(buffer);
|
||||
while (remaining > 0) {
|
||||
ssize_t bytes_read = read(fd, buffer_pos, remaining);
|
||||
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer_pos, remaining));
|
||||
if (bytes_read == 0) {
|
||||
return count - remaining;
|
||||
} else if (bytes_read == -1 && errno != EINTR) {
|
||||
// Error codes EAGAIN and EWOULDBLOCK should only happen for non
|
||||
// blocking file descriptors.
|
||||
ASSERT(errno != EAGAIN && errno != EWOULDBLOCK);
|
||||
} else if (bytes_read == -1) {
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
// Error code EWOULDBLOCK should only happen for non blocking
|
||||
// file descriptors.
|
||||
ASSERT(errno != EWOULDBLOCK);
|
||||
return -1;
|
||||
} else if (bytes_read > 0) {
|
||||
} else {
|
||||
ASSERT((bytes_read > 0));
|
||||
remaining -= bytes_read;
|
||||
buffer_pos += bytes_read;
|
||||
} else {
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
|
@ -85,19 +85,20 @@ ssize_t FDUtils::WriteToBlocking(int fd, const void* buffer, size_t count) {
|
|||
size_t remaining = count;
|
||||
char* buffer_pos = const_cast<char*>(reinterpret_cast<const char*>(buffer));
|
||||
while (remaining > 0) {
|
||||
ssize_t bytes_written = write(fd, buffer_pos, remaining);
|
||||
ssize_t bytes_written =
|
||||
TEMP_FAILURE_RETRY(write(fd, buffer_pos, remaining));
|
||||
if (bytes_written == 0) {
|
||||
return count - remaining;
|
||||
} else if (bytes_written == -1 && errno != EINTR) {
|
||||
// Error codes EAGAIN and EWOULDBLOCK should only happen for non
|
||||
// blocking file descriptors.
|
||||
ASSERT(errno != EAGAIN && errno != EWOULDBLOCK);
|
||||
} else if (bytes_written == -1) {
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
// Error code EWOULDBLOCK should only happen for non blocking
|
||||
// file descriptors.
|
||||
ASSERT(errno != EWOULDBLOCK);
|
||||
return -1;
|
||||
} else if (bytes_written > 0) {
|
||||
} else {
|
||||
ASSERT(bytes_written > 0);
|
||||
remaining -= bytes_written;
|
||||
buffer_pos += bytes_written;
|
||||
} else {
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -38,7 +38,7 @@ File::~File() {
|
|||
|
||||
void File::Close() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
int err = close(handle_->fd());
|
||||
int err = TEMP_FAILURE_RETRY(close(handle_->fd()));
|
||||
if (err != 0) {
|
||||
const int kBufferSize = 1024;
|
||||
char error_message[kBufferSize];
|
||||
|
@ -56,49 +56,49 @@ bool File::IsClosed() {
|
|||
|
||||
int64_t File::Read(void* buffer, int64_t num_bytes) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return read(handle_->fd(), buffer, num_bytes);
|
||||
return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
|
||||
}
|
||||
|
||||
|
||||
int64_t File::Write(const void* buffer, int64_t num_bytes) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return write(handle_->fd(), buffer, num_bytes);
|
||||
return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
|
||||
}
|
||||
|
||||
|
||||
off_t File::Position() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return lseek(handle_->fd(), 0, SEEK_CUR);
|
||||
return TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_CUR));
|
||||
}
|
||||
|
||||
|
||||
bool File::SetPosition(int64_t position) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return (lseek(handle_->fd(), position, SEEK_SET) != -1);
|
||||
return TEMP_FAILURE_RETRY(lseek(handle_->fd(), position, SEEK_SET) != -1);
|
||||
}
|
||||
|
||||
|
||||
bool File::Truncate(int64_t length) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return (ftruncate(handle_->fd(), length) != -1);
|
||||
return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length) != -1);
|
||||
}
|
||||
|
||||
|
||||
void File::Flush() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
fsync(handle_->fd());
|
||||
TEMP_FAILURE_RETRY(fsync(handle_->fd()));
|
||||
}
|
||||
|
||||
|
||||
off_t File::Length() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
off_t position = lseek(handle_->fd(), 0, SEEK_CUR);
|
||||
off_t position = TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_CUR));
|
||||
if (position < 0) {
|
||||
// The file is not capable of seeking. Return an error.
|
||||
return -1;
|
||||
}
|
||||
off_t result = lseek(handle_->fd(), 0, SEEK_END);
|
||||
lseek(handle_->fd(), position, SEEK_SET);
|
||||
off_t result = TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_END));
|
||||
TEMP_FAILURE_RETRY(lseek(handle_->fd(), position, SEEK_SET));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ File* File::Open(const char* name, FileOpenMode mode) {
|
|||
if ((mode & kTruncate) != 0) {
|
||||
flags = flags | O_TRUNC;
|
||||
}
|
||||
int fd = open(name, flags, 0666);
|
||||
int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ File* File::Open(const char* name, FileOpenMode mode) {
|
|||
|
||||
bool File::Exists(const char* name) {
|
||||
struct stat st;
|
||||
if (stat(name, &st) == 0) {
|
||||
if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
|
||||
return S_ISREG(st.st_mode); // Deal with symlinks?
|
||||
} else {
|
||||
return false;
|
||||
|
@ -130,7 +130,7 @@ bool File::Exists(const char* name) {
|
|||
|
||||
|
||||
bool File::Create(const char* name) {
|
||||
int fd = open(name, O_RDONLY | O_CREAT, 0666);
|
||||
int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CREAT, 0666));
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ bool File::Create(const char* name) {
|
|||
|
||||
|
||||
bool File::Delete(const char* name) {
|
||||
int status = remove(name);
|
||||
int status = TEMP_FAILURE_RETRY(remove(name));
|
||||
if (status == -1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -155,7 +155,9 @@ bool File::IsAbsolutePath(const char* pathname) {
|
|||
char* File::GetCanonicalPath(const char* pathname) {
|
||||
char* abs_path = NULL;
|
||||
if (pathname != NULL) {
|
||||
abs_path = realpath(pathname, NULL);
|
||||
do {
|
||||
abs_path = realpath(pathname, NULL);
|
||||
} while (abs_path == NULL && errno == EINTR);
|
||||
assert(abs_path == NULL || IsAbsolutePath(abs_path));
|
||||
}
|
||||
return abs_path;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -39,7 +39,7 @@ File::~File() {
|
|||
|
||||
void File::Close() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
int err = close(handle_->fd());
|
||||
int err = TEMP_FAILURE_RETRY(close(handle_->fd()));
|
||||
if (err != 0) {
|
||||
const int kBufferSize = 1024;
|
||||
char error_message[kBufferSize];
|
||||
|
@ -57,49 +57,49 @@ bool File::IsClosed() {
|
|||
|
||||
int64_t File::Read(void* buffer, int64_t num_bytes) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return read(handle_->fd(), buffer, num_bytes);
|
||||
return TEMP_FAILURE_RETRY(read(handle_->fd(), buffer, num_bytes));
|
||||
}
|
||||
|
||||
|
||||
int64_t File::Write(const void* buffer, int64_t num_bytes) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return write(handle_->fd(), buffer, num_bytes);
|
||||
return TEMP_FAILURE_RETRY(write(handle_->fd(), buffer, num_bytes));
|
||||
}
|
||||
|
||||
|
||||
off_t File::Position() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return lseek(handle_->fd(), 0, SEEK_CUR);
|
||||
return TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_CUR));
|
||||
}
|
||||
|
||||
|
||||
bool File::SetPosition(int64_t position) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return (lseek(handle_->fd(), position, SEEK_SET) != -1);
|
||||
return TEMP_FAILURE_RETRY(lseek(handle_->fd(), position, SEEK_SET) != -1);
|
||||
}
|
||||
|
||||
|
||||
bool File::Truncate(int64_t length) {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
return (ftruncate(handle_->fd(), length) != -1);
|
||||
return TEMP_FAILURE_RETRY(ftruncate(handle_->fd(), length) != -1);
|
||||
}
|
||||
|
||||
|
||||
void File::Flush() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
fsync(handle_->fd());
|
||||
TEMP_FAILURE_RETRY(fsync(handle_->fd()));
|
||||
}
|
||||
|
||||
|
||||
off_t File::Length() {
|
||||
ASSERT(handle_->fd() >= 0);
|
||||
off_t position = lseek(handle_->fd(), 0, SEEK_CUR);
|
||||
off_t position = TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_CUR));
|
||||
if (position < 0) {
|
||||
// The file is not capable of seeking. Return an error.
|
||||
return -1;
|
||||
}
|
||||
off_t result = lseek(handle_->fd(), 0, SEEK_END);
|
||||
lseek(handle_->fd(), position, SEEK_SET);
|
||||
off_t result = TEMP_FAILURE_RETRY(lseek(handle_->fd(), 0, SEEK_END));
|
||||
TEMP_FAILURE_RETRY(lseek(handle_->fd(), position, SEEK_SET));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ File* File::Open(const char* name, FileOpenMode mode) {
|
|||
if ((mode & kTruncate) != 0) {
|
||||
flags = flags | O_TRUNC;
|
||||
}
|
||||
int fd = open(name, flags, 0666);
|
||||
int fd = TEMP_FAILURE_RETRY(open(name, flags, 0666));
|
||||
if (fd < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ File* File::Open(const char* name, FileOpenMode mode) {
|
|||
|
||||
bool File::Exists(const char* name) {
|
||||
struct stat st;
|
||||
if (stat(name, &st) == 0) {
|
||||
if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
|
||||
return S_ISREG(st.st_mode); // Deal with symlinks?
|
||||
} else {
|
||||
return false;
|
||||
|
@ -130,13 +130,8 @@ bool File::Exists(const char* name) {
|
|||
}
|
||||
|
||||
|
||||
bool File::IsAbsolutePath(const char* pathname) {
|
||||
return (pathname != NULL && pathname[0] == '/');
|
||||
}
|
||||
|
||||
|
||||
bool File::Create(const char* name) {
|
||||
int fd = open(name, O_RDONLY | O_CREAT, 0666);
|
||||
int fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CREAT, 0666));
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
@ -145,7 +140,7 @@ bool File::Create(const char* name) {
|
|||
|
||||
|
||||
bool File::Delete(const char* name) {
|
||||
int status = remove(name);
|
||||
int status = TEMP_FAILURE_RETRY(remove(name));
|
||||
if (status == -1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -153,6 +148,11 @@ bool File::Delete(const char* name) {
|
|||
}
|
||||
|
||||
|
||||
bool File::IsAbsolutePath(const char* pathname) {
|
||||
return (pathname != NULL && pathname[0] == '/');
|
||||
}
|
||||
|
||||
|
||||
char* File::GetCanonicalPath(const char* pathname) {
|
||||
char* abs_path = NULL;
|
||||
if (pathname != NULL) {
|
||||
|
@ -160,9 +160,11 @@ char* File::GetCanonicalPath(const char* pathname) {
|
|||
// space for the resolved_path when a NULL is passed in does not seem to
|
||||
// work, so we explicitly allocate space. The caller is responsible for
|
||||
// freeing this space as in a regular realpath call.
|
||||
char* resolved_path = reinterpret_cast<char*>(malloc(PATH_MAX+1));
|
||||
char* resolved_path = reinterpret_cast<char*>(malloc(PATH_MAX + 1));
|
||||
ASSERT(resolved_path != NULL);
|
||||
abs_path = realpath(pathname, resolved_path);
|
||||
do {
|
||||
abs_path = realpath(pathname, NULL);
|
||||
} while (abs_path == NULL && errno == EINTR);
|
||||
assert(abs_path == NULL || IsAbsolutePath(abs_path));
|
||||
}
|
||||
return abs_path;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -88,7 +88,7 @@ static void SetChildOsErrorMessage(char* os_error_message,
|
|||
void ExitHandler(int process_signal, siginfo_t* siginfo, void* tmp) {
|
||||
int pid = 0;
|
||||
int status = 0;
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
|
||||
int exit_code = 0;
|
||||
int negative = 0;
|
||||
if (WIFEXITED(status)) {
|
||||
|
@ -106,7 +106,7 @@ void ExitHandler(int process_signal, siginfo_t* siginfo, void* tmp) {
|
|||
if (result != sizeof(message) && errno != EPIPE) {
|
||||
perror("ExitHandler notification failed");
|
||||
}
|
||||
close(process->fd());
|
||||
TEMP_FAILURE_RETRY(close(process->fd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ static void ReportChildError(int exec_control_fd) {
|
|||
FDUtils::WriteToBlocking(
|
||||
exec_control_fd, os_error_message, strlen(os_error_message) + 1);
|
||||
}
|
||||
close(exec_control_fd);
|
||||
TEMP_FAILURE_RETRY(close(exec_control_fd));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -148,59 +148,61 @@ int Process::Start(const char* path,
|
|||
int exec_control[2]; // Pipe to get the result from exec.
|
||||
int result;
|
||||
|
||||
result = pipe(read_in);
|
||||
result = TEMP_FAILURE_RETRY(pipe(read_in));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(read_err);
|
||||
result = TEMP_FAILURE_RETRY(pipe(read_err));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(write_out);
|
||||
result = TEMP_FAILURE_RETRY(pipe(write_out));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(exec_control);
|
||||
result = TEMP_FAILURE_RETRY(pipe(exec_control));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
// Set close on exec on the write file descriptor of the exec control pipe.
|
||||
result = fcntl(
|
||||
exec_control[1], F_SETFD, fcntl(exec_control[1], F_GETFD) | FD_CLOEXEC);
|
||||
result = TEMP_FAILURE_RETRY(
|
||||
fcntl(exec_control[1],
|
||||
F_SETFD,
|
||||
TEMP_FAILURE_RETRY(fcntl(exec_control[1], F_GETFD)) | FD_CLOEXEC));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
close(exec_control[0]);
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
fprintf(stderr, "fcntl failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
@ -219,18 +221,18 @@ int Process::Start(const char* path,
|
|||
if (sigaction(SIGCHLD, &act, 0) != 0) {
|
||||
perror("Process start: setting signal handler failed");
|
||||
}
|
||||
pid = fork();
|
||||
pid = TEMP_FAILURE_RETRY(fork());
|
||||
if (pid < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
delete[] program_arguments;
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
close(exec_control[0]);
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
return errno;
|
||||
} else if (pid == 0) {
|
||||
// Wait for parent process before setting up the child process.
|
||||
|
@ -241,31 +243,33 @@ int Process::Start(const char* path,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
close(write_out[1]);
|
||||
close(read_in[0]);
|
||||
close(read_err[0]);
|
||||
close(exec_control[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
|
||||
if (dup2(write_out[0], STDIN_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(write_out[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
|
||||
if (dup2(read_in[1], STDOUT_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
|
||||
if (dup2(read_err[1], STDERR_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
|
||||
if (working_directory != NULL && chdir(working_directory) == -1) {
|
||||
if (working_directory != NULL &&
|
||||
TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
|
||||
execvp(path, const_cast<char* const*>(program_arguments));
|
||||
TEMP_FAILURE_RETRY(
|
||||
execvp(path, const_cast<char* const*>(program_arguments)));
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
|
||||
|
@ -273,15 +277,15 @@ int Process::Start(const char* path,
|
|||
delete[] program_arguments;
|
||||
|
||||
int event_fds[2];
|
||||
result = pipe(event_fds);
|
||||
result = TEMP_FAILURE_RETRY(pipe(event_fds));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
@ -301,7 +305,7 @@ int Process::Start(const char* path,
|
|||
// Read exec result from child. If no data is returned the exec was
|
||||
// successful and the exec call closed the pipe. Otherwise the errno
|
||||
// is written to the pipe.
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
int child_errno;
|
||||
int bytes_read = -1;
|
||||
ASSERT(sizeof(child_errno) == sizeof(errno));
|
||||
|
@ -314,16 +318,16 @@ int Process::Start(const char* path,
|
|||
os_error_message_len);
|
||||
os_error_message[os_error_message_len - 1] = '\0';
|
||||
}
|
||||
close(exec_control[0]);
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
|
||||
// Return error code if any failures.
|
||||
if (bytes_read != 0) {
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
if (bytes_read == -1) {
|
||||
return errno; // Read failed.
|
||||
} else {
|
||||
|
@ -333,13 +337,13 @@ int Process::Start(const char* path,
|
|||
|
||||
FDUtils::SetNonBlocking(read_in[0]);
|
||||
*in = read_in[0];
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
FDUtils::SetNonBlocking(write_out[1]);
|
||||
*out = write_out[1];
|
||||
close(write_out[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
FDUtils::SetNonBlocking(read_err[0]);
|
||||
*err = read_err[0];
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
|
||||
*id = pid;
|
||||
return 0;
|
||||
|
@ -347,7 +351,7 @@ int Process::Start(const char* path,
|
|||
|
||||
|
||||
bool Process::Kill(intptr_t id) {
|
||||
int result = kill(id, SIGKILL);
|
||||
int result = TEMP_FAILURE_RETRY(kill(id, SIGKILL));
|
||||
if (result == -1) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -87,7 +87,7 @@ static void SetChildOsErrorMessage(char* os_error_message,
|
|||
void ExitHandler(int process_signal, siginfo_t* siginfo, void* tmp) {
|
||||
int pid = 0;
|
||||
int status = 0;
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
|
||||
int exit_code = 0;
|
||||
int negative = 0;
|
||||
if (WIFEXITED(status)) {
|
||||
|
@ -105,7 +105,7 @@ void ExitHandler(int process_signal, siginfo_t* siginfo, void* tmp) {
|
|||
if (result != sizeof(message) && errno != EPIPE) {
|
||||
perror("ExitHandler notification failed");
|
||||
}
|
||||
close(process->fd());
|
||||
TEMP_FAILURE_RETRY(close(process->fd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ static void ReportChildError(int exec_control_fd) {
|
|||
FDUtils::WriteToBlocking(
|
||||
exec_control_fd, os_error_message, strlen(os_error_message) + 1);
|
||||
}
|
||||
close(exec_control_fd);
|
||||
TEMP_FAILURE_RETRY(close(exec_control_fd));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -147,59 +147,61 @@ int Process::Start(const char* path,
|
|||
int exec_control[2]; // Pipe to get the result from exec.
|
||||
int result;
|
||||
|
||||
result = pipe(read_in);
|
||||
result = TEMP_FAILURE_RETRY(pipe(read_in));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(read_err);
|
||||
result = TEMP_FAILURE_RETRY(pipe(read_err));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(write_out);
|
||||
result = TEMP_FAILURE_RETRY(pipe(write_out));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
result = pipe(exec_control);
|
||||
result = TEMP_FAILURE_RETRY(pipe(exec_control));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
||||
// Set close on exec on the write file descriptor of the exec control pipe.
|
||||
result = fcntl(
|
||||
exec_control[1], F_SETFD, fcntl(exec_control[1], F_GETFD) | FD_CLOEXEC);
|
||||
result = TEMP_FAILURE_RETRY(
|
||||
fcntl(exec_control[1],
|
||||
F_SETFD,
|
||||
TEMP_FAILURE_RETRY(fcntl(exec_control[1], F_GETFD)) | FD_CLOEXEC));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
close(exec_control[0]);
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
fprintf(stderr, "fcntl failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
@ -218,18 +220,18 @@ int Process::Start(const char* path,
|
|||
if (sigaction(SIGCHLD, &act, 0) != 0) {
|
||||
perror("Process start: setting signal handler failed");
|
||||
}
|
||||
pid = fork();
|
||||
pid = TEMP_FAILURE_RETRY(fork());
|
||||
if (pid < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
delete[] program_arguments;
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
close(exec_control[0]);
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
return errno;
|
||||
} else if (pid == 0) {
|
||||
// Wait for parent process before setting up the child process.
|
||||
|
@ -240,31 +242,33 @@ int Process::Start(const char* path,
|
|||
exit(1);
|
||||
}
|
||||
|
||||
close(write_out[1]);
|
||||
close(read_in[0]);
|
||||
close(read_err[0]);
|
||||
close(exec_control[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
|
||||
if (dup2(write_out[0], STDIN_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(write_out[0], STDIN_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(write_out[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
|
||||
if (dup2(read_in[1], STDOUT_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(read_in[1], STDOUT_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
|
||||
if (dup2(read_err[1], STDERR_FILENO) == -1) {
|
||||
if (TEMP_FAILURE_RETRY(dup2(read_err[1], STDERR_FILENO)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
|
||||
if (working_directory != NULL && chdir(working_directory) == -1) {
|
||||
if (working_directory != NULL &&
|
||||
TEMP_FAILURE_RETRY(chdir(working_directory)) == -1) {
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
|
||||
execvp(path, const_cast<char* const*>(program_arguments));
|
||||
TEMP_FAILURE_RETRY(
|
||||
execvp(path, const_cast<char* const*>(program_arguments)));
|
||||
ReportChildError(exec_control[1]);
|
||||
}
|
||||
|
||||
|
@ -272,15 +276,15 @@ int Process::Start(const char* path,
|
|||
delete[] program_arguments;
|
||||
|
||||
int event_fds[2];
|
||||
result = pipe(event_fds);
|
||||
result = TEMP_FAILURE_RETRY(pipe(event_fds));
|
||||
if (result < 0) {
|
||||
SetChildOsErrorMessage(os_error_message, os_error_message_len);
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
fprintf(stderr, "Error pipe creation failed: %s\n", os_error_message);
|
||||
return errno;
|
||||
}
|
||||
|
@ -300,7 +304,7 @@ int Process::Start(const char* path,
|
|||
// Read exec result from child. If no data is returned the exec was
|
||||
// successful and the exec call closed the pipe. Otherwise the errno
|
||||
// is written to the pipe.
|
||||
close(exec_control[1]);
|
||||
TEMP_FAILURE_RETRY(close(exec_control[1]));
|
||||
int child_errno;
|
||||
int bytes_read = -1;
|
||||
ASSERT(sizeof(child_errno) == sizeof(errno));
|
||||
|
@ -313,16 +317,16 @@ int Process::Start(const char* path,
|
|||
os_error_message_len);
|
||||
os_error_message[os_error_message_len - 1] = '\0';
|
||||
}
|
||||
close(exec_control[0]);
|
||||
TEMP_FAILURE_RETRY(close(exec_control[0]));
|
||||
|
||||
// Return error code if any failures.
|
||||
if (bytes_read != 0) {
|
||||
close(read_in[0]);
|
||||
close(read_in[1]);
|
||||
close(read_err[0]);
|
||||
close(read_err[1]);
|
||||
close(write_out[0]);
|
||||
close(write_out[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[0]));
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
TEMP_FAILURE_RETRY(close(write_out[1]));
|
||||
if (bytes_read == -1) {
|
||||
return errno; // Read failed.
|
||||
} else {
|
||||
|
@ -332,13 +336,13 @@ int Process::Start(const char* path,
|
|||
|
||||
FDUtils::SetNonBlocking(read_in[0]);
|
||||
*in = read_in[0];
|
||||
close(read_in[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_in[1]));
|
||||
FDUtils::SetNonBlocking(write_out[1]);
|
||||
*out = write_out[1];
|
||||
close(write_out[0]);
|
||||
TEMP_FAILURE_RETRY(close(write_out[0]));
|
||||
FDUtils::SetNonBlocking(read_err[0]);
|
||||
*err = read_err[0];
|
||||
close(read_err[1]);
|
||||
TEMP_FAILURE_RETRY(close(read_err[1]));
|
||||
|
||||
*id = pid;
|
||||
return 0;
|
||||
|
@ -346,7 +350,7 @@ int Process::Start(const char* path,
|
|||
|
||||
|
||||
bool Process::Kill(intptr_t id) {
|
||||
int result = kill(id, SIGKILL);
|
||||
int result = TEMP_FAILURE_RETRY(kill(id, SIGKILL));
|
||||
if (result == -1) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -26,7 +26,7 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
struct hostent* server;
|
||||
struct sockaddr_in server_address;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error CreateConnect: %s\n", strerror(errno));
|
||||
return -1;
|
||||
|
@ -36,7 +36,7 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL) {
|
||||
close(fd);
|
||||
TEMP_FAILURE_RETRY(close(fd));
|
||||
fprintf(stderr, "Error CreateConnect: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,9 +45,10 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
server_address.sin_port = htons(port);
|
||||
bcopy(server->h_addr, &server_address.sin_addr.s_addr, server->h_length);
|
||||
memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
|
||||
intptr_t result = connect(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address));
|
||||
intptr_t result = TEMP_FAILURE_RETRY(
|
||||
connect(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address)));
|
||||
if (result == 0 || errno == EINPROGRESS) {
|
||||
return fd;
|
||||
}
|
||||
|
@ -62,11 +63,11 @@ intptr_t Socket::Available(intptr_t fd) {
|
|||
|
||||
int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t read_bytes = read(fd, buffer, num_bytes);
|
||||
if (read_bytes == -1 &&
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
|
||||
// If the read was interrupted or the read would block we need
|
||||
// to retry and therefore return 0 as the number of bytes written.
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (read_bytes == -1 && errno == EWOULDBLOCK) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
}
|
||||
return read_bytes;
|
||||
|
@ -75,11 +76,11 @@ int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
|
||||
int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes = write(fd, buffer, num_bytes);
|
||||
if (written_bytes == -1 &&
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
|
||||
// If the write was interrupted or the write would block we need
|
||||
// to retry and therefore return 0 as the number of bytes written.
|
||||
ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (written_bytes == -1 && errno == EWOULDBLOCK) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
}
|
||||
return written_bytes;
|
||||
|
@ -90,8 +91,10 @@ intptr_t Socket::GetPort(intptr_t fd) {
|
|||
ASSERT(fd >= 0);
|
||||
struct sockaddr_in socket_address;
|
||||
socklen_t size = sizeof(socket_address);
|
||||
if (getsockname(fd, reinterpret_cast<struct sockaddr *>(&socket_address),
|
||||
&size)) {
|
||||
if (TEMP_FAILURE_RETRY(
|
||||
getsockname(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&socket_address),
|
||||
&size))) {
|
||||
fprintf(stderr, "Error getsockname: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,33 +108,36 @@ intptr_t Socket::GetStdioHandle(int num) {
|
|||
|
||||
|
||||
intptr_t ServerSocket::CreateBindListen(const char* host,
|
||||
intptr_t port,
|
||||
intptr_t backlog) {
|
||||
intptr_t port,
|
||||
intptr_t backlog) {
|
||||
intptr_t fd;
|
||||
struct sockaddr_in server_address;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error CreateBind: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int optval = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
TEMP_FAILURE_RETRY(
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
|
||||
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(port);
|
||||
server_address.sin_addr.s_addr = inet_addr(host);
|
||||
memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
|
||||
|
||||
if (bind(fd, reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address)) < 0) {
|
||||
close(fd);
|
||||
if (TEMP_FAILURE_RETRY(
|
||||
bind(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address))) < 0) {
|
||||
TEMP_FAILURE_RETRY(close(fd));
|
||||
fprintf(stderr, "Error Bind: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(fd, backlog) != 0) {
|
||||
if (TEMP_FAILURE_RETRY(listen(fd, backlog)) != 0) {
|
||||
fprintf(stderr, "Error Listen: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -144,7 +150,7 @@ intptr_t ServerSocket::Accept(intptr_t fd) {
|
|||
intptr_t socket;
|
||||
struct sockaddr clientaddr;
|
||||
socklen_t addrlen = sizeof(clientaddr);
|
||||
socket = accept(fd, &clientaddr, &addrlen);
|
||||
socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
|
||||
if (socket < 0) {
|
||||
fprintf(stderr, "Error Accept: %s\n", strerror(errno));
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
||||
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -26,7 +26,7 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
struct hostent* server;
|
||||
struct sockaddr_in server_address;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error CreateConnect: %s\n", strerror(errno));
|
||||
return -1;
|
||||
|
@ -36,7 +36,7 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
|
||||
server = gethostbyname(host);
|
||||
if (server == NULL) {
|
||||
close(fd);
|
||||
TEMP_FAILURE_RETRY(close(fd));
|
||||
fprintf(stderr, "Error CreateConnect: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,9 +45,10 @@ intptr_t Socket::CreateConnect(const char* host, const intptr_t port) {
|
|||
server_address.sin_port = htons(port);
|
||||
bcopy(server->h_addr, &server_address.sin_addr.s_addr, server->h_length);
|
||||
memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
|
||||
intptr_t result = connect(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address));
|
||||
intptr_t result = TEMP_FAILURE_RETRY(
|
||||
connect(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address)));
|
||||
if (result == 0 || errno == EINPROGRESS) {
|
||||
return fd;
|
||||
}
|
||||
|
@ -62,11 +63,11 @@ intptr_t Socket::Available(intptr_t fd) {
|
|||
|
||||
int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t read_bytes = read(fd, buffer, num_bytes);
|
||||
if (read_bytes == -1 &&
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
|
||||
// If the read was interrupted or the read would block we need
|
||||
// to retry and therefore return 0 as the number of bytes written.
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (read_bytes == -1 && errno == EWOULDBLOCK) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
}
|
||||
return read_bytes;
|
||||
|
@ -75,11 +76,11 @@ int Socket::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
|
||||
int Socket::Write(intptr_t fd, const void* buffer, intptr_t num_bytes) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes = write(fd, buffer, num_bytes);
|
||||
if (written_bytes == -1 &&
|
||||
(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) {
|
||||
// If the write was interrupted or the write would block we need
|
||||
// to retry and therefore return 0 as the number of bytes written.
|
||||
ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if (written_bytes == -1 && errno == EWOULDBLOCK) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
}
|
||||
return written_bytes;
|
||||
|
@ -90,8 +91,10 @@ intptr_t Socket::GetPort(intptr_t fd) {
|
|||
ASSERT(fd >= 0);
|
||||
struct sockaddr_in socket_address;
|
||||
socklen_t size = sizeof(socket_address);
|
||||
if (getsockname(fd, reinterpret_cast<struct sockaddr *>(&socket_address),
|
||||
&size)) {
|
||||
if (TEMP_FAILURE_RETRY(
|
||||
getsockname(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&socket_address),
|
||||
&size))) {
|
||||
fprintf(stderr, "Error getsockname: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,33 +108,36 @@ intptr_t Socket::GetStdioHandle(int num) {
|
|||
|
||||
|
||||
intptr_t ServerSocket::CreateBindListen(const char* host,
|
||||
intptr_t port,
|
||||
intptr_t backlog) {
|
||||
intptr_t port,
|
||||
intptr_t backlog) {
|
||||
intptr_t fd;
|
||||
struct sockaddr_in server_address;
|
||||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd = TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_STREAM, 0));
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error CreateBind: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int optval = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
||||
TEMP_FAILURE_RETRY(
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)));
|
||||
|
||||
server_address.sin_family = AF_INET;
|
||||
server_address.sin_port = htons(port);
|
||||
server_address.sin_addr.s_addr = inet_addr(host);
|
||||
memset(&server_address.sin_zero, 0, sizeof(server_address.sin_zero));
|
||||
|
||||
if (bind(fd, reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address)) < 0) {
|
||||
close(fd);
|
||||
if (TEMP_FAILURE_RETRY(
|
||||
bind(fd,
|
||||
reinterpret_cast<struct sockaddr *>(&server_address),
|
||||
sizeof(server_address))) < 0) {
|
||||
TEMP_FAILURE_RETRY(close(fd));
|
||||
fprintf(stderr, "Error Bind: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(fd, backlog) != 0) {
|
||||
if (TEMP_FAILURE_RETRY(listen(fd, backlog)) != 0) {
|
||||
fprintf(stderr, "Error Listen: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
@ -144,7 +150,7 @@ intptr_t ServerSocket::Accept(intptr_t fd) {
|
|||
intptr_t socket;
|
||||
struct sockaddr clientaddr;
|
||||
socklen_t addrlen = sizeof(clientaddr);
|
||||
socket = accept(fd, &clientaddr, &addrlen);
|
||||
socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen));
|
||||
if (socket < 0) {
|
||||
fprintf(stderr, "Error Accept: %s\n", strerror(errno));
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "platform/c99_support_win.h"
|
||||
|
@ -102,4 +103,17 @@ static inline void USE(T) { }
|
|||
#define strtok_r strtok_s
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_OS_WINDOWS) && !defined(TEMP_FAILURE_RETRY)
|
||||
// TEMP_FAILURE_RETRY is defined in unistd.h on some platforms. The
|
||||
// definition below is copied from Linux and adapted to avoid lint
|
||||
// errors (type long int changed to int64_t and do/while split on
|
||||
// separate lines with body in {}s).
|
||||
# define TEMP_FAILURE_RETRY(expression) \
|
||||
({ int64_t __result; \
|
||||
do { \
|
||||
__result = (int64_t) (expression); \
|
||||
} while (__result == -1L && errno == EINTR); \
|
||||
__result; })
|
||||
#endif
|
||||
|
||||
#endif // PLATFORM_GLOBALS_H_
|
||||
|
|
Loading…
Reference in a new issue