mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2024-12-27 05:55:02 +03:00
OS X returns EINVAL for write > 2^31
This commit is contained in:
parent
ae53bc91d1
commit
627f3f908c
39
util/file.cc
39
util/file.cc
@ -111,15 +111,26 @@ void ResizeOrThrow(int fd, uint64_t to) {
|
|||||||
UTIL_THROW_IF_ARG(ret, FDException, (fd), "while resizing to " << to << " bytes");
|
UTIL_THROW_IF_ARG(ret, FDException, (fd), "while resizing to " << to << " bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::size_t GuardLarge(std::size_t size) {
|
||||||
|
// The following operating systems have broken read/write/pread/pwrite that
|
||||||
|
// only supports up to 2^31.
|
||||||
|
#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) || defined(OS_ANDROID)
|
||||||
|
return std::min(static_cast<std::size_t>(INT_MAX), size);
|
||||||
|
#else
|
||||||
|
return size;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::size_t PartialRead(int fd, void *to, std::size_t amount) {
|
std::size_t PartialRead(int fd, void *to, std::size_t amount) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
amount = min(static_cast<std::size_t>(INT_MAX), amount);
|
int ret = _read(fd, to, GuardLarge(amount));
|
||||||
int ret = _read(fd, to, amount);
|
|
||||||
#else
|
#else
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
do {
|
do {
|
||||||
ret = read(fd, to, amount);
|
ret = read(fd, to, GuardLarge(amount));
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
#endif
|
#endif
|
||||||
UTIL_THROW_IF_ARG(ret < 0, FDException, (fd), "while reading " << amount << " bytes");
|
UTIL_THROW_IF_ARG(ret < 0, FDException, (fd), "while reading " << amount << " bytes");
|
||||||
@ -169,11 +180,13 @@ void PReadOrThrow(int fd, void *to_void, std::size_t size, uint64_t off) {
|
|||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
do {
|
do {
|
||||||
|
ret =
|
||||||
#ifdef OS_ANDROID
|
#ifdef OS_ANDROID
|
||||||
ret = pread64(fd, to, size, off);
|
pread64
|
||||||
#else
|
#else
|
||||||
ret = pread(fd, to, size, off);
|
pread
|
||||||
#endif
|
#endif
|
||||||
|
(fd, to, GuardLarge(size), off);
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
UTIL_THROW_IF(ret == 0, EndOfFileException, " for reading " << size << " bytes at " << off << " from " << NameFromFD(fd));
|
UTIL_THROW_IF(ret == 0, EndOfFileException, " for reading " << size << " bytes at " << off << " from " << NameFromFD(fd));
|
||||||
@ -190,14 +203,20 @@ void WriteOrThrow(int fd, const void *data_void, std::size_t size) {
|
|||||||
const uint8_t *data = static_cast<const uint8_t*>(data_void);
|
const uint8_t *data = static_cast<const uint8_t*>(data_void);
|
||||||
while (size) {
|
while (size) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
int ret = write(fd, data, min(static_cast<std::size_t>(INT_MAX), size));
|
int ret;
|
||||||
#else
|
#else
|
||||||
errno = 0;
|
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
do {
|
|
||||||
ret = write(fd, data, size);
|
|
||||||
} while (ret == -1 && errno == EINTR);
|
|
||||||
#endif
|
#endif
|
||||||
|
errno = 0;
|
||||||
|
do {
|
||||||
|
ret =
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
_write
|
||||||
|
#else
|
||||||
|
write
|
||||||
|
#endif
|
||||||
|
(fd, data, GuardLarge(size));
|
||||||
|
} while (ret == -1 && errno == EINTR);
|
||||||
UTIL_THROW_IF_ARG(ret < 1, FDException, (fd), "while writing " << size << " bytes");
|
UTIL_THROW_IF_ARG(ret < 1, FDException, (fd), "while writing " << size << " bytes");
|
||||||
data += ret;
|
data += ret;
|
||||||
size -= ret;
|
size -= ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user