diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-05-24 23:27:14 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-05-24 23:27:14 -0700 |
commit | bde5844909cd61ecfa3393fba4e9884c083f2fa8 (patch) | |
tree | aac869f82fe13e0f91ee110e9e6fe9849b86a308 /ext/io_splice | |
parent | c405321e8df7ff71417cc0b6f7b0624e18970655 (diff) | |
download | ruby_io_splice-bde5844909cd61ecfa3393fba4e9884c083f2fa8.tar.gz |
Diffstat (limited to 'ext/io_splice')
-rw-r--r-- | ext/io_splice/io_splice_ext.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/ext/io_splice/io_splice_ext.c b/ext/io_splice/io_splice_ext.c index 0679273..69c0288 100644 --- a/ext/io_splice/io_splice_ext.c +++ b/ext/io_splice/io_splice_ext.c @@ -223,6 +223,28 @@ static VALUE nogvl_vmsplice(void *ptr) return (VALUE)vmsplice(a->fd, a->iov, a->nr_segs, a->flags); } +/* this can't be a function since we use alloca() */ +#define ARY2IOVEC(iov,iovcnt,expect,ary) \ +do { \ + VALUE *cur; \ + struct iovec *tmp; \ + long n; \ + Check_Type(ary, T_ARRAY); \ + cur = RARRAY_PTR(ary); \ + n = RARRAY_LEN(ary); \ + if (n > IOV_MAX) \ + rb_raise(rb_eArgError, "array is larger than IOV_MAX"); \ + iov = tmp = alloca(sizeof(struct iovec) * n); \ + expect = 0; \ + iovcnt = n; \ + for (; --n >= 0; tmp++, cur++) { \ + Check_Type(*cur, T_STRING); \ + tmp->iov_base = RSTRING_PTR(*cur); \ + tmp->iov_len = RSTRING_LEN(*cur); \ + expect += tmp->iov_len; \ + } \ +} while (0) + /* * call-seq: * IO.vmsplice(fd, string_array, flags) => integer @@ -239,32 +261,10 @@ static VALUE nogvl_vmsplice(void *ptr) static VALUE my_vmsplice(VALUE self, VALUE fd, VALUE data, VALUE flags) { long n; + ssize_t left; struct vmsplice_args a; - struct iovec *tmp; - VALUE *ary; - - switch (TYPE(data)) { - case T_ARRAY: - ary = RARRAY_PTR(data); - a.nr_segs = RARRAY_LEN(data); - - if (a.nr_segs > IOV_MAX) - rb_raise(rb_eArgError, "array larger than IOV_MAX"); - - a.iov = tmp = alloca(sizeof(struct iovec) * a.nr_segs); - - for (n = (long)a.nr_segs; --n >= 0; tmp++, ary++) { - if (TYPE(*ary) != T_STRING) - rb_raise(rb_eArgError, - "must be an array of strings"); - tmp->iov_base = RSTRING_PTR(*ary); - tmp->iov_len = RSTRING_LEN(*ary); - } - break; - default: - rb_raise(rb_eArgError, "must be an array of strings"); - } + ARY2IOVEC(a.iov, a.nr_segs, left, data); a.fd = NUM2INT(fd); a.flags = NUM2UINT(flags); |