33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'ext/socket_helper/socket_helper.c', line 33
static VALUE
rb_socket_read_in_full(int argc, VALUE *argv, VALUE self)
{
rb_io_t *fptr;
VALUE rb_sock, rb_buffer, rb_klass;
struct recv_args arg;
long buflen;
VALUE len, flg;
rb_scan_args(argc, argv, "21", &rb_sock, &len, &flg);
if (flg == Qnil)
arg.flags = 0;
else
arg.flags = NUM2INT(flg);
buflen = NUM2INT(len);
GetOpenFile(rb_sock, fptr);
if (rb_io_read_pending(fptr)) {
rb_raise(rb_eIOError, "recv for buffered IO");
}
arg.fd = fptr->fd;
arg.pos = 0;
arg.buffer = rb_buffer = rb_tainted_str_new(0, buflen);
rb_klass = RBASIC(rb_buffer)->klass;
rb_obj_hide(rb_buffer);
while (arg.pos < buflen) {
long slen;
rb_io_check_closed(fptr);
slen = BLOCKING_REGION_FD(recv_loop, &arg);
if (!slen)
break;
if (slen < 0 && !rb_io_wait_readable(fptr->fd))
rb_sys_fail("recv(2)");
}
rb_obj_reveal(rb_buffer, rb_klass);
if (arg.pos < buflen)
rb_raise(rb_eRuntimeError, "connection closed");
rb_obj_taint(rb_buffer);
return rb_buffer;
}
|