summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/win32/win32.c b/win32/win32.c
index 9f80d3228d..2661641266 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -4122,6 +4122,33 @@ fcntl(int fd, int cmd, ...)
}
}
+/* License: Ruby's */
+int
+rb_w32_set_nonblock(int fd)
+{
+ SOCKET sock = TO_SOCKET(fd);
+ if (is_socket(sock)) {
+ return setfl(sock, O_NONBLOCK);
+ }
+ else if (is_pipe(sock)) {
+ DWORD state;
+ if (!GetNamedPipeHandleState((HANDLE)sock, &state, NULL, NULL, NULL, NULL, 0)) {
+ errno = map_errno(GetLastError());
+ return -1;
+ }
+ state |= PIPE_NOWAIT;
+ if (!SetNamedPipeHandleState((HANDLE)sock, &state, NULL, NULL)) {
+ errno = map_errno(GetLastError());
+ return -1;
+ }
+ return 0;
+ }
+ else {
+ errno = EBADF;
+ return -1;
+ }
+}
+
#ifndef WNOHANG
#define WNOHANG -1
#endif
@@ -6354,7 +6381,18 @@ rb_w32_read(int fd, void *buf, size_t size)
if (!ReadFile((HANDLE)_osfhnd(fd), buf, len, &read, pol)) {
err = GetLastError();
- if (err != ERROR_IO_PENDING) {
+ if (err == ERROR_NO_DATA && (_osfile(fd) & FPIPE)) {
+ DWORD state;
+ if (GetNamedPipeHandleState((HANDLE)_osfhnd(fd), &state, NULL, NULL, NULL, NULL, 0) && (state & PIPE_NOWAIT)) {
+ errno = EWOULDBLOCK;
+ }
+ else {
+ errno = map_errno(err);
+ }
+ MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));
+ return -1;
+ }
+ else if (err != ERROR_IO_PENDING) {
if (pol) CloseHandle(ol.hEvent);
if (err == ERROR_ACCESS_DENIED)
errno = EBADF;
@@ -6517,6 +6555,10 @@ rb_w32_write(int fd, const void *buf, size_t size)
if (size > 0)
goto retry;
}
+ if (ret == 0) {
+ ret = -1;
+ errno = EWOULDBLOCK;
+ }
MTHREAD_ONLY(LeaveCriticalSection(&_pioinfo(fd)->lock));