diff --git a/ChangeLog b/ChangeLog
index 4b0ae6198f..b6f99da2c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Jun 18 18:31:03 2008  NAKAMURA Usaku  <usa@ruby-lang.org>
+
+	* win32/win32.c (errmap): add some pipe errors.
+
+	* win32/win32.c (rb_w32_write): set errno when CRT's errno is EINVAL
+	  for pipe errors.
+
 Wed Jun 18 18:09:08 2008  NAKAMURA Usaku  <usa@ruby-lang.org>
 
 	* win32/win32.c (poll_child_status): set EINVAL to errno when
diff --git a/win32/win32.c b/win32/win32.c
index 813c4ee191..1d6b7c0eed 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -156,6 +156,14 @@ static struct {
     {	ERROR_INFLOOP_IN_RELOC_CHAIN,	ENOEXEC		},
     {	ERROR_FILENAME_EXCED_RANGE,	ENOENT		},
     {	ERROR_NESTING_NOT_ALLOWED,	EAGAIN		},
+#ifndef ERROR_PIPE_LOCAL
+#define ERROR_PIPE_LOCAL	229L
+#endif
+    {	ERROR_PIPE_LOCAL,		EPIPE		},
+    {	ERROR_BAD_PIPE,			EPIPE		},
+    {	ERROR_PIPE_BUSY,		EAGAIN		},
+    {	ERROR_NO_DATA,			EPIPE		},
+    {	ERROR_PIPE_NOT_CONNECTED,	EPIPE		},
     {	ERROR_NOT_ENOUGH_QUOTA,		ENOMEM		},
     {	WSAENAMETOOLONG,		ENAMETOOLONG	},
     {	WSAENOTEMPTY,			ENOTEMPTY	},
@@ -3873,8 +3881,12 @@ rb_w32_write(int fd, const void *buf, size_t size)
 {
     SOCKET sock = TO_SOCKET(fd);
 
-    if (!is_socket(sock))
-	return write(fd, buf, size);
+    if (!is_socket(sock)) {
+	size_t ret = write(fd, buf, size);
+	if ((int)ret < 0 && errno == EINVAL)
+	    errno = map_errno(GetLastError());
+	return ret;
+    }
     else
 	return rb_w32_send(fd, buf, size, 0);
 }