kgio 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ #ifndef KGIO_H
2
+ #define KGIO_H
3
+
4
+ #include <ruby.h>
5
+ #ifdef HAVE_RUBY_IO_H
6
+ # include <ruby/io.h>
7
+ #else
8
+ # include <rubyio.h>
9
+ #endif
10
+ #include <errno.h>
11
+ #include <sys/types.h>
12
+ #include <sys/socket.h>
13
+ #include <sys/un.h>
14
+ #include <netinet/in.h>
15
+ #include <fcntl.h>
16
+ #include <unistd.h>
17
+ #include <arpa/inet.h>
18
+ #include <assert.h>
19
+
20
+ #include "missing/ancient_ruby.h"
21
+ #include "nonblock.h"
22
+ #include "my_fileno.h"
23
+
24
+ struct io_args {
25
+ VALUE io;
26
+ VALUE buf;
27
+ char *ptr;
28
+ long len;
29
+ int fd;
30
+ };
31
+
32
+ void init_kgio_wait(VALUE mKgio);
33
+ void init_kgio_read_write(VALUE mKgio);
34
+ void init_kgio_accept(VALUE mKgio);
35
+ void init_kgio_connect(VALUE mKgio);
36
+
37
+ void kgio_wait_writable(VALUE io, int fd);
38
+ void kgio_wait_readable(VALUE io, int fd);
39
+
40
+ #endif /* KGIO_H */
@@ -1,1095 +1,11 @@
1
- #include <ruby.h>
2
- #ifdef HAVE_RUBY_IO_H
3
- # include <ruby/io.h>
4
- #else
5
- # include <rubyio.h>
6
- #endif
7
- #include <errno.h>
8
- #include <sys/types.h>
9
- #include <sys/socket.h>
10
- #include <sys/un.h>
11
- #include <netinet/in.h>
12
- #include <fcntl.h>
13
- #include <unistd.h>
14
- #include <arpa/inet.h>
15
- #include <assert.h>
16
-
17
- #include "missing/accept4.h"
18
- #include "missing/ancient_ruby.h"
19
- #include "nonblock.h"
20
- #include "my_fileno.h"
21
- #include "sock_for_fd.h"
22
-
23
- #if defined(__linux__)
24
- /*
25
- * we know MSG_DONTWAIT works properly on all stream sockets under Linux
26
- * we can define this macro for other platforms as people care and
27
- * notice.
28
- */
29
- # define USE_MSG_DONTWAIT
30
- static int accept4_flags = A4_SOCK_CLOEXEC;
31
- #else /* ! linux */
32
- static int accept4_flags = A4_SOCK_CLOEXEC | A4_SOCK_NONBLOCK;
33
- #endif /* ! linux */
34
-
35
- static VALUE cClientSocket;
36
- static VALUE mSocketMethods;
37
- static VALUE cSocket;
38
- static VALUE localhost;
39
- static VALUE mKgio_WaitReadable, mKgio_WaitWritable;
40
- static ID io_wait_rd, io_wait_wr;
41
- static ID iv_kgio_addr;
42
-
43
- struct io_args {
44
- VALUE io;
45
- VALUE buf;
46
- char *ptr;
47
- long len;
48
- int fd;
49
- };
50
-
51
- struct accept_args {
52
- int fd;
53
- struct sockaddr *addr;
54
- socklen_t *addrlen;
55
- };
56
-
57
- static void wait_readable(VALUE io, int fd)
58
- {
59
- if (io_wait_rd) {
60
- (void)rb_funcall(io, io_wait_rd, 0, 0);
61
- } else {
62
- if (!rb_io_wait_readable(fd))
63
- rb_sys_fail("wait readable");
64
- }
65
- }
66
-
67
- static void wait_writable(VALUE io, int fd)
68
- {
69
- if (io_wait_wr) {
70
- (void)rb_funcall(io, io_wait_wr, 0, 0);
71
- } else {
72
- if (!rb_io_wait_writable(fd))
73
- rb_sys_fail("wait writable");
74
- }
75
- }
76
-
77
- static void prepare_read(struct io_args *a, int argc, VALUE *argv, VALUE io)
78
- {
79
- VALUE length;
80
-
81
- a->io = io;
82
- a->fd = my_fileno(io);
83
- rb_scan_args(argc, argv, "11", &length, &a->buf);
84
- a->len = NUM2LONG(length);
85
- if (NIL_P(a->buf)) {
86
- a->buf = rb_str_new(NULL, a->len);
87
- } else {
88
- StringValue(a->buf);
89
- rb_str_resize(a->buf, a->len);
90
- }
91
- a->ptr = RSTRING_PTR(a->buf);
92
- }
93
-
94
- static int read_check(struct io_args *a, long n, const char *msg, int io_wait)
95
- {
96
- if (n == -1) {
97
- if (errno == EINTR)
98
- return -1;
99
- rb_str_set_len(a->buf, 0);
100
- if (errno == EAGAIN) {
101
- if (io_wait) {
102
- wait_readable(a->io, a->fd);
103
-
104
- /* buf may be modified in other thread/fiber */
105
- rb_str_resize(a->buf, a->len);
106
- a->ptr = RSTRING_PTR(a->buf);
107
- return -1;
108
- } else {
109
- a->buf = mKgio_WaitReadable;
110
- return 0;
111
- }
112
- }
113
- rb_sys_fail(msg);
114
- }
115
- rb_str_set_len(a->buf, n);
116
- if (n == 0)
117
- a->buf = Qnil;
118
- return 0;
119
- }
120
-
121
- static VALUE my_read(int io_wait, int argc, VALUE *argv, VALUE io)
122
- {
123
- struct io_args a;
124
- long n;
125
-
126
- prepare_read(&a, argc, argv, io);
127
- set_nonblocking(a.fd);
128
- retry:
129
- n = (long)read(a.fd, a.ptr, a.len);
130
- if (read_check(&a, n, "read", io_wait) != 0)
131
- goto retry;
132
- return a.buf;
133
- }
134
-
135
- /*
136
- * call-seq:
137
- *
138
- * io.kgio_read(maxlen) -> buffer
139
- * io.kgio_read(maxlen, buffer) -> buffer
140
- *
141
- * Reads at most maxlen bytes from the stream socket. Returns with a
142
- * newly allocated buffer, or may reuse an existing buffer if supplied.
143
- *
144
- * Calls the method assigned to Kgio.wait_readable, or blocks in a
145
- * thread-safe manner for writability.
146
- *
147
- * Returns nil on EOF.
148
- *
149
- * This behaves like read(2) and IO#readpartial, NOT fread(3) or
150
- * IO#read which possess read-in-full behavior.
151
- */
152
- static VALUE kgio_read(int argc, VALUE *argv, VALUE io)
153
- {
154
- return my_read(1, argc, argv, io);
155
- }
156
-
157
- /*
158
- * call-seq:
159
- *
160
- * io.kgio_tryread(maxlen) -> buffer
161
- * io.kgio_tryread(maxlen, buffer) -> buffer
162
- *
163
- * Reads at most maxlen bytes from the stream socket. Returns with a
164
- * newly allocated buffer, or may reuse an existing buffer if supplied.
165
- *
166
- * Returns nil on EOF.
167
- *
168
- * Returns Kgio::WaitReadable if EAGAIN is encountered.
169
- */
170
- static VALUE kgio_tryread(int argc, VALUE *argv, VALUE io)
171
- {
172
- return my_read(0, argc, argv, io);
173
- }
174
-
175
- #ifdef USE_MSG_DONTWAIT
176
- static VALUE my_recv(int io_wait, int argc, VALUE *argv, VALUE io)
177
- {
178
- struct io_args a;
179
- long n;
180
-
181
- prepare_read(&a, argc, argv, io);
182
- retry:
183
- n = (long)recv(a.fd, a.ptr, a.len, MSG_DONTWAIT);
184
- if (read_check(&a, n, "recv", io_wait) != 0)
185
- goto retry;
186
- return a.buf;
187
- }
188
-
189
- /*
190
- * This method may be optimized on some systems (e.g. GNU/Linux) to use
191
- * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
192
- * Otherwise this is the same as Kgio::PipeMethods#kgio_read
193
- */
194
- static VALUE kgio_recv(int argc, VALUE *argv, VALUE io)
195
- {
196
- return my_recv(1, argc, argv, io);
197
- }
198
-
199
- /*
200
- * This method may be optimized on some systems (e.g. GNU/Linux) to use
201
- * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
202
- * Otherwise this is the same as Kgio::PipeMethods#kgio_tryread
203
- */
204
- static VALUE kgio_tryrecv(int argc, VALUE *argv, VALUE io)
205
- {
206
- return my_recv(0, argc, argv, io);
207
- }
208
- #else /* ! USE_MSG_DONTWAIT */
209
- # define kgio_recv kgio_read
210
- # define kgio_tryrecv kgio_tryread
211
- #endif /* USE_MSG_DONTWAIT */
212
-
213
- static void prepare_write(struct io_args *a, VALUE io, VALUE str)
214
- {
215
- a->buf = (TYPE(str) == T_STRING) ? str : rb_obj_as_string(str);
216
- a->ptr = RSTRING_PTR(a->buf);
217
- a->len = RSTRING_LEN(a->buf);
218
- a->io = io;
219
- a->fd = my_fileno(io);
220
- }
221
-
222
- static int write_check(struct io_args *a, long n, const char *msg, int io_wait)
223
- {
224
- if (a->len == n) {
225
- done:
226
- a->buf = Qnil;
227
- } else if (n == -1) {
228
- if (errno == EINTR)
229
- return -1;
230
- if (errno == EAGAIN) {
231
- if (io_wait) {
232
- long written = RSTRING_LEN(a->buf) - a->len;
233
-
234
- wait_writable(a->io, a->fd);
235
-
236
- /* buf may be modified in other thread/fiber */
237
- a->len = RSTRING_LEN(a->buf) - written;
238
- if (a->len <= 0)
239
- goto done;
240
- a->ptr = RSTRING_PTR(a->buf) + written;
241
- return -1;
242
- } else {
243
- a->buf = mKgio_WaitWritable;
244
- return 0;
245
- }
246
- }
247
- rb_sys_fail(msg);
248
- } else {
249
- assert(n >= 0 && n < a->len && "write/send syscall broken?");
250
- if (io_wait) {
251
- a->ptr += n;
252
- a->len -= n;
253
- return -1;
254
- }
255
- a->buf = rb_str_new(a->ptr + n, a->len - n);
256
- }
257
- return 0;
258
- }
259
-
260
- static VALUE my_write(VALUE io, VALUE str, int io_wait)
261
- {
262
- struct io_args a;
263
- long n;
264
-
265
- prepare_write(&a, io, str);
266
- set_nonblocking(a.fd);
267
- retry:
268
- n = (long)write(a.fd, a.ptr, a.len);
269
- if (write_check(&a, n, "write", io_wait) != 0)
270
- goto retry;
271
- return a.buf;
272
- }
273
-
274
- /*
275
- * call-seq:
276
- *
277
- * io.kgio_write(str) -> nil
278
- *
279
- * Returns nil when the write completes.
280
- *
281
- * Calls the method Kgio.wait_writable if it is set. Otherwise this
282
- * blocks in a thread-safe manner until all data is written or a
283
- * fatal error occurs.
284
- */
285
- static VALUE kgio_write(VALUE io, VALUE str)
286
- {
287
- return my_write(io, str, 1);
288
- }
289
-
290
- /*
291
- * call-seq:
292
- *
293
- * io.kgio_trywrite(str) -> nil or Kgio::WaitWritable
294
- *
295
- * Returns nil if the write was completed in full.
296
- *
297
- * Returns a String containing the unwritten portion if there was a
298
- * partial write.
299
- *
300
- * Returns Kgio::WaitWritable if EAGAIN is encountered.
301
- */
302
- static VALUE kgio_trywrite(VALUE io, VALUE str)
303
- {
304
- return my_write(io, str, 0);
305
- }
306
-
307
- #ifdef USE_MSG_DONTWAIT
308
- /*
309
- * This method behaves like Kgio::PipeMethods#kgio_write, except
310
- * it will use send(2) with the MSG_DONTWAIT flag on sockets to
311
- * avoid unnecessary calls to fcntl(2).
312
- */
313
- static VALUE my_send(VALUE io, VALUE str, int io_wait)
314
- {
315
- struct io_args a;
316
- long n;
317
-
318
- prepare_write(&a, io, str);
319
- retry:
320
- n = (long)send(a.fd, a.ptr, a.len, MSG_DONTWAIT);
321
- if (write_check(&a, n, "send", io_wait) != 0)
322
- goto retry;
323
- return a.buf;
324
- }
325
-
326
- /*
327
- * This method may be optimized on some systems (e.g. GNU/Linux) to use
328
- * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
329
- * Otherwise this is the same as Kgio::PipeMethods#kgio_write
330
- */
331
- static VALUE kgio_send(VALUE io, VALUE str)
332
- {
333
- return my_send(io, str, 1);
334
- }
335
-
336
- /*
337
- * This method may be optimized on some systems (e.g. GNU/Linux) to use
338
- * MSG_DONTWAIT to avoid explicitly setting the O_NONBLOCK flag via fcntl.
339
- * Otherwise this is the same as Kgio::PipeMethods#kgio_trywrite
340
- */
341
- static VALUE kgio_trysend(VALUE io, VALUE str)
342
- {
343
- return my_send(io, str, 0);
344
- }
345
- #else /* ! USE_MSG_DONTWAIT */
346
- # define kgio_send kgio_write
347
- # define kgio_trysend kgio_trywrite
348
- #endif /* ! USE_MSG_DONTWAIT */
349
-
350
- /*
351
- * call-seq:
352
- *
353
- * Kgio.wait_readable = :method_name
354
- * Kgio.wait_readable = nil
355
- *
356
- * Sets a method for kgio_read to call when a read would block.
357
- * This is useful for non-blocking frameworks that use Fibers,
358
- * as the method referred to this may cause the current Fiber
359
- * to yield execution.
360
- *
361
- * A special value of nil will cause Ruby to wait using the
362
- * rb_io_wait_readable() function.
363
- */
364
- static VALUE set_wait_rd(VALUE mod, VALUE sym)
365
- {
366
- switch (TYPE(sym)) {
367
- case T_SYMBOL:
368
- io_wait_rd = SYM2ID(sym);
369
- return sym;
370
- case T_NIL:
371
- io_wait_rd = 0;
372
- return sym;
373
- }
374
- rb_raise(rb_eTypeError, "must be a symbol or nil");
375
- return sym;
376
- }
377
-
378
- /*
379
- * call-seq:
380
- *
381
- * Kgio.wait_writable = :method_name
382
- * Kgio.wait_writable = nil
383
- *
384
- * Sets a method for kgio_write to call when a read would block.
385
- * This is useful for non-blocking frameworks that use Fibers,
386
- * as the method referred to this may cause the current Fiber
387
- * to yield execution.
388
- *
389
- * A special value of nil will cause Ruby to wait using the
390
- * rb_io_wait_writable() function.
391
- */
392
- static VALUE set_wait_wr(VALUE mod, VALUE sym)
393
- {
394
- switch (TYPE(sym)) {
395
- case T_SYMBOL:
396
- io_wait_wr = SYM2ID(sym);
397
- return sym;
398
- case T_NIL:
399
- io_wait_wr = 0;
400
- return sym;
401
- }
402
- rb_raise(rb_eTypeError, "must be a symbol or nil");
403
- return sym;
404
- }
405
-
406
- /*
407
- * call-seq:
408
- *
409
- * Kgio.wait_writable -> Symbol or nil
410
- *
411
- * Returns the symbolic method name of the method assigned to
412
- * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_write
413
- * or Kgio::SocketMethods#kgio_write call
414
- */
415
- static VALUE wait_wr(VALUE mod)
416
- {
417
- return io_wait_wr ? ID2SYM(io_wait_wr) : Qnil;
418
- }
419
-
420
- /*
421
- * call-seq:
422
- *
423
- * Kgio.wait_readable -> Symbol or nil
424
- *
425
- * Returns the symbolic method name of the method assigned to
426
- * call when EAGAIN is occurs on a Kgio::PipeMethods#kgio_read
427
- * or Kgio::SocketMethods#kgio_read call.
428
- */
429
- static VALUE wait_rd(VALUE mod)
430
- {
431
- return io_wait_rd ? ID2SYM(io_wait_rd) : Qnil;
432
- }
433
-
434
- static VALUE xaccept(void *ptr)
435
- {
436
- struct accept_args *a = ptr;
437
-
438
- return (VALUE)accept4(a->fd, a->addr, a->addrlen, accept4_flags);
439
- }
440
-
441
- #ifdef HAVE_RB_THREAD_BLOCKING_REGION
442
- # include <time.h>
443
- /*
444
- * Try to use a (real) blocking accept() since that can prevent
445
- * thundering herds under Linux:
446
- * http://www.citi.umich.edu/projects/linux-scalability/reports/accept.html
447
- *
448
- * So we periodically disable non-blocking, but not too frequently
449
- * because other processes may set non-blocking (especially during
450
- * a process upgrade) with Rainbows! concurrency model changes.
451
- */
452
- static int thread_accept(struct accept_args *a, int force_nonblock)
453
- {
454
- if (force_nonblock)
455
- set_nonblocking(a->fd);
456
- return (int)rb_thread_blocking_region(xaccept, a, RUBY_UBF_IO, 0);
457
- }
458
-
459
- static void set_blocking_or_block(int fd)
460
- {
461
- static time_t last_set_blocking;
462
- time_t now = time(NULL);
463
-
464
- if (last_set_blocking == 0) {
465
- last_set_blocking = now;
466
- (void)rb_io_wait_readable(fd);
467
- } else if ((now - last_set_blocking) <= 5) {
468
- (void)rb_io_wait_readable(fd);
469
- } else {
470
- int flags = fcntl(fd, F_GETFL);
471
- if (flags == -1)
472
- rb_sys_fail("fcntl(F_GETFL)");
473
- if (flags & O_NONBLOCK) {
474
- flags = fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
475
- if (flags == -1)
476
- rb_sys_fail("fcntl(F_SETFL)");
477
- }
478
- last_set_blocking = now;
479
- }
480
- }
481
- #else /* ! HAVE_RB_THREAD_BLOCKING_REGION */
482
- # include <rubysig.h>
483
- static int thread_accept(struct accept_args *a, int force_nonblock)
484
- {
485
- int rv;
486
-
487
- /* always use non-blocking accept() under 1.8 for green threads */
488
- set_nonblocking(a->fd);
489
- TRAP_BEG;
490
- rv = (int)xaccept(a);
491
- TRAP_END;
492
- return rv;
493
- }
494
- #define set_blocking_or_block(fd) (void)rb_io_wait_readable(fd)
495
- #endif /* ! HAVE_RB_THREAD_BLOCKING_REGION */
496
-
497
- static VALUE
498
- my_accept(VALUE io, struct sockaddr *addr, socklen_t *addrlen, int nonblock)
499
- {
500
- int client;
501
- struct accept_args a;
502
-
503
- a.fd = my_fileno(io);
504
- a.addr = addr;
505
- a.addrlen = addrlen;
506
- retry:
507
- client = thread_accept(&a, nonblock);
508
- if (client == -1) {
509
- switch (errno) {
510
- case EAGAIN:
511
- if (nonblock)
512
- return Qnil;
513
- set_blocking_or_block(a.fd);
514
- #ifdef ECONNABORTED
515
- case ECONNABORTED:
516
- #endif /* ECONNABORTED */
517
- #ifdef EPROTO
518
- case EPROTO:
519
- #endif /* EPROTO */
520
- case EINTR:
521
- goto retry;
522
- case ENOMEM:
523
- case EMFILE:
524
- case ENFILE:
525
- #ifdef ENOBUFS
526
- case ENOBUFS:
527
- #endif /* ENOBUFS */
528
- errno = 0;
529
- rb_gc();
530
- client = thread_accept(&a, nonblock);
531
- }
532
- if (client == -1) {
533
- if (errno == EINTR)
534
- goto retry;
535
- rb_sys_fail("accept");
536
- }
537
- }
538
- return sock_for_fd(cClientSocket, client);
539
- }
540
-
541
- static void in_addr_set(VALUE io, struct sockaddr_in *addr)
542
- {
543
- VALUE host = rb_str_new(0, INET_ADDRSTRLEN);
544
- socklen_t addrlen = (socklen_t)INET_ADDRSTRLEN;
545
- const char *name;
546
-
547
- name = inet_ntop(AF_INET, &addr->sin_addr, RSTRING_PTR(host), addrlen);
548
- if (name == NULL)
549
- rb_sys_fail("inet_ntop");
550
- rb_str_set_len(host, strlen(name));
551
- rb_ivar_set(io, iv_kgio_addr, host);
552
- }
553
-
554
- /*
555
- * call-seq:
556
- *
557
- * server = Kgio::TCPServer.new('0.0.0.0', 80)
558
- * server.kgio_tryaccept -> Kgio::Socket or nil
559
- *
560
- * Initiates a non-blocking accept and returns a generic Kgio::Socket
561
- * object with the kgio_addr attribute set to the IP address of the
562
- * connected client on success.
563
- *
564
- * Returns nil on EAGAIN, and raises on other errors.
565
- */
566
- static VALUE tcp_tryaccept(VALUE io)
567
- {
568
- struct sockaddr_in addr;
569
- socklen_t addrlen = sizeof(struct sockaddr_in);
570
- VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 1);
571
-
572
- if (!NIL_P(rv))
573
- in_addr_set(rv, &addr);
574
- return rv;
575
- }
576
-
577
- /*
578
- * call-seq:
579
- *
580
- * server = Kgio::TCPServer.new('0.0.0.0', 80)
581
- * server.kgio_accept -> Kgio::Socket or nil
582
- *
583
- * Initiates a blocking accept and returns a generic Kgio::Socket
584
- * object with the kgio_addr attribute set to the IP address of
585
- * the client on success.
586
- *
587
- * On Ruby implementations using native threads, this can use a blocking
588
- * accept(2) (or accept4(2)) system call to avoid thundering herds.
589
- */
590
- static VALUE tcp_accept(VALUE io)
591
- {
592
- struct sockaddr_in addr;
593
- socklen_t addrlen = sizeof(struct sockaddr_in);
594
- VALUE rv = my_accept(io, (struct sockaddr *)&addr, &addrlen, 0);
595
-
596
- in_addr_set(rv, &addr);
597
- return rv;
598
- }
599
-
600
- /*
601
- * call-seq:
602
- *
603
- * server = Kgio::UNIXServer.new("/path/to/unix/socket")
604
- * server.kgio_tryaccept -> Kgio::Socket or nil
605
- *
606
- * Initiates a non-blocking accept and returns a generic Kgio::Socket
607
- * object with the kgio_addr attribute set (to the value of
608
- * Kgio::LOCALHOST) on success.
609
- *
610
- * Returns nil on EAGAIN, and raises on other errors.
611
- */
612
- static VALUE unix_tryaccept(VALUE io)
613
- {
614
- VALUE rv = my_accept(io, NULL, NULL, 1);
615
-
616
- if (!NIL_P(rv))
617
- rb_ivar_set(rv, iv_kgio_addr, localhost);
618
- return rv;
619
- }
620
-
621
- /*
622
- * call-seq:
623
- *
624
- * server = Kgio::UNIXServer.new("/path/to/unix/socket")
625
- * server.kgio_accept -> Kgio::Socket or nil
626
- *
627
- * Initiates a blocking accept and returns a generic Kgio::Socket
628
- * object with the kgio_addr attribute set (to the value of
629
- * Kgio::LOCALHOST) on success.
630
- *
631
- * On Ruby implementations using native threads, this can use a blocking
632
- * accept(2) (or accept4(2)) system call to avoid thundering herds.
633
- */
634
- static VALUE unix_accept(VALUE io)
635
- {
636
- VALUE rv = my_accept(io, NULL, NULL, 0);
637
-
638
- rb_ivar_set(rv, iv_kgio_addr, localhost);
639
- return rv;
640
- }
641
-
642
- /*
643
- * call-seq:
644
- *
645
- * Kgio.accept_cloexec? -> true or false
646
- *
647
- * Returns true if newly accepted Kgio::Sockets are created with the
648
- * FD_CLOEXEC file descriptor flag, false if not.
649
- */
650
- static VALUE get_cloexec(VALUE mod)
651
- {
652
- return (accept4_flags & A4_SOCK_CLOEXEC) ==
653
- A4_SOCK_CLOEXEC ? Qtrue : Qfalse;
654
- }
655
-
656
- /*
657
- *
658
- * call-seq:
659
- *
660
- * Kgio.accept_nonblock? -> true or false
661
- *
662
- * Returns true if newly accepted Kgio::Sockets are created with the
663
- * O_NONBLOCK file status flag, false if not.
664
- */
665
- static VALUE get_nonblock(VALUE mod)
666
- {
667
- return (accept4_flags & A4_SOCK_NONBLOCK) ==
668
- A4_SOCK_NONBLOCK ? Qtrue : Qfalse;
669
- }
670
-
671
- /*
672
- * call-seq:
673
- *
674
- * Kgio.accept_cloexec = true
675
- * Kgio.accept_clocexec = false
676
- *
677
- * Sets whether or not Kgio::Socket objects created by
678
- * TCPServer#kgio_accept,
679
- * TCPServer#kgio_tryaccept,
680
- * UNIXServer#kgio_accept,
681
- * and UNIXServer#kgio_tryaccept
682
- * are created with the FD_CLOEXEC file descriptor flag.
683
- *
684
- * This is on by default, as there is little reason to deal to enable
685
- * it for client sockets on a socket server.
686
- */
687
- static VALUE set_cloexec(VALUE mod, VALUE boolean)
688
- {
689
- switch (TYPE(boolean)) {
690
- case T_TRUE:
691
- accept4_flags |= A4_SOCK_CLOEXEC;
692
- return boolean;
693
- case T_FALSE:
694
- accept4_flags &= ~A4_SOCK_CLOEXEC;
695
- return boolean;
696
- }
697
- rb_raise(rb_eTypeError, "not true or false");
698
- return Qnil;
699
- }
700
-
701
- /*
702
- * call-seq:
703
- *
704
- * Kgio.accept_nonblock = true
705
- * Kgio.accept_nonblock = false
706
- *
707
- * Sets whether or not Kgio::Socket objects created by
708
- * TCPServer#kgio_accept,
709
- * TCPServer#kgio_tryaccept,
710
- * UNIXServer#kgio_accept,
711
- * and UNIXServer#kgio_tryaccept
712
- * are created with the O_NONBLOCK file status flag.
713
- *
714
- * This defaults to +false+ for GNU/Linux where MSG_DONTWAIT is
715
- * available (and on newer GNU/Linux, accept4() may also set
716
- * the non-blocking flag. This defaults to +true+ on non-GNU/Linux
717
- * systems.
718
- */
719
- static VALUE set_nonblock(VALUE mod, VALUE boolean)
720
- {
721
- switch (TYPE(boolean)) {
722
- case T_TRUE:
723
- accept4_flags |= A4_SOCK_NONBLOCK;
724
- return boolean;
725
- case T_FALSE:
726
- accept4_flags &= ~A4_SOCK_NONBLOCK;
727
- return boolean;
728
- }
729
- rb_raise(rb_eTypeError, "not true or false");
730
- return Qnil;
731
- }
732
-
733
- static void close_fail(int fd, const char *msg)
734
- {
735
- int saved_errno = errno;
736
- (void)close(fd);
737
- errno = saved_errno;
738
- rb_sys_fail(msg);
739
- }
740
-
741
- #ifdef SOCK_NONBLOCK
742
- # define MY_SOCK_STREAM (SOCK_STREAM|SOCK_NONBLOCK)
743
- #else
744
- # define MY_SOCK_STREAM SOCK_STREAM
745
- #endif /* ! SOCK_NONBLOCK */
746
-
747
- static VALUE
748
- my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
749
- {
750
- int fd = socket(domain, MY_SOCK_STREAM, 0);
751
-
752
- if (fd == -1) {
753
- switch (errno) {
754
- case EMFILE:
755
- case ENFILE:
756
- #ifdef ENOBUFS
757
- case ENOBUFS:
758
- #endif /* ENOBUFS */
759
- errno = 0;
760
- rb_gc();
761
- fd = socket(domain, MY_SOCK_STREAM, 0);
762
- }
763
- if (fd == -1)
764
- rb_sys_fail("socket");
765
- }
766
-
767
- #ifndef SOCK_NONBLOCK
768
- if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
769
- close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
770
- #endif /* SOCK_NONBLOCK */
771
-
772
- if (connect(fd, addr, addrlen) == -1) {
773
- if (errno == EINPROGRESS) {
774
- VALUE io = sock_for_fd(klass, fd);
775
-
776
- if (io_wait) {
777
- errno = EAGAIN;
778
- wait_writable(io, fd);
779
- }
780
- return io;
781
- }
782
- close_fail(fd, "connect");
783
- }
784
- return sock_for_fd(klass, fd);
785
- }
786
-
787
- static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
788
- {
789
- struct sockaddr_in addr = { 0 };
790
-
791
- addr.sin_family = AF_INET;
792
- addr.sin_port = htons((unsigned short)NUM2INT(port));
793
-
794
- switch (inet_pton(AF_INET, StringValuePtr(ip), &addr.sin_addr)) {
795
- case 1:
796
- return my_connect(klass, io_wait, PF_INET, &addr, sizeof(addr));
797
- case -1:
798
- rb_sys_fail("inet_pton");
799
- }
800
- rb_raise(rb_eArgError, "invalid address: %s", StringValuePtr(ip));
801
-
802
- return Qnil;
803
- }
804
-
805
- /*
806
- * call-seq:
807
- *
808
- * Kgio::TCPSocket.new('127.0.0.1', 80) -> socket
809
- *
810
- * Creates a new Kgio::TCPSocket object and initiates a
811
- * non-blocking connection.
812
- *
813
- * This may block and call any method assigned to Kgio.wait_writable.
814
- *
815
- * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
816
- * lookups (which is subject to a different set of timeouts and
817
- * best handled elsewhere).
818
- */
819
- static VALUE kgio_tcp_connect(VALUE klass, VALUE ip, VALUE port)
820
- {
821
- return tcp_connect(klass, ip, port, 1);
822
- }
823
-
824
- /*
825
- * call-seq:
826
- *
827
- * Kgio::TCPSocket.start('127.0.0.1', 80) -> socket
828
- *
829
- * Creates a new Kgio::TCPSocket object and initiates a
830
- * non-blocking connection. The caller should select/poll
831
- * on the socket for writability before attempting to write
832
- * or optimistically attempt a write and handle Kgio::WaitWritable
833
- * or Errno::EAGAIN.
834
- *
835
- * Unlike the TCPSocket.new in Ruby, this does NOT perform DNS
836
- * lookups (which is subject to a different set of timeouts and
837
- * best handled elsewhere).
838
- */
839
- static VALUE kgio_tcp_start(VALUE klass, VALUE ip, VALUE port)
840
- {
841
- return tcp_connect(klass, ip, port, 0);
842
- }
843
-
844
- static VALUE unix_connect(VALUE klass, VALUE path, int io_wait)
845
- {
846
- struct sockaddr_un addr = { 0 };
847
- long len;
848
-
849
- StringValue(path);
850
- len = RSTRING_LEN(path);
851
- if (sizeof(addr.sun_path) <= len)
852
- rb_raise(rb_eArgError,
853
- "too long unix socket path (max: %dbytes)",
854
- (int)sizeof(addr.sun_path)-1);
855
-
856
- memcpy(addr.sun_path, RSTRING_PTR(path), len);
857
- addr.sun_family = AF_UNIX;
858
-
859
- return my_connect(klass, io_wait, PF_UNIX, &addr, sizeof(addr));
860
- }
861
-
862
- /*
863
- * call-seq:
864
- *
865
- * Kgio::UNIXSocket.new("/path/to/unix/socket") -> socket
866
- *
867
- * Creates a new Kgio::UNIXSocket object and initiates a
868
- * non-blocking connection.
869
- *
870
- * This may block and call any method assigned to Kgio.wait_writable.
871
- */
872
- static VALUE kgio_unix_connect(VALUE klass, VALUE path)
873
- {
874
- return unix_connect(klass, path, 1);
875
- }
876
-
877
- /*
878
- * call-seq:
879
- *
880
- * Kgio::UNIXSocket.start("/path/to/unix/socket") -> socket
881
- *
882
- * Creates a new Kgio::UNIXSocket object and initiates a
883
- * non-blocking connection. The caller should select/poll
884
- * on the socket for writability before attempting to write
885
- * or optimistically attempt a write and handle Kgio::WaitWritable
886
- * or Errno::EAGAIN.
887
- */
888
- static VALUE kgio_unix_start(VALUE klass, VALUE path)
889
- {
890
- return unix_connect(klass, path, 0);
891
- }
892
-
893
- static VALUE stream_connect(VALUE klass, VALUE addr, int io_wait)
894
- {
895
- int domain;
896
- socklen_t addrlen;
897
- struct sockaddr *sockaddr;
898
-
899
- if (TYPE(addr) == T_STRING) {
900
- sockaddr = (struct sockaddr *)(RSTRING_PTR(addr));
901
- addrlen = (socklen_t)RSTRING_LEN(addr);
902
- } else {
903
- rb_raise(rb_eTypeError, "invalid address");
904
- }
905
- switch (((struct sockaddr_in *)(sockaddr))->sin_family) {
906
- case AF_UNIX: domain = PF_UNIX; break;
907
- case AF_INET: domain = PF_INET; break;
908
- #ifdef AF_INET6 /* IPv6 support incomplete */
909
- case AF_INET6: domain = PF_INET6; break;
910
- #endif /* AF_INET6 */
911
- default:
912
- rb_raise(rb_eArgError, "invalid address family");
913
- }
914
-
915
- return my_connect(klass, io_wait, domain, sockaddr, addrlen);
916
- }
917
-
918
- /* call-seq:
919
- *
920
- * addr = Socket.pack_sockaddr_in(80, 'example.com')
921
- * Kgio::Socket.connect(addr) -> socket
922
- *
923
- * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
924
- * Kgio::Socket.connect(addr) -> socket
925
- *
926
- * Creates a generic Kgio::Socket object and initiates a
927
- * non-blocking connection.
928
- *
929
- * This may block and call any method assigned to Kgio.wait_writable.
930
- */
931
- static VALUE kgio_connect(VALUE klass, VALUE addr)
932
- {
933
- return stream_connect(klass, addr, 1);
934
- }
935
-
936
- /* call-seq:
937
- *
938
- * addr = Socket.pack_sockaddr_in(80, 'example.com')
939
- * Kgio::Socket.start(addr) -> socket
940
- *
941
- * addr = Socket.pack_sockaddr_un("/path/to/unix/socket")
942
- * Kgio::Socket.start(addr) -> socket
943
- *
944
- * Creates a generic Kgio::Socket object and initiates a
945
- * non-blocking connection. The caller should select/poll
946
- * on the socket for writability before attempting to write
947
- * or optimistically attempt a write and handle Kgio::WaitWritable
948
- * or Errno::EAGAIN.
949
- */
950
- static VALUE kgio_start(VALUE klass, VALUE addr)
951
- {
952
- return stream_connect(klass, addr, 0);
953
- }
954
-
955
- static VALUE set_accepted(VALUE klass, VALUE aclass)
956
- {
957
- VALUE tmp;
958
-
959
- if (NIL_P(aclass))
960
- aclass = cSocket;
961
-
962
- tmp = rb_funcall(aclass, rb_intern("included_modules"), 0, 0);
963
- tmp = rb_funcall(tmp, rb_intern("include?"), 1, mSocketMethods);
964
-
965
- if (tmp != Qtrue)
966
- rb_raise(rb_eTypeError,
967
- "class must include Kgio::SocketMethods");
968
-
969
- cClientSocket = aclass;
970
-
971
- return aclass;
972
- }
973
-
974
- static VALUE get_accepted(VALUE klass)
975
- {
976
- return cClientSocket;
977
- }
1
+ #include "kgio.h"
978
2
 
979
3
  void Init_kgio_ext(void)
980
4
  {
981
- VALUE mKgio = rb_define_module("Kgio");
982
- VALUE mPipeMethods;
983
- VALUE cUNIXServer, cTCPServer, cUNIXSocket, cTCPSocket;
984
-
985
- rb_require("socket");
986
-
987
- /*
988
- * Document-module: Kgio::Socket
989
- *
990
- * A generic socket class with Kgio::SocketMethods included.
991
- * This is returned by all Kgio methods that accept(2) a connected
992
- * stream socket.
993
- */
994
- cSocket = rb_const_get(rb_cObject, rb_intern("Socket"));
995
- cSocket = rb_define_class_under(mKgio, "Socket", cSocket);
996
- cClientSocket = cSocket;
997
-
998
- localhost = rb_str_new2("127.0.0.1");
999
-
1000
- /*
1001
- * The IPv4 address of UNIX domain sockets, useful for creating
1002
- * Rack (and CGI) servers that also serve HTTP traffic over
1003
- * UNIX domain sockets.
1004
- */
1005
- rb_const_set(mKgio, rb_intern("LOCALHOST"), localhost);
1006
-
1007
- /*
1008
- * Document-module: Kgio::WaitReadable
1009
- *
1010
- * PipeMethods#kgio_tryread and SocketMethods#kgio_tryread will
1011
- * return this constant when waiting for a read is required.
1012
- */
1013
- mKgio_WaitReadable = rb_define_module_under(mKgio, "WaitReadable");
1014
-
1015
- /*
1016
- * Document-module: Kgio::WaitWritable
1017
- *
1018
- * PipeMethods#kgio_trywrite and SocketMethods#kgio_trywrite will
1019
- * return this constant when waiting for a read is required.
1020
- */
1021
- mKgio_WaitWritable = rb_define_module_under(mKgio, "WaitWritable");
1022
-
1023
- rb_define_singleton_method(mKgio, "wait_readable=", set_wait_rd, 1);
1024
- rb_define_singleton_method(mKgio, "wait_writable=", set_wait_wr, 1);
1025
- rb_define_singleton_method(mKgio, "wait_readable", wait_rd, 0);
1026
- rb_define_singleton_method(mKgio, "wait_writable", wait_wr, 0);
1027
- rb_define_singleton_method(mKgio, "accept_cloexec?", get_cloexec, 0);
1028
- rb_define_singleton_method(mKgio, "accept_cloexec=", set_cloexec, 1);
1029
- rb_define_singleton_method(mKgio, "accept_nonblock?", get_nonblock, 0);
1030
- rb_define_singleton_method(mKgio, "accept_nonblock=", set_nonblock, 1);
1031
- rb_define_singleton_method(mKgio, "accept_class=", set_accepted, 1);
1032
- rb_define_singleton_method(mKgio, "accept_class", get_accepted, 0);
1033
-
1034
- /*
1035
- * Document-module: Kgio::PipeMethods
1036
- *
1037
- * This module may be used used to create classes that respond to
1038
- * various Kgio methods for reading and writing. This is included
1039
- * in Kgio::Pipe by default.
1040
- */
1041
- mPipeMethods = rb_define_module_under(mKgio, "PipeMethods");
1042
- rb_define_method(mPipeMethods, "kgio_read", kgio_read, -1);
1043
- rb_define_method(mPipeMethods, "kgio_write", kgio_write, 1);
1044
- rb_define_method(mPipeMethods, "kgio_tryread", kgio_tryread, -1);
1045
- rb_define_method(mPipeMethods, "kgio_trywrite", kgio_trywrite, 1);
1046
-
1047
- /*
1048
- * Document-module: Kgio::SocketMethods
1049
- *
1050
- * This method behaves like Kgio::PipeMethods, but contains
1051
- * optimizations for sockets on certain operating systems
1052
- * (e.g. GNU/Linux).
1053
- */
1054
- mSocketMethods = rb_define_module_under(mKgio, "SocketMethods");
1055
- rb_define_method(mSocketMethods, "kgio_read", kgio_recv, -1);
1056
- rb_define_method(mSocketMethods, "kgio_write", kgio_send, 1);
1057
- rb_define_method(mSocketMethods, "kgio_tryread", kgio_tryrecv, -1);
1058
- rb_define_method(mSocketMethods, "kgio_trywrite", kgio_trysend, 1);
1059
-
1060
- /*
1061
- * Returns the client IPv4 address of the socket in dotted quad
1062
- * form as a string. This is always the value of the
1063
- * Kgio::LOCALHOST constant for UNIX domain sockets.
1064
- */
1065
- rb_define_attr(mSocketMethods, "kgio_addr", 1, 1);
1066
-
1067
- rb_include_module(cSocket, mSocketMethods);
1068
- rb_define_singleton_method(cSocket, "new", kgio_connect, 1);
1069
- rb_define_singleton_method(cSocket, "start", kgio_start, 1);
1070
-
1071
- cUNIXServer = rb_const_get(rb_cObject, rb_intern("UNIXServer"));
1072
- cUNIXServer = rb_define_class_under(mKgio, "UNIXServer", cUNIXServer);
1073
- rb_define_method(cUNIXServer, "kgio_tryaccept", unix_tryaccept, 0);
1074
- rb_define_method(cUNIXServer, "kgio_accept", unix_accept, 0);
1075
-
1076
- cTCPServer = rb_const_get(rb_cObject, rb_intern("TCPServer"));
1077
- cTCPServer = rb_define_class_under(mKgio, "TCPServer", cTCPServer);
1078
- rb_define_method(cTCPServer, "kgio_tryaccept", tcp_tryaccept, 0);
1079
- rb_define_method(cTCPServer, "kgio_accept", tcp_accept, 0);
1080
-
1081
- cTCPSocket = rb_const_get(rb_cObject, rb_intern("TCPSocket"));
1082
- cTCPSocket = rb_define_class_under(mKgio, "TCPSocket", cTCPSocket);
1083
- rb_include_module(cTCPSocket, mSocketMethods);
1084
- rb_define_singleton_method(cTCPSocket, "new", kgio_tcp_connect, 2);
1085
- rb_define_singleton_method(cTCPSocket, "start", kgio_tcp_start, 2);
1086
-
1087
- cUNIXSocket = rb_const_get(rb_cObject, rb_intern("UNIXSocket"));
1088
- cUNIXSocket = rb_define_class_under(mKgio, "UNIXSocket", cUNIXSocket);
1089
- rb_include_module(cUNIXSocket, mSocketMethods);
1090
- rb_define_singleton_method(cUNIXSocket, "new", kgio_unix_connect, 1);
1091
- rb_define_singleton_method(cUNIXSocket, "start", kgio_unix_start, 1);
5
+ VALUE mKgio = rb_const_get(rb_cObject, rb_intern("Kgio"));
1092
6
 
1093
- iv_kgio_addr = rb_intern("@kgio_addr");
1094
- init_sock_for_fd();
7
+ init_kgio_wait(mKgio);
8
+ init_kgio_read_write(mKgio);
9
+ init_kgio_connect(mKgio);
10
+ init_kgio_accept(mKgio);
1095
11
  }