io.c: no restriction

* io.c (io_write_m): remove argc restriction upto IOV_MAX-1.
  [Feature #9323]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60370 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2017-10-23 02:25:58 +00:00
parent cb4a2a6113
commit c0f40369b6
2 changed files with 16 additions and 59 deletions

55
io.c
View File

@ -1593,10 +1593,6 @@ io_fwritev(int argc, VALUE *argv, rb_io_t *fptr)
VALUE v1, v2, str, tmp, *tmp_array; VALUE v1, v2, str, tmp, *tmp_array;
struct iovec *iov; struct iovec *iov;
if (iovcnt > IOV_MAX) {
rb_raise(rb_eArgError, "too many items (IOV_MAX: %d)", IOV_MAX);
}
iov = ALLOCV_N(struct iovec, v1, iovcnt); iov = ALLOCV_N(struct iovec, v1, iovcnt);
tmp_array = ALLOCV_N(VALUE, v2, argc); tmp_array = ALLOCV_N(VALUE, v2, argc);
@ -1625,13 +1621,15 @@ io_fwritev(int argc, VALUE *argv, rb_io_t *fptr)
return n; return n;
} }
#endif /* HAVE_WRITEV */
static VALUE static VALUE
io_writev(int argc, VALUE *argv, VALUE io) io_writev(int argc, VALUE *argv, VALUE io)
{ {
rb_io_t *fptr; rb_io_t *fptr;
long n; long n;
VALUE tmp; VALUE tmp, total = INT2FIX(0);
int i, cnt = 1;
io = GetWriteIO(io); io = GetWriteIO(io);
tmp = rb_io_check_io(io); tmp = rb_io_check_io(io);
@ -1644,48 +1642,20 @@ io_writev(int argc, VALUE *argv, VALUE io)
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
rb_io_check_writable(fptr); rb_io_check_writable(fptr);
n = io_fwritev(argc, argv, fptr); for (i = 0; i < argc; i += cnt) {
if (n == -1L) rb_sys_fail_path(fptr->pathv); #ifdef HAVE_WRITEV
if ((cnt = argc - i) >= IOV_MAX) cnt = IOV_MAX-1;
return LONG2FIX(n); n = io_fwritev(cnt, &argv[i], fptr);
}
#else #else
static VALUE
io_writev(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
long n;
VALUE str, tmp, total = INT2FIX(0);
int nosync;
int i;
io = GetWriteIO(io);
tmp = rb_io_check_io(io);
if (NIL_P(tmp)) {
/* port is not IO, call write method for it. */
return rb_funcallv(io, id_write, argc, argv);
}
io = tmp;
GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
for (i = 0; i < argc; i++) {
/* sync at last item */ /* sync at last item */
if (i == argc-1) n = io_fwrite(argv[i], fptr, (i < argc-1));
nosync = 0; #endif
else
nosync = 1;
str = argv[i];
n = io_fwrite(str, fptr, nosync);
if (n == -1L) rb_sys_fail_path(fptr->pathv); if (n == -1L) rb_sys_fail_path(fptr->pathv);
total = rb_fix_plus_fix(LONG2FIX(n), total); total = rb_fix_plus_fix(LONG2FIX(n), total);
} }
return total; return total;
} }
#endif /* HAVE_WRITEV */
/* /*
* call-seq: * call-seq:
@ -1708,13 +1678,6 @@ io_writev(int argc, VALUE *argv, VALUE io)
static VALUE static VALUE
io_write_m(int argc, VALUE *argv, VALUE io) io_write_m(int argc, VALUE *argv, VALUE io)
{ {
#ifdef HAVE_WRITEV
rb_check_arity(argc, 1, IOV_MAX-1);
#else
/* in many environments, IOV_MAX is 1024 */
rb_check_arity(argc, 1, 1023);
#endif
if (argc > 1) { if (argc > 1) {
return io_writev(argc, argv, io); return io_writev(argc, argv, io);
} }

View File

@ -1226,19 +1226,13 @@ class TestIO < Test::Unit::TestCase
end end
def test_write_with_many_arguments def test_write_with_many_arguments
pipe(proc do |w| [1023, 1024].each do |n|
w.write(*(["a"] * 1023)) pipe(proc do |w|
w.close w.write(*(["a"] * n))
end, proc do |r| w.close
assert_equal("a" * 1023, r.read) end, proc do |r|
end) assert_equal("a" * n, r.read)
end end)
def test_write_with_too_many_arguments
with_pipe do |r, w|
assert_raise(ArgumentError) do
w.write(*(["a"] * 1024))
end
end end
end end