1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

io.c: honor buffered mode

* io.c (io_writev): honor buffered mode to get rid of broken pipe
  error when stdout is redirected to a pipeline.
  [ruby-core:83578] [Feature #14042]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60535 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-10-29 05:46:23 +00:00
parent 85195203f4
commit 8354b6d2cd
2 changed files with 18 additions and 5 deletions

14
io.c
View file

@ -1637,12 +1637,16 @@ io_writev(int argc, VALUE *argv, VALUE io)
for (i = 0; i < argc; i += cnt) {
#ifdef HAVE_WRITEV
if ((cnt = argc - i) >= IOV_MAX) cnt = IOV_MAX-1;
n = io_fwritev(cnt, &argv[i], fptr);
#else
/* sync at last item */
n = io_fwrite(argv[i], fptr, (i < argc-1));
if ((fptr->mode & (FMODE_SYNC|FMODE_TTY)) && ((cnt = argc - i) < IOV_MAX)) {
n = io_fwritev(cnt, &argv[i], fptr);
}
else
#endif
{
cnt = 1;
/* sync at last item */
n = io_fwrite(rb_obj_as_string(argv[i]), fptr, (i < argc-1));
}
if (n == -1L) rb_sys_fail_path(fptr->pathv);
total = rb_fix_plus(LONG2FIX(n), total);
}

View file

@ -1274,6 +1274,15 @@ class TestIO < Test::Unit::TestCase
assert_in_out_err([], "STDOUT.write(:foo, :bar)", ["foobar"])
end
def test_write_buffered_with_multiple_arguments
out, err, (_, status) = EnvUtil.invoke_ruby(["-e", "sleep 0.1;puts 'foo'"], "", true, true) do |_, o, e, i|
[o.read, e.read, Process.waitpid2(i)]
end
assert_predicate(status, :success?)
assert_equal("foo\n", out)
assert_empty(err)
end
def test_write_non_writable
with_pipe do |r, w|
assert_raise(IOError) do