mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* win32/win32.c, include/ruby/win32.h (rb_w32_open): overlapped file
I/O support. * win32/win32.c, include/ruby/win32.h (rb_w32_pipe): overlapped pipe I/O support. * wn32/win32.c (rb_w32_read, rb_w32_write): overlapped I/O support to enable canceling I/O. * thread_win32.c (ubf_handle): remove workaround. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cf6334e1cb
commit
3c8dca55c4
4 changed files with 466 additions and 20 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
Thu Aug 28 21:43:05 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* win32/win32.c, include/ruby/win32.h (rb_w32_open): overlapped file
|
||||
I/O support.
|
||||
|
||||
* win32/win32.c, include/ruby/win32.h (rb_w32_pipe): overlapped pipe
|
||||
I/O support.
|
||||
|
||||
* wn32/win32.c (rb_w32_read, rb_w32_write): overlapped I/O support to
|
||||
enable canceling I/O.
|
||||
|
||||
* thread_win32.c (ubf_handle): remove workaround.
|
||||
|
||||
Thu Aug 28 20:22:49 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* vm_insnhelper.c (vm_yield_setup_args): object with to_ary should
|
||||
|
|
|
@ -134,7 +134,8 @@ extern DWORD rb_w32_osid(void);
|
|||
#define utime(_p, _t) rb_w32_utime(_p, _t)
|
||||
#define lseek(_f, _o, _w) _lseeki64(_f, _o, _w)
|
||||
|
||||
#define pipe(p) _pipe(p, 65536L, _O_NOINHERIT)
|
||||
#define pipe(p) rb_w32_pipe(p)
|
||||
#define open rb_w32_open
|
||||
#define close(h) rb_w32_close(h)
|
||||
#define fclose(f) rb_w32_fclose(f)
|
||||
#define read(f, b, s) rb_w32_read(f, b, s)
|
||||
|
@ -543,8 +544,10 @@ HANDLE GetCurrentThreadHandle(void);
|
|||
int rb_w32_sleep(unsigned long msec);
|
||||
int rb_w32_putc(int, FILE*);
|
||||
int rb_w32_getc(FILE*);
|
||||
int rb_w32_open(const char *, int, ...);
|
||||
int rb_w32_close(int);
|
||||
int rb_w32_fclose(FILE*);
|
||||
int rb_w32_pipe(int[2]);
|
||||
size_t rb_w32_read(int, void *, size_t);
|
||||
size_t rb_w32_write(int, const void *, size_t);
|
||||
int rb_w32_utime(const char *, const struct utimbuf *);
|
||||
|
|
|
@ -524,18 +524,9 @@ static void
|
|||
ubf_handle(void *ptr)
|
||||
{
|
||||
typedef BOOL (WINAPI *cancel_io_func_t)(HANDLE);
|
||||
static cancel_io_func_t cancel_func = NULL;
|
||||
rb_thread_t *th = (rb_thread_t *)ptr;
|
||||
thread_debug("ubf_handle: %p\n", th);
|
||||
|
||||
if (!cancel_func) {
|
||||
cancel_func = (cancel_io_func_t)GetProcAddress(GetModuleHandle("kernel32"), "CancelSynchronousIo");
|
||||
if (!cancel_func)
|
||||
cancel_func = (cancel_io_func_t)-1;
|
||||
}
|
||||
if (cancel_func != (cancel_io_func_t)-1)
|
||||
cancel_func((HANDLE)th->thread_id);
|
||||
|
||||
w32_set_event(th->native_thread_data.interrupt_event);
|
||||
}
|
||||
|
||||
|
|
459
win32/win32.c
459
win32/win32.c
|
@ -1736,6 +1736,8 @@ set_pioinfo_extra(void)
|
|||
#define _set_osflags(fh, flags) (_osfile(fh) = (flags))
|
||||
|
||||
#define FOPEN 0x01 /* file handle open */
|
||||
#define FEOFLAG 0x02 /* end of file has been encountered */
|
||||
#define FPIPE 0x08 /* file handle refers to a pipe */
|
||||
#define FNOINHERIT 0x10 /* file handle opened O_NOINHERIT */
|
||||
#define FAPPEND 0x20 /* file handle opened O_APPEND */
|
||||
#define FDEV 0x40 /* file handle refers to device */
|
||||
|
@ -3994,6 +3996,167 @@ rb_w32_getppid(void)
|
|||
return ppid;
|
||||
}
|
||||
|
||||
int
|
||||
rb_w32_open(const char *file, int oflag, ...)
|
||||
{
|
||||
char flags = 0;
|
||||
int fd;
|
||||
DWORD access;
|
||||
DWORD create;
|
||||
DWORD attr = FILE_ATTRIBUTE_NORMAL;
|
||||
SECURITY_ATTRIBUTES sec;
|
||||
HANDLE h;
|
||||
|
||||
sec.nLength = sizeof(sec);
|
||||
sec.lpSecurityDescriptor = NULL;
|
||||
if (oflag & O_NOINHERIT) {
|
||||
sec.bInheritHandle = FALSE;
|
||||
flags |= FNOINHERIT;
|
||||
}
|
||||
else {
|
||||
sec.bInheritHandle = TRUE;
|
||||
}
|
||||
oflag &= ~O_NOINHERIT;
|
||||
|
||||
/* always open with binary mode */
|
||||
oflag &= ~(O_BINARY | O_TEXT);
|
||||
|
||||
switch (oflag & (O_RDWR | O_RDONLY | O_WRONLY)) {
|
||||
case O_RDWR:
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
case O_RDONLY:
|
||||
access = GENERIC_READ;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
access = GENERIC_WRITE;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
oflag &= ~(O_RDWR | O_RDONLY | O_WRONLY);
|
||||
|
||||
switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
|
||||
case O_CREAT:
|
||||
create = OPEN_ALWAYS;
|
||||
break;
|
||||
case 0:
|
||||
case O_EXCL:
|
||||
create = OPEN_EXISTING;
|
||||
break;
|
||||
case O_CREAT | O_EXCL:
|
||||
case O_CREAT | O_EXCL | O_TRUNC:
|
||||
create = CREATE_NEW;
|
||||
break;
|
||||
case O_TRUNC:
|
||||
case O_TRUNC | O_EXCL:
|
||||
create = TRUNCATE_EXISTING;
|
||||
break;
|
||||
case O_CREAT | O_TRUNC:
|
||||
create = CREATE_ALWAYS;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (oflag & O_CREAT) {
|
||||
va_list arg;
|
||||
int pmode;
|
||||
va_start(arg, oflag);
|
||||
pmode = va_arg(arg, int);
|
||||
va_end(arg);
|
||||
/* TODO: we need to check umask here, but it's not exported... */
|
||||
if (!(pmode & S_IWRITE))
|
||||
attr = FILE_ATTRIBUTE_READONLY;
|
||||
}
|
||||
oflag &= ~(O_CREAT | O_EXCL | O_TRUNC);
|
||||
|
||||
if (oflag & O_TEMPORARY) {
|
||||
attr |= FILE_FLAG_DELETE_ON_CLOSE;
|
||||
access |= DELETE;
|
||||
}
|
||||
oflag &= ~O_TEMPORARY;
|
||||
|
||||
if (oflag & _O_SHORT_LIVED)
|
||||
attr |= FILE_ATTRIBUTE_TEMPORARY;
|
||||
oflag &= ~_O_SHORT_LIVED;
|
||||
|
||||
switch (oflag & (O_SEQUENTIAL | O_RANDOM)) {
|
||||
case 0:
|
||||
break;
|
||||
case O_SEQUENTIAL:
|
||||
attr |= FILE_FLAG_SEQUENTIAL_SCAN;
|
||||
break;
|
||||
case O_RANDOM:
|
||||
attr |= FILE_FLAG_RANDOM_ACCESS;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
oflag &= ~(O_SEQUENTIAL | O_RANDOM);
|
||||
|
||||
if (oflag & ~O_APPEND) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allocate a C Runtime file handle */
|
||||
RUBY_CRITICAL({
|
||||
h = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
fd = _open_osfhandle((long)h, 0);
|
||||
CloseHandle(h);
|
||||
});
|
||||
if (fd == -1) {
|
||||
errno = EMFILE;
|
||||
return -1;
|
||||
}
|
||||
RUBY_CRITICAL({
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fd)->lock)));
|
||||
_set_osfhnd(fd, (long)INVALID_HANDLE_VALUE);
|
||||
_set_osflags(fd, 0);
|
||||
|
||||
/* open with FILE_FLAG_OVERLAPPED if have CancelIo */
|
||||
if (cancel_io)
|
||||
attr |= FILE_FLAG_OVERLAPPED;
|
||||
h = CreateFile(file, access, FILE_SHARE_READ | FILE_SHARE_WRITE, &sec,
|
||||
create, attr, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE) {
|
||||
errno = map_errno(GetLastError());
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
fd = -1;
|
||||
goto quit;
|
||||
}
|
||||
|
||||
switch (GetFileType(h)) {
|
||||
case FILE_TYPE_CHAR:
|
||||
flags |= FDEV;
|
||||
break;
|
||||
case FILE_TYPE_PIPE:
|
||||
flags |= FPIPE;
|
||||
break;
|
||||
case FILE_TYPE_UNKNOWN:
|
||||
errno = map_errno(GetLastError());
|
||||
CloseHandle(h);
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
fd = -1;
|
||||
goto quit;
|
||||
}
|
||||
if (!(flags & (FDEV | FPIPE)) && (oflag & O_APPEND))
|
||||
flags |= FAPPEND;
|
||||
|
||||
_set_osfhnd(fd, (long)h);
|
||||
_osfile(fd) = flags | FOPEN;
|
||||
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
quit:
|
||||
;
|
||||
});
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
rb_w32_fclose(FILE *fp)
|
||||
{
|
||||
|
@ -4016,6 +4179,98 @@ rb_w32_fclose(FILE *fp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rb_w32_pipe(int fds[2])
|
||||
{
|
||||
static DWORD serial = 0;
|
||||
char name[] = "\\\\.\\pipe\\ruby0000000000000000-0000000000000000";
|
||||
char *p;
|
||||
SECURITY_ATTRIBUTES sec;
|
||||
HANDLE hRead, hWrite, h;
|
||||
int fdRead, fdWrite;
|
||||
int ret;
|
||||
|
||||
/* if doesn't have CancelIo, use default pipe function */
|
||||
if (!cancel_io)
|
||||
return _pipe(fds, 65536L, _O_NOINHERIT);
|
||||
|
||||
p = strchr(name, '0');
|
||||
snprintf(p, strlen(p) + 1, "%x-%x", rb_w32_getpid(), serial++);
|
||||
|
||||
sec.nLength = sizeof(sec);
|
||||
sec.lpSecurityDescriptor = NULL;
|
||||
sec.bInheritHandle = FALSE;
|
||||
|
||||
RUBY_CRITICAL({
|
||||
hRead = CreateNamedPipe(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
|
||||
0, 2, 65536, 65536, 0, &sec);
|
||||
});
|
||||
if (hRead == INVALID_HANDLE_VALUE) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_PIPE_BUSY)
|
||||
errno = EMFILE;
|
||||
else
|
||||
errno = map_errno(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
RUBY_CRITICAL({
|
||||
hWrite = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sec,
|
||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
});
|
||||
if (hWrite == INVALID_HANDLE_VALUE) {
|
||||
errno = map_errno(GetLastError());
|
||||
CloseHandle(hRead);
|
||||
return -1;
|
||||
}
|
||||
|
||||
RUBY_CRITICAL(do {
|
||||
ret = 0;
|
||||
h = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
fdRead = _open_osfhandle((long)h, 0);
|
||||
CloseHandle(h);
|
||||
if (fdRead == -1) {
|
||||
errno = EMFILE;
|
||||
CloseHandle(hWrite);
|
||||
CloseHandle(hRead);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fdRead)->lock)));
|
||||
_set_osfhnd(fdRead, (long)hRead);
|
||||
_set_osflags(fdRead, FOPEN | FPIPE | FNOINHERIT);
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&(_pioinfo(fdRead)->lock)));
|
||||
} while (0));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
RUBY_CRITICAL(do {
|
||||
h = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
|
||||
fdWrite = _open_osfhandle((long)h, 0);
|
||||
CloseHandle(h);
|
||||
if (fdWrite == -1) {
|
||||
errno = EMFILE;
|
||||
CloseHandle(hWrite);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fdWrite)->lock)));
|
||||
_set_osfhnd(fdWrite, (long)hWrite);
|
||||
_set_osflags(fdWrite, FOPEN | FPIPE | FNOINHERIT);
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&(_pioinfo(fdWrite)->lock)));
|
||||
} while (0));
|
||||
if (ret) {
|
||||
rb_w32_close(fdRead);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fds[0] = fdRead;
|
||||
fds[1] = fdWrite;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rb_w32_close(int fd)
|
||||
{
|
||||
|
@ -4045,11 +4300,107 @@ size_t
|
|||
rb_w32_read(int fd, void *buf, size_t size)
|
||||
{
|
||||
SOCKET sock = TO_SOCKET(fd);
|
||||
DWORD read;
|
||||
DWORD wait;
|
||||
DWORD err;
|
||||
OVERLAPPED ol, *pol = NULL;
|
||||
|
||||
if (!is_socket(sock))
|
||||
return read(fd, buf, size);
|
||||
else
|
||||
if (is_socket(sock))
|
||||
return rb_w32_recv(fd, buf, size, 0);
|
||||
|
||||
if (!(_osfile(fd) & FOPEN)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fd)->lock)));
|
||||
|
||||
if (!size || _osfile(fd) & FEOFLAG) {
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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());
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pol = &ol;
|
||||
}
|
||||
|
||||
if (!ReadFile((HANDLE)_osfhnd(fd), buf, size, &read, pol)) {
|
||||
err = GetLastError();
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
if (err == ERROR_ACCESS_DENIED)
|
||||
errno = EBADF;
|
||||
else if (err == ERROR_BROKEN_PIPE) {
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
errno = map_errno(err);
|
||||
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pol) {
|
||||
wait = rb_w32_wait_events_blocking(&ol.hEvent, 1, INFINITE);
|
||||
if (wait != WAIT_OBJECT_0) {
|
||||
if (errno != EINTR)
|
||||
errno = map_errno(GetLastError());
|
||||
CloseHandle(ol.hEvent);
|
||||
cancel_io((HANDLE)_osfhnd(fd));
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!GetOverlappedResult((HANDLE)_osfhnd(fd), &ol, &read, TRUE) &&
|
||||
(err = GetLastError()) != ERROR_HANDLE_EOF) {
|
||||
errno = map_errno(err);
|
||||
CloseHandle(ol.hEvent);
|
||||
cancel_io((HANDLE)_osfhnd(fd));
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pol) {
|
||||
CloseHandle(ol.hEvent);
|
||||
|
||||
if (!(_osfile(fd) & (FDEV | FPIPE))) {
|
||||
LONG high = ol.OffsetHigh;
|
||||
LONG low = ol.Offset + read;
|
||||
if (low < ol.Offset)
|
||||
++high;
|
||||
SetFilePointer((HANDLE)_osfhnd(fd), low, &high, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
#undef write
|
||||
|
@ -4057,15 +4408,103 @@ size_t
|
|||
rb_w32_write(int fd, const void *buf, size_t size)
|
||||
{
|
||||
SOCKET sock = TO_SOCKET(fd);
|
||||
DWORD written;
|
||||
DWORD wait;
|
||||
DWORD err;
|
||||
OVERLAPPED ol, *pol = NULL;
|
||||
|
||||
if (!is_socket(sock)) {
|
||||
size_t ret = write(fd, buf, size);
|
||||
if ((int)ret < 0 && errno == EINVAL)
|
||||
errno = map_errno(GetLastError());
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
if (is_socket(sock))
|
||||
return rb_w32_send(fd, buf, size, 0);
|
||||
|
||||
if (!(_osfile(fd) & FOPEN)) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
MTHREAD_ONLY(EnterCriticalSection(&(_pioinfo(fd)->lock)));
|
||||
|
||||
if (!size || _osfile(fd) & FEOFLAG) {
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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());
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pol = &ol;
|
||||
}
|
||||
|
||||
if (!WriteFile((HANDLE)_osfhnd(fd), buf, size, &written, pol)) {
|
||||
err = GetLastError();
|
||||
if (err != ERROR_IO_PENDING) {
|
||||
if (err == ERROR_ACCESS_DENIED)
|
||||
errno = EBADF;
|
||||
else
|
||||
errno = map_errno(err);
|
||||
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pol) {
|
||||
wait = rb_w32_wait_events_blocking(&ol.hEvent, 1, INFINITE);
|
||||
if (wait != WAIT_OBJECT_0) {
|
||||
if (errno != EINTR)
|
||||
errno = map_errno(GetLastError());
|
||||
CloseHandle(ol.hEvent);
|
||||
cancel_io((HANDLE)_osfhnd(fd));
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!GetOverlappedResult((HANDLE)_osfhnd(fd), &ol, &written,
|
||||
TRUE)) {
|
||||
errno = map_errno(err);
|
||||
CloseHandle(ol.hEvent);
|
||||
cancel_io((HANDLE)_osfhnd(fd));
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pol) {
|
||||
CloseHandle(ol.hEvent);
|
||||
|
||||
if (!(_osfile(fd) & (FDEV | FPIPE))) {
|
||||
LONG high = ol.OffsetHigh;
|
||||
LONG low = ol.Offset + written;
|
||||
if (low < ol.Offset)
|
||||
++high;
|
||||
SetFilePointer((HANDLE)_osfhnd(fd), low, &high, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
Loading…
Add table
Reference in a new issue