山本です。

>これだと本当のエラーまで隠してしまって、まずそうです。

と書きましたが、win32/win32.c(rb_w32_getc) では既に EPIPE ==> EOF とみなして
いる様なので、fread でも同じようにしてみました
(bcc32 と wince で rb_w32_fread を定義しました)

 * win32/win32.c(rb_w32_fread): fread で errno == EPIPE となったときは、
   エラーフラグをクリアして、EOF フラグを立てる

Index: win32.h
===================================================================
RCS file: /var/cvs/src/ruby/win32/win32.h,v
retrieving revision 1.51
diff -u -w -b -p -r1.51 win32.h
--- win32.h	19 Feb 2004 09:08:23 -0000	1.51
+++ win32.h	21 Jun 2004 02:46:25 -0000
@@ -122,6 +122,11 @@ extern "C++" {
 #undef execv
 #define execv(path,argv)	rb_w32_aspawn(P_OVERLAY,path,argv)
 
+#if defined __BORLANDC__ || _WIN32_WCE
+#undef fread
+#define fread(p, m, n, stream)	rb_w32_fread(p, m, n, stream)
+#endif
+
 #ifdef __MINGW32__
 struct timezone {
   int tz_minuteswest;

Index: win32.c
===================================================================
RCS file: /var/cvs/src/ruby/win32/win32.c,v
retrieving revision 1.117
diff -u -w -b -p -r1.117 win32.c
--- win32.c	21 Jun 2004 00:27:39 -0000	1.117
+++ win32.c	21 Jun 2004 03:12:44 -0000
@@ -3034,10 +3034,14 @@ rb_w32_getc(FILE* stream)
     else 
 #endif
     {
+#if defined __BORLANDC__ || defined _WIN32_WCE
+	errno = 0;
+#endif
 	c = _filbuf(stream);
 #if defined __BORLANDC__ || defined _WIN32_WCE
         if ((c == EOF) && (errno == EPIPE)) {
 	    clearerr(stream);
+	    stream->flags |= _F_EOF;
         }
 #endif
 	rb_trap_immediate = trap_immediate;
@@ -3065,6 +3069,22 @@ rb_w32_putc(int c, FILE* stream)
     }
     return c;
 }
+
+#if defined __BORLANDC__ || defined _WIN32_WCE
+#undef fread
+size_t
+rb_w32_fread(void *ptr, size_t size, size_t n, FILE *stream)
+{
+    size_t i;
+    errno = 0;
+    i = fread(ptr, size, n, stream);
+    if ((i < n) && (errno == EPIPE)) {
+	clearerr(stream);
+	stream->flags |= _F_EOF;
+    }
+    return i;
+}
+#endif
 
 struct asynchronous_arg_t {
     /* output field */