Re: io_write()/fwrite() and EINTR on Solaris
From:
Jos Backus <jos@...>
Date:
2002-11-06 19:35:06 UTC
List:
ruby-core #565
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'