diff --git a/io.c b/io.c index c3fb3e4..f482bfe 100644 --- a/io.c +++ b/io.c @@ -468,6 +468,9 @@ io_fwrite(str, fptr) { long len, n, r, l, offset = 0; FILE *f = GetWriteFile(fptr); +#if BSD_STDIO + off_t cur_offset; +#endif len = RSTRING(str)->len; if ((n = len) <= 0) return n; @@ -488,7 +491,19 @@ io_fwrite(str, fptr) r = write(fileno(f), RSTRING(str)->ptr+offset, l); TRAP_END; #if BSD_STDIO - fseeko(f, lseek(fileno(f), (off_t)0, SEEK_CUR), SEEK_SET); + if (r > 0) { + cur_offset = lseek(fileno(f), (off_t)0, SEEK_CUR); + if (cur_offset != -1) { + if (fseeko(f, cur_offset, SEEK_SET) == -1) + /* Raise fseeko's error. */ + r = -1; + } + else if (errno != ESPIPE) { + /* Raise lseek's error. */ + r = -1; + } + /* else if (errno == ESPIPE) ignore error */ + } #endif if (r == n) return len; if (0 <= r) { diff --git a/test/io/test_write.rb b/test/io/test_write.rb new file mode 100644 index 0000000..a46e50e --- /dev/null +++ b/test/io/test_write.rb @@ -0,0 +1,16 @@ +require 'test/unit' + +class TestIOWrite < Test::Unit::TestCase + def test_write + a, b = IO.pipe + begin + a.close + assert_raises(Errno::EPIPE) do + b.write("hi") + end + ensure + a.close if !a.closed? + b.close if !b.closed? + end + end +end