mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 01:23:57 +02:00
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_2_0_0@41056 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
e6ae0db36e
commit
e377d3bb75
4 changed files with 84 additions and 57 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Tue Jun 4 00:46:05 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* win32/win32.c (setup_overlapped, finish_overlapped): extract from
|
||||||
|
rb_w32_read() and rb_w32_write().
|
||||||
|
|
||||||
Tue Jun 4 00:02:45 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Tue Jun 4 00:02:45 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* vm_core.h (rb_vm_tag): move jmpbuf between tag and prev so ensure to
|
* vm_core.h (rb_vm_tag): move jmpbuf between tag and prev so ensure to
|
||||||
|
|
|
@ -2655,4 +2655,35 @@ End
|
||||||
IO.select(tempfiles)
|
IO.select(tempfiles)
|
||||||
}, bug8080
|
}, bug8080
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_read_32bit_boundary
|
||||||
|
bug8431 = '[ruby-core:55098] [Bug #8431]'
|
||||||
|
make_tempfile {|t|
|
||||||
|
assert_separately(["-", bug8431, t.path], <<-"end;")
|
||||||
|
msg = ARGV.shift
|
||||||
|
f = open(ARGV[0], "rb")
|
||||||
|
f.seek(0xffff_ffff)
|
||||||
|
assert_nil(f.read(1), msg)
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
end if /mswin|mingw/ =~ RUBY_PLATFORM
|
||||||
|
|
||||||
|
def test_write_32bit_boundary
|
||||||
|
bug8431 = '[ruby-core:55098] [Bug #8431]'
|
||||||
|
make_tempfile {|t|
|
||||||
|
assert_separately(["-", bug8431, t.path], <<-"end;", timeout: 30)
|
||||||
|
msg = ARGV.shift
|
||||||
|
f = open(ARGV[0], "wb")
|
||||||
|
f.seek(0xffff_ffff)
|
||||||
|
begin
|
||||||
|
# this will consume very long time or fail by ENOSPC on a
|
||||||
|
# filesystem which sparse file is not supported
|
||||||
|
f.write('1')
|
||||||
|
rescue SystemCallError
|
||||||
|
else
|
||||||
|
assert_equal(0x1_0000_0000, f.tell, msg)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
}
|
||||||
|
end if /mswin|mingw/ =~ RUBY_PLATFORM
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#define RUBY_VERSION "2.0.0"
|
#define RUBY_VERSION "2.0.0"
|
||||||
#define RUBY_RELEASE_DATE "2013-06-04"
|
#define RUBY_RELEASE_DATE "2013-06-04"
|
||||||
#define RUBY_PATCHLEVEL 200
|
#define RUBY_PATCHLEVEL 201
|
||||||
|
|
||||||
#define RUBY_RELEASE_YEAR 2013
|
#define RUBY_RELEASE_YEAR 2013
|
||||||
#define RUBY_RELEASE_MONTH 6
|
#define RUBY_RELEASE_MONTH 6
|
||||||
|
|
103
win32/win32.c
103
win32/win32.c
|
@ -5867,6 +5867,49 @@ rb_w32_close(int fd)
|
||||||
return 0;
|
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
|
#undef read
|
||||||
/* License: Ruby's */
|
/* License: Ruby's */
|
||||||
ssize_t
|
ssize_t
|
||||||
|
@ -5927,25 +5970,7 @@ rb_w32_read(int fd, void *buf, size_t size)
|
||||||
|
|
||||||
/* if have cancel_io, use Overlapped I/O */
|
/* if have cancel_io, use Overlapped I/O */
|
||||||
if (cancel_io) {
|
if (cancel_io) {
|
||||||
memset(&ol, 0, sizeof(ol));
|
if (setup_overlapped(&ol, fd)) {
|
||||||
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());
|
|
||||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -6003,15 +6028,7 @@ rb_w32_read(int fd, void *buf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pol) {
|
if (pol) {
|
||||||
CloseHandle(ol.hEvent);
|
finish_overlapped(&ol, fd, read);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += read;
|
ret += read;
|
||||||
|
@ -6071,25 +6088,7 @@ rb_w32_write(int fd, const void *buf, size_t size)
|
||||||
|
|
||||||
/* if have cancel_io, use Overlapped I/O */
|
/* if have cancel_io, use Overlapped I/O */
|
||||||
if (cancel_io) {
|
if (cancel_io) {
|
||||||
memset(&ol, 0, sizeof(ol));
|
if (setup_overlapped(&ol, fd)) {
|
||||||
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());
|
|
||||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -6135,15 +6134,7 @@ rb_w32_write(int fd, const void *buf, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pol) {
|
if (pol) {
|
||||||
CloseHandle(ol.hEvent);
|
finish_overlapped(&ol, fd, written);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += written;
|
ret += written;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue