My apologies for sending a bad patch. This is the correct one. Comments
appreciated. I'll report back if I hear anything from Sun on this issue.

Index: io.c
===================================================================
RCS file: /src/ruby/io.c,v
retrieving revision 1.167
diff -u -r1.167 io.c
--- io.c	29 Oct 2002 21:35:28 -0000	1.167
+++ io.c	6 Nov 2002 19:32:24 -0000
@@ -24,6 +24,11 @@
 #include <ctype.h>
 #include <errno.h>
 
+#if defined(sun)
+# define BROKEN_FWRITE
+# include <signal.h>
+#endif
+
 #if defined(MSDOS) || defined(__BOW__) || defined(__CYGWIN__) || defined(NT) || defined(__human68k__) || defined(__EMX__) || defined(__BEOS__)
 # define NO_SAFE_RENAME
 #endif
@@ -359,6 +364,9 @@
     FILE *f;
     long n, r;
     register char *ptr;
+#ifdef BROKEN_FWRITE
+    sigset_t set;
+#endif
 
     rb_secure(4);
     if (TYPE(str) != T_STRING)
@@ -384,7 +392,20 @@
 	}
     } while (--n > 0);
 #else
-    while (ptr += (r = fwrite(ptr, 1, n, f)), (n -= r) > 0) {
+#ifdef BROKEN_FWRITE
+    /* Prevent the fwrite() from being interrupted by a VTALRM signal */
+    sigemptyset(&set);
+    sigaddset(&set, SIGVTALRM);
+#endif
+    for (;;) {
+#ifdef BROKEN_FWRITE
+	sigprocmask(SIG_BLOCK, &set, 0);
+#endif
+	ptr += (r = fwrite(ptr, 1, n, f));
+#ifdef BROKEN_FWRITE
+	sigprocmask(SIG_UNBLOCK, &set, 0);
+#endif
+	if ((n -= r) <= 0) break;
 	if (ferror(f)) {
 	    if (rb_io_wait_writable(fileno(f))) {
 		clearerr(f);

-- 
Jos Backus                       _/  _/_/_/      Sunnyvale, CA
                                _/  _/   _/
                               _/  _/_/_/
                          _/  _/  _/    _/
jos at catnook.com        _/_/   _/_/_/          require 'std/disclaimer'