add kgio_read! methods which may raise EOFError
[kgio.git] / ext / kgio / read_write.c
blob7466c914033dc2b0efd0a2766f00433b749fdf26
1 #include "kgio.h"
2 static VALUE mKgio_WaitReadable, mKgio_WaitWritable;
4 /*
5 * we know MSG_DONTWAIT works properly on all stream sockets under Linux
6 * we can define this macro for other platforms as people care and
7 * notice.
8 */
9 #if defined(__linux__) && ! defined(USE_MSG_DONTWAIT)
10 # define USE_MSG_DONTWAIT
11 #endif
13 NORETURN(static void my_eof_error(void));
15 static void my_eof_error(void)
17 VALUE exc = rb_exc_new2(rb_eEOFError, "");
18 VALUE bt = rb_ary_new();
20 rb_funcall(exc, rb_intern("set_backtrace"), 1, bt);
21 rb_exc_raise(exc);
24 static void prepare_read(struct io_args *a, int argc, VALUE *argv, VALUE io)
26 VALUE length;
28 a->io = io;
29 a->fd = my_fileno(io);
30 rb_scan_args(argc, argv, "11", &length, &a->buf);
31 a->len = NUM2LONG(length);
32 if (NIL_P(a->buf)) {
33 a->buf = rb_str_new(NULL, a->len);
34 } else {
35 StringValue(a->buf);
36 rb_str_resize(a->buf, a->len);
38 a->ptr = RSTRING_PTR(a->buf);
41 static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
43 if (n == -1) {
44 if (errno == EINTR)
45 return -1;
46 rb_str_set_len(a->buf, 0);
47 if (errno == EAGAIN) {
48 if (io_wait) {
49 kgio_wait_readable(a->io, a->fd);
51 /* buf may be modified in other thread/fiber */
52 rb_str_resize(a->buf, a->len);
53 a->ptr = RSTRING_PTR(a->buf);
54 return -1;
55 } else {
56 a->buf = mKgio_WaitReadable;
57 return 0;
60 rb_sys_fail(msg);
62 rb_str_set_len(a->buf, n);
63 if (n == 0)
64 a->buf = Qnil;
65 return 0;
68 static VALUE my_read(int io_wait, int argc, VALUE *argv, VALUE io)
70 struct io_args a;
71 long n;
73 prepare_read(&a, argc, argv, io);
74 set_nonblocking(a.fd);
75 retry:
76 n = (long)read(a.fd, a.ptr, a.len);
77 if (read_check(&a, n, "read", io_wait) != 0)
78 goto retry;
79 return a.buf;
83 * call-seq:
85 * io.kgio_read(maxlen) -> buffer
86 * io.kgio_read(maxlen, buffer) -> buffer
88 * Reads at most maxlen bytes from the stream socket. Returns with a
89 * newly allocated buffer, or may reuse an existing buffer if supplied.
91 * Calls the method assigned to Kgio.wait_readable, or blocks in a
92 * thread-safe manner for writability.
94 * Returns nil on EOF.
96 * This behaves like read(2) and IO#readpartial, NOT fread(3) or
97 * IO#read which possess read-in-full behavior.
99 static VALUE kgio_read(int argc, VALUE *argv, VALUE io)
101 return my_read(1, argc, argv, io);
105 * Same as Kgio::PipeMethods#kgio_read, except EOFError is raised
106 * on EOF without a backtrace
108 static VALUE kgio_read_bang(int argc, VALUE *argv, VALUE io)
110 VALUE rv = my_read(1, argc, argv, io);
112 if (NIL_P(rv)) my_eof_error();
113 return rv;
117 * call-seq:
119 * io.kgio_tryread(maxlen) -> buffer
120 * io.kgio_tryread(maxlen, buffer) -> buffer
122 * Reads at most maxlen bytes from the stream socket. Returns with a
123 * newly allocated buffer, or may reuse an existing buffer if supplied.
125 * Returns nil on EOF.
127 * Returns Kgio::WaitReadable if EAGAIN is encountered.
129 static VALUE kgio_tryread(int argc, VALUE *argv, VALUE io)
131 return my_read(0, argc, argv, io);
134 #ifdef USE_MSG_DONTWAIT
135 static VALUE my_recv(int io_wait, int argc, VALUE *argv, VALUE io)
137 struct io_args a;
138 long n;
140 prepare_read(&a, argc, argv, io);
141 retry:
142 n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT);
143 if (read_check(&a, n, "recv", io_wait) != 0)
144 goto retry;
145 return a.buf;
149 * This method may be optimized on some systems (e.g. GNU/Linux) to use
150 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
151 * Otherwise this is the same as Kgio::PipeMethods#kgio_read
153 static VALUE kgio_recv(int argc, VALUE *argv, VALUE io)
155 return my_recv(1, argc, argv, io);
159 * Same as Kgio::SocketMethods#kgio_read, except EOFError is raised
160 * on EOF without a backtrace
162 static VALUE kgio_recv_bang(int argc, VALUE *argv, VALUE io)
164 VALUE rv = my_recv(1, argc, argv, io);
166 if (NIL_P(rv)) my_eof_error();
167 return rv;
171 * This method may be optimized on some systems (e.g. GNU/Linux) to use
172 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
173 * Otherwise this is the same as Kgio::PipeMethods#kgio_tryread
175 static VALUE kgio_tryrecv(int argc, VALUE *argv, VALUE io)
177 return my_recv(0, argc, argv, io);
179 #else /* ! USE_MSG_DONTWAIT */
180 # define kgio_recv kgio_read
181 # define kgio_recv_bang kgio_read_bang
182 # define kgio_tryrecv kgio_tryread
183 #endif /* USE_MSG_DONTWAIT */
185 static void prepare_write(struct io_args *a, VALUE io, VALUE str)
187 a->buf = (TYPE(str) == T_STRING) ? str : rb_obj_as_string(str);
188 a->ptr = RSTRING_PTR(a->buf);
189 a->len = RSTRING_LEN(a->buf);
190 a->io = io;
191 a->fd = my_fileno(io);
194 static int write_check(struct io_args *a, long n, const char *msg, int io_wait)
196 if (a->len == n) {
197 done:
198 a->buf = Qnil;
199 } else if (n == -1) {
200 if (errno == EINTR)
201 return -1;
202 if (errno == EAGAIN) {
203 long written = RSTRING_LEN(a->buf) - a->len;
205 if (io_wait) {
206 kgio_wait_writable(a->io, a->fd);
208 /* buf may be modified in other thread/fiber */
209 a->len = RSTRING_LEN(a->buf) - written;
210 if (a->len <= 0)
211 goto done;
212 a->ptr = RSTRING_PTR(a->buf) + written;
213 return -1;
214 } else if (written > 0) {
215 a->buf = rb_str_new(a->ptr + n, a->len - n);
216 } else {
217 a->buf = mKgio_WaitWritable;
219 return 0;
221 rb_sys_fail(msg);
222 } else {
223 assert(n >= 0 && n < a->len && "write/send syscall broken?");
224 a->ptr += n;
225 a->len -= n;
226 return -1;
228 return 0;
231 static VALUE my_write(VALUE io, VALUE str, int io_wait)
233 struct io_args a;
234 long n;
236 prepare_write(&a, io, str);
237 set_nonblocking(a.fd);
238 retry:
239 n = (long)write(a.fd, a.ptr, a.len);
240 if (write_check(&a, n, "write", io_wait) != 0)
241 goto retry;
242 return a.buf;
246 * call-seq:
248 * io.kgio_write(str) -> nil
250 * Returns nil when the write completes.
252 * Calls the method Kgio.wait_writable if it is set. Otherwise this
253 * blocks in a thread-safe manner until all data is written or a
254 * fatal error occurs.
256 static VALUE kgio_write(VALUE io, VALUE str)
258 return my_write(io, str, 1);
262 * call-seq:
264 * io.kgio_trywrite(str) -> nil or Kgio::WaitWritable
266 * Returns nil if the write was completed in full.
268 * Returns a String containing the unwritten portion if EAGAIN
269 * was encountered, but some portion was successfully written.
271 * Returns Kgio::WaitWritable if EAGAIN is encountered and nothing
272 * was written.
274 static VALUE kgio_trywrite(VALUE io, VALUE str)
276 return my_write(io, str, 0);
279 #ifdef USE_MSG_DONTWAIT
281 * This method behaves like Kgio::PipeMethods#kgio_write, except
282 * it will use send(2) with the MSG_DONTWAIT flag on sockets to
283 * avoid unnecessary calls to fcntl(2).
285 static VALUE my_send(VALUE io, VALUE str, int io_wait)
287 struct io_args a;
288 long n;
290 prepare_write(&a, io, str);
291 retry:
292 n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT);
293 if (write_check(&a, n, "send", io_wait) != 0)
294 goto retry;
295 return a.buf;
299 * This method may be optimized on some systems (e.g. GNU/Linux) to use
300 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
301 * Otherwise this is the same as Kgio::PipeMethods#kgio_write
303 static VALUE kgio_send(VALUE io, VALUE str)
305 return my_send(io, str, 1);
309 * This method may be optimized on some systems (e.g. GNU/Linux) to use
310 * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
311 * Otherwise this is the same as Kgio::PipeMethods#kgio_trywrite
313 static VALUE kgio_trysend(VALUE io, VALUE str)
315 return my_send(io, str, 0);
317 #else /* ! USE_MSG_DONTWAIT */
318 # define kgio_send kgio_write
319 # define kgio_trysend kgio_trywrite
320 #endif /* ! USE_MSG_DONTWAIT */
322 void init_kgio_read_write(VALUE mKgio)
324 VALUE mPipeMethods, mSocketMethods;
326 mKgio_WaitReadable = rb_const_get(mKgio, rb_intern("WaitReadable"));
327 mKgio_WaitWritable = rb_const_get(mKgio, rb_intern("WaitWritable"));
330 * Document-module: Kgio::PipeMethods
332 * This module may be used used to create classes that respond to
333 * various Kgio methods for reading and writing. This is included
334 * in Kgio::Pipe by default.
336 mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
337 rb_define_method(mPipeMethods, "kgio_read", kgio_read, -1);
338 rb_define_method(mPipeMethods, "kgio_read!", kgio_read_bang, -1);
339 rb_define_method(mPipeMethods, "kgio_write", kgio_write, 1);
340 rb_define_method(mPipeMethods, "kgio_tryread", kgio_tryread, -1);
341 rb_define_method(mPipeMethods, "kgio_trywrite", kgio_trywrite, 1);
344 * Document-module: Kgio::SocketMethods
346 * This method behaves like Kgio::PipeMethods, but contains
347 * optimizations for sockets on certain operating systems
348 * (e.g. GNU/Linux).
350 mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
351 rb_define_method(mSocketMethods, "kgio_read", kgio_recv, -1);
352 rb_define_method(mSocketMethods, "kgio_read!", kgio_recv_bang, -1);
353 rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1);
354 rb_define_method(mSocketMethods, "kgio_tryread", kgio_tryrecv, -1);
355 rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1);
358 * Returns the client IPv4 address of the socket in dotted quad
359 * form as a string. This is always the value of the
360 * Kgio::LOCALHOST constant for UNIX domain sockets.
362 rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);