summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-10 10:42:19 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-11-10 10:42:19 +0000
commitfd9f6bde957ce681fed49182be02124ecc89b362 (patch)
treead4a0c12e80ad4ca7c60d6dd8c18be960d5dde8c /win32
parent6ccf3d68c21c2eabefe80f9ff1f7b5296a9ddfd2 (diff)
* win32/win32.c, include/win32/win32.h (rb_w32_set_nonblock): new
function to support nonblock-mode of pipes. * win32/win32.c (rb_w32_read): nonblock-mode pipe returns ERROR_NO_DATA if there is no data, but also returns it if remote-end is closed. * win32/win32.c (rb_w32_write): if cannot to write any data, it may be blocking. * io.c (rb_io_set_nonblock): use rb_w32_set_nonblock for Windows. * ext/io/nonblock/nonblock.c (rb_io_nonblock_set): use ruby's API when setting nonblock-mode. * test/ruby/test_io.rb: test nonblock pipes on Windows. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48361 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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));