/*
* call-seq:
* IO.copy_stream(src, dst)
* IO.copy_stream(src, dst, copy_length)
* IO.copy_stream(src, dst, copy_length, src_offset)
*
* IO.copy_stream copies <i>src</i> to <i>dst</i>.
* <i>src</i> and <i>dst</i> is either a filename or an IO.
*
* This method returns the number of bytes copied.
*
* If optional arguments are not given,
* the start position of the copy is
* the beginning of the filename or
* the current file offset of the IO.
* The end position of the copy is the end of file.
*
* If <i>copy_length</i> is given,
* No more than <i>copy_length</i> bytes are copied.
*
* If <i>src_offset</i> is given,
* it specifies the start position of the copy.
*
* When <i>src_offset</i> is specified and
* <i>src</i> is an IO,
* IO.copy_stream doesn't move the current file offset.
*
*/
static VALUE
rb_io_s_copy_stream(int argc, VALUE *argv, VALUE io)
{
VALUE src, dst, length, src_offset;
struct copy_stream_struct st;
MEMZERO(&st, struct copy_stream_struct, 1);
rb_scan_args(argc, argv, "22", &src, &dst, &length, &src_offset);
st.src = src;
st.dst = dst;
if (NIL_P(length))
st.copy_length = (off_t)-1;
else
st.copy_length = NUM2OFFT(length);
if (NIL_P(src_offset))
st.src_offset = (off_t)-1;
else
st.src_offset = NUM2OFFT(src_offset);
rb_ensure(copy_stream_body, (VALUE)&st, copy_stream_finalize, (VALUE)&st);
return OFFT2NUM(st.total);
}