diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-05 03:38:28 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-06-05 03:38:28 +0000 |
commit | 6ef15ce55a095ac8fea78d579b86b41efc9dcbab (patch) | |
tree | ffc3db8d8fb35679a2db76759789567c26e2453d /win32 | |
parent | 88fbd108a2afa59c1f7aa542745a582073d92e63 (diff) |
merge revision(s) 40887,40888,40894,40896: [Backport #8431]
* win32/win32.c (setup_overlapped, finish_overlapped): extract from
rb_w32_read() and rb_w32_write().
* win32/win32.c (setup_overlapped): check the error code in addition
to the result of SetFilePointer() to determine if an error occurred,
because INVALID_SET_FILE_POINTER is a valid value.
[ruby-core:55098] [Bug #8431]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@41082 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r-- | win32/win32.c | 103 |
1 files changed, 47 insertions, 56 deletions
diff --git a/win32/win32.c b/win32/win32.c index c35e5462f8..fbf35664b6 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -5180,6 +5180,49 @@ rb_w32_close(int fd) return 0; } +static int +setup_overlapped(OVERLAPPED *ol, int fd) +{ + memset(ol, 0, sizeof(*ol)); + if (!(_osfile(fd) & (FDEV | FPIPE))) { + LONG high = 0; + DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT; + DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method); +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + if (low == INVALID_SET_FILE_POINTER) { + DWORD err = GetLastError(); + if (err != NO_ERROR) { + errno = map_errno(err); + return -1; + } + } + ol->Offset = low; + ol->OffsetHigh = high; + } + ol->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + if (!ol->hEvent) { + errno = map_errno(GetLastError()); + return -1; + } + return 0; +} + +static void +finish_overlapped(OVERLAPPED *ol, int fd, DWORD size) +{ + CloseHandle(ol->hEvent); + + if (!(_osfile(fd) & (FDEV | FPIPE))) { + LONG high = ol->OffsetHigh; + DWORD low = ol->Offset + size; + if (low < ol->Offset) + ++high; + SetFilePointer((HANDLE)_osfhnd(fd), low, &high, FILE_BEGIN); + } +} + #undef read ssize_t rb_w32_read(int fd, void *buf, size_t size) @@ -5238,25 +5281,7 @@ rb_w32_read(int fd, void *buf, size_t size) /* if have cancel_io, use Overlapped I/O */ if (cancel_io) { - memset(&ol, 0, sizeof(ol)); - if (!(_osfile(fd) & (FDEV | FPIPE))) { - LONG high = 0; - DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, - FILE_CURRENT); -#ifndef INVALID_SET_FILE_POINTER -#define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - if (low == INVALID_SET_FILE_POINTER) { - errno = map_errno(GetLastError()); - MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); - return -1; - } - ol.Offset = low; - ol.OffsetHigh = high; - } - ol.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (!ol.hEvent) { - errno = map_errno(GetLastError()); + if (setup_overlapped(&ol, fd)) { MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); return -1; } @@ -5310,15 +5335,7 @@ rb_w32_read(int fd, void *buf, size_t size) } if (pol) { - CloseHandle(ol.hEvent); - - if (!(_osfile(fd) & (FDEV | FPIPE))) { - LONG high = ol.OffsetHigh; - DWORD low = ol.Offset + read; - if (low < ol.Offset) - ++high; - SetFilePointer((HANDLE)_osfhnd(fd), low, &high, FILE_BEGIN); - } + finish_overlapped(&ol, fd, read); } ret += read; @@ -5376,25 +5393,7 @@ rb_w32_write(int fd, const void *buf, size_t size) /* if have cancel_io, use Overlapped I/O */ if (cancel_io) { - memset(&ol, 0, sizeof(ol)); - if (!(_osfile(fd) & (FDEV | FPIPE))) { - LONG high = 0; - DWORD method = _osfile(fd) & FAPPEND ? FILE_END : FILE_CURRENT; - DWORD low = SetFilePointer((HANDLE)_osfhnd(fd), 0, &high, method); -#ifndef INVALID_SET_FILE_POINTER -#define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - if (low == INVALID_SET_FILE_POINTER) { - errno = map_errno(GetLastError()); - MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); - return -1; - } - ol.Offset = low; - ol.OffsetHigh = high; - } - ol.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); - if (!ol.hEvent) { - errno = map_errno(GetLastError()); + if (setup_overlapped(&ol, fd)) { MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock)); return -1; } @@ -5440,15 +5439,7 @@ rb_w32_write(int fd, const void *buf, size_t size) } if (pol) { - CloseHandle(ol.hEvent); - - if (!(_osfile(fd) & (FDEV | FPIPE))) { - LONG high = ol.OffsetHigh; - DWORD low = ol.Offset + written; - if (low < ol.Offset) - ++high; - SetFilePointer((HANDLE)_osfhnd(fd), low, &high, FILE_BEGIN); - } + finish_overlapped(&ol, fd, written); } ret += written; |