kgio 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/.wrongdoc.yml CHANGED
@@ -2,3 +2,5 @@
2
2
  cgit_url: http://bogomips.org/kgio.git
3
3
  git_url: git://bogomips.org/kgio.git
4
4
  rdoc_url: http://bogomips.org/kgio/
5
+ public_email: kgio@librelist.org
6
+ private_email: kgio@bogomips.org
data/GIT-VERSION-GEN CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/sh
2
2
 
3
3
  GVF=GIT-VERSION-FILE
4
- DEF_VER=v2.6.0.GIT
4
+ DEF_VER=v2.7.0.GIT
5
5
 
6
6
  LF='
7
7
  '
data/LICENSE CHANGED
@@ -14,5 +14,5 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14
14
  License for more details.
15
15
 
16
16
  You should have received a copy of the GNU Lesser General Public License
17
- along with the GNU C Library; if not, write to the Free Software
17
+ along with kgio; if not, write to the Free Software
18
18
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
data/TODO CHANGED
@@ -1 +1 @@
1
- * SSL/TLS support with SNI
1
+ * SSL/TLS support with SNI ({done}[http://bogomips.org/kgio-monkey/])
data/ext/kgio/accept.c CHANGED
@@ -10,7 +10,7 @@ static VALUE cKgio_Socket;
10
10
  static VALUE mSocketMethods;
11
11
  static VALUE iv_kgio_addr;
12
12
 
13
- #if defined(__linux__)
13
+ #if defined(__linux__) && defined(HAVE_RB_THREAD_BLOCKING_REGION)
14
14
  static int accept4_flags = SOCK_CLOEXEC;
15
15
  #else /* ! linux */
16
16
  static int accept4_flags = SOCK_CLOEXEC | SOCK_NONBLOCK;
@@ -125,6 +125,10 @@ static int thread_accept(struct accept_args *a, int force_nonblock)
125
125
 
126
126
  /* always use non-blocking accept() under 1.8 for green threads */
127
127
  set_nonblocking(a->fd);
128
+
129
+ /* created sockets are always non-blocking under 1.8, too */
130
+ a->flags |= SOCK_NONBLOCK;
131
+
128
132
  TRAP_BEG;
129
133
  rv = (int)xaccept(a);
130
134
  TRAP_END;
@@ -279,12 +283,11 @@ static VALUE addr_bang(VALUE io)
279
283
  * An optional +klass+ argument may be specified to override the
280
284
  * Kgio::Socket-class on a successful return value.
281
285
  *
282
- * An optional +flags+ argument may also be specifed to override the
283
- * value of +Kgio.accept_cloexec+ and +Kgio.accept_nonblock+. +flags+
284
- * is a bitmask that may contain any combination of:
286
+ * An optional +flags+ argument may also be specified.
287
+ * +flags+ is a bitmask that may contain any combination of:
285
288
  *
286
- * - Kgio::SOCK_CLOEXEC - close-on-exec flag
287
- * - Kgio::SOCK_NONBLOCK - non-blocking flag
289
+ * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
290
+ * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
288
291
  */
289
292
  static VALUE tcp_tryaccept(int argc, VALUE *argv, VALUE self)
290
293
  {
@@ -316,12 +319,11 @@ static VALUE tcp_tryaccept(int argc, VALUE *argv, VALUE self)
316
319
  * An optional +klass+ argument may be specified to override the
317
320
  * Kgio::Socket-class on a successful return value.
318
321
  *
319
- * An optional +flags+ argument may also be specifed to override the
320
- * value of +Kgio.accept_cloexec+ and +Kgio.accept_nonblock+. +flags+
321
- * is a bitmask that may contain any combination of:
322
+ * An optional +flags+ argument may also be specified.
323
+ * +flags+ is a bitmask that may contain any combination of:
322
324
  *
323
- * - Kgio::SOCK_CLOEXEC - close-on-exec flag
324
- * - Kgio::SOCK_NONBLOCK - non-blocking flag
325
+ * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
326
+ * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
325
327
  */
326
328
  static VALUE tcp_accept(int argc, VALUE *argv, VALUE self)
327
329
  {
@@ -350,12 +352,11 @@ static VALUE tcp_accept(int argc, VALUE *argv, VALUE self)
350
352
  * An optional +klass+ argument may be specified to override the
351
353
  * Kgio::Socket-class on a successful return value.
352
354
  *
353
- * An optional +flags+ argument may also be specifed to override the
354
- * value of +Kgio.accept_cloexec+ and +Kgio.accept_nonblock+. +flags+
355
- * is a bitmask that may contain any combination of:
355
+ * An optional +flags+ argument may also be specified.
356
+ * +flags+ is a bitmask that may contain any combination of:
356
357
  *
357
- * - Kgio::SOCK_CLOEXEC - close-on-exec flag
358
- * - Kgio::SOCK_NONBLOCK - non-blocking flag
358
+ * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
359
+ * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
359
360
  */
360
361
  static VALUE unix_tryaccept(int argc, VALUE *argv, VALUE self)
361
362
  {
@@ -385,12 +386,11 @@ static VALUE unix_tryaccept(int argc, VALUE *argv, VALUE self)
385
386
  * An optional +klass+ argument may be specified to override the
386
387
  * Kgio::Socket-class on a successful return value.
387
388
  *
388
- * An optional +flags+ argument may also be specifed to override the
389
- * value of +Kgio.accept_cloexec+ and +Kgio.accept_nonblock+. +flags+
390
- * is a bitmask that may contain any combination of:
389
+ * An optional +flags+ argument may also be specified.
390
+ * +flags+ is a bitmask that may contain any combination of:
391
391
  *
392
- * - Kgio::SOCK_CLOEXEC - close-on-exec flag
393
- * - Kgio::SOCK_NONBLOCK - non-blocking flag
392
+ * - Kgio::SOCK_CLOEXEC - close-on-exec flag (enabled by default)
393
+ * - Kgio::SOCK_NONBLOCK - non-blocking flag (unimportant)
394
394
  */
395
395
  static VALUE unix_accept(int argc, VALUE *argv, VALUE self)
396
396
  {
@@ -409,6 +409,8 @@ static VALUE unix_accept(int argc, VALUE *argv, VALUE self)
409
409
  *
410
410
  * Returns true if newly accepted Kgio::Sockets are created with the
411
411
  * FD_CLOEXEC file descriptor flag, false if not.
412
+ *
413
+ * Deprecated, use the per-socket flags for kgio_*accept instead.
412
414
  */
413
415
  static VALUE get_cloexec(VALUE mod)
414
416
  {
@@ -423,6 +425,8 @@ static VALUE get_cloexec(VALUE mod)
423
425
  *
424
426
  * Returns true if newly accepted Kgio::Sockets are created with the
425
427
  * O_NONBLOCK file status flag, false if not.
428
+ *
429
+ * Deprecated, use the per-socket flags for kgio_*accept instead.
426
430
  */
427
431
  static VALUE get_nonblock(VALUE mod)
428
432
  {
@@ -444,6 +448,8 @@ static VALUE get_nonblock(VALUE mod)
444
448
  *
445
449
  * This is on by default, as there is little reason to deal to enable
446
450
  * it for client sockets on a socket server.
451
+ *
452
+ * Deprecated, use the per-socket flags for kgio_*accept instead.
447
453
  */
448
454
  static VALUE set_cloexec(VALUE mod, VALUE boolean)
449
455
  {
@@ -476,6 +482,10 @@ static VALUE set_cloexec(VALUE mod, VALUE boolean)
476
482
  * available (and on newer GNU/Linux, accept4() may also set
477
483
  * the non-blocking flag. This defaults to +true+ on non-GNU/Linux
478
484
  * systems.
485
+ *
486
+ * This is always true on Ruby implementations using user-space threads.
487
+ *
488
+ * Deprecated, use the per-socket flags for kgio_*accept instead.
479
489
  */
480
490
  static VALUE set_nonblock(VALUE mod, VALUE boolean)
481
491
  {
@@ -497,14 +507,18 @@ void init_kgio_accept(void)
497
507
  VALUE mKgio = rb_define_module("Kgio");
498
508
 
499
509
  /*
500
- * this maps to the SOCK_NONBLOCK constant in Linux for setting
501
- * the non-blocking flag on newly accepted sockets.
510
+ * Maps to the SOCK_NONBLOCK constant in Linux for setting
511
+ * the non-blocking flag on newly accepted sockets. This is
512
+ * usually unnecessary as sockets are made non-blocking
513
+ * whenever non-blocking methods are used.
502
514
  */
503
515
  rb_define_const(mKgio, "SOCK_NONBLOCK", INT2NUM(SOCK_NONBLOCK));
504
516
 
505
517
  /*
506
- * this maps to the SOCK_CLOEXEC constant in Linux for setting
507
- * the close-on-exec flag on newly accepted descriptors.
518
+ * Maps to the SOCK_CLOEXEC constant in Linux for setting
519
+ * the close-on-exec flag on newly accepted descriptors. This
520
+ * is enabled by default, and there is usually no reason to
521
+ * disable close-on-exec for accepted sockets.
508
522
  */
509
523
  rb_define_const(mKgio, "SOCK_CLOEXEC", INT2NUM(SOCK_CLOEXEC));
510
524
 
data/ext/kgio/connect.c CHANGED
@@ -9,16 +9,30 @@ static void close_fail(int fd, const char *msg)
9
9
  rb_sys_fail(msg);
10
10
  }
11
11
 
12
- #ifdef SOCK_NONBLOCK
13
- # define MY_SOCK_STREAM (SOCK_STREAM|SOCK_NONBLOCK)
12
+ static int MY_SOCK_STREAM =
13
+ #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
14
+ # ifdef HAVE_RB_FD_FIX_CLOEXEC
15
+ (SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC)
16
+ # else
17
+ (SOCK_STREAM|SOCK_NONBLOCK)
18
+ # endif
14
19
  #else
15
- # define MY_SOCK_STREAM SOCK_STREAM
20
+ SOCK_STREAM
16
21
  #endif /* ! SOCK_NONBLOCK */
22
+ ;
23
+
24
+ /* do not set close-on-exec by default on Ruby <2.0.0 */
25
+ #ifndef HAVE_RB_FD_FIX_CLOEXEC
26
+ # define rb_fd_fix_cloexec(fd) for (;0;)
27
+ #endif /* HAVE_RB_FD_FIX_CLOEXEC */
17
28
 
18
29
  static VALUE
19
30
  my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
20
31
  {
21
- int fd = socket(domain, MY_SOCK_STREAM, 0);
32
+ int fd;
33
+
34
+ retry:
35
+ fd = socket(domain, MY_SOCK_STREAM, 0);
22
36
 
23
37
  if (fd == -1) {
24
38
  switch (errno) {
@@ -30,15 +44,22 @@ my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
30
44
  errno = 0;
31
45
  rb_gc();
32
46
  fd = socket(domain, MY_SOCK_STREAM, 0);
47
+ break;
48
+ case EINVAL:
49
+ if (MY_SOCK_STREAM != SOCK_STREAM) {
50
+ MY_SOCK_STREAM = SOCK_STREAM;
51
+ goto retry;
52
+ }
33
53
  }
34
54
  if (fd == -1)
35
55
  rb_sys_fail("socket");
36
56
  }
37
57
 
38
- #ifndef SOCK_NONBLOCK
39
- if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
40
- close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
41
- #endif /* SOCK_NONBLOCK */
58
+ if (MY_SOCK_STREAM == SOCK_STREAM) {
59
+ if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
60
+ close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
61
+ rb_fd_fix_cloexec(fd);
62
+ }
42
63
 
43
64
  if (connect(fd, addr, addrlen) == -1) {
44
65
  if (errno == EINPROGRESS) {
@@ -63,7 +84,11 @@ static VALUE tcp_connect(VALUE klass, VALUE ip, VALUE port, int io_wait)
63
84
  struct addrinfo *res;
64
85
  const char *ipname = StringValuePtr(ip);
65
86
  char ipport[6];
66
- unsigned uport = FIX2UINT(port);
87
+ unsigned uport;
88
+
89
+ if (TYPE(port) != T_FIXNUM)
90
+ rb_raise(rb_eTypeError, "port must be a non-negative integer");
91
+ uport = FIX2UINT(port);
67
92
 
68
93
  rc = snprintf(ipport, sizeof(ipport), "%u", uport);
69
94
  if (rc >= (int)sizeof(ipport) || rc <= 0)
data/ext/kgio/extconf.rb CHANGED
@@ -41,6 +41,9 @@ have_type("struct RFile", rubyio) and check_sizeof("struct RFile", rubyio)
41
41
  have_type("struct RObject") and check_sizeof("struct RObject")
42
42
  check_sizeof("int")
43
43
  have_func('rb_io_ascii8bit_binmode')
44
+ have_func('rb_update_max_fd')
45
+ have_func('rb_fd_fix_cloexec')
46
+ have_func('rb_cloexec_open')
44
47
  have_func('rb_thread_blocking_region')
45
48
  have_func('rb_thread_io_blocking_region')
46
49
  have_func('rb_str_set_len')
data/ext/kgio/kgio.h CHANGED
@@ -46,4 +46,7 @@ VALUE kgio_call_wait_readable(VALUE io);
46
46
  # define USE_KGIO_POLL
47
47
  #endif /* USE_KGIO_POLL */
48
48
 
49
+ #ifndef HAVE_RB_UPDATE_MAX_FD
50
+ # define rb_update_max_fd(fd) for (;0;)
51
+ #endif
49
52
  #endif /* KGIO_H */
@@ -29,9 +29,11 @@
29
29
  #if SOCK_FOR_FD == 19 /* modeled after ext/socket/init.c */
30
30
  static VALUE sock_for_fd(VALUE klass, int fd)
31
31
  {
32
- VALUE sock = rb_obj_alloc(klass);
32
+ VALUE sock;
33
33
  rb_io_t *fp;
34
34
 
35
+ rb_update_max_fd(fd); /* 1.9.3+ API */
36
+ sock = rb_obj_alloc(klass);
35
37
  MakeOpenFile(sock, fp);
36
38
  fp->fd = fd;
37
39
  fp->mode = FMODE_READWRITE|FMODE_DUPLEX|FMODE_NOREVLOOKUP;
data/ext/kgio/tryopen.c CHANGED
@@ -25,11 +25,15 @@ struct open_args {
25
25
  mode_t mode;
26
26
  };
27
27
 
28
+ #ifndef HAVE_RB_CLOEXEC_OPEN
29
+ # define rb_cloexec_open(p,f,m) open((p),(f),(m))
30
+ #endif
31
+
28
32
  static VALUE nogvl_open(void *ptr)
29
33
  {
30
34
  struct open_args *o = ptr;
31
35
 
32
- return (VALUE)open(o->pathname, o->flags, o->mode);
36
+ return (VALUE)rb_cloexec_open(o->pathname, o->flags, o->mode);
33
37
  }
34
38
 
35
39
  #ifndef HAVE_RB_THREAD_BLOCKING_REGION
data/ext/kgio/wait.c CHANGED
@@ -68,7 +68,7 @@ static VALUE kgio_wait_readable(int argc, VALUE *argv, VALUE self)
68
68
  /*
69
69
  * call-seq:
70
70
  *
71
- * io.kgio_wait_writeable -> IO
71
+ * io.kgio_wait_writable -> IO
72
72
  * io.kgio_wait_writable(timeout) -> IO or nil
73
73
  *
74
74
  * Blocks the running Thread indefinitely until the IO object is writable
@@ -25,7 +25,6 @@ module LibServerAccept
25
25
  IO.select([@srv])
26
26
  b = @srv.kgio_tryaccept nil, 0
27
27
  assert_kind_of Kgio::Socket, b
28
- assert_equal false, b.nonblock?
29
28
  assert_equal 0, b.fcntl(Fcntl::F_GETFD)
30
29
  end
31
30
 
@@ -34,7 +33,6 @@ module LibServerAccept
34
33
  IO.select([@srv])
35
34
  b = @srv.kgio_accept nil, 0
36
35
  assert_kind_of Kgio::Socket, b
37
- assert_equal false, b.nonblock?
38
36
  assert_equal 0, b.fcntl(Fcntl::F_GETFD)
39
37
  end
40
38
 
@@ -13,7 +13,6 @@ class TestAcceptFlags < Test::Unit::TestCase
13
13
  client = TCPSocket.new(@host, @port)
14
14
  accepted = @srv.kgio_accept(nil, Kgio::SOCK_NONBLOCK)
15
15
  assert_instance_of Kgio::Socket, accepted
16
- assert accepted.nonblock?
17
16
  flags = accepted.fcntl(Fcntl::F_GETFD)
18
17
  assert_equal 0, flags & Fcntl::FD_CLOEXEC
19
18
  assert_nil client.close
@@ -22,7 +21,6 @@ class TestAcceptFlags < Test::Unit::TestCase
22
21
  client = TCPSocket.new(@host, @port)
23
22
  accepted = @srv.kgio_accept(nil, Kgio::SOCK_CLOEXEC)
24
23
  assert_instance_of Kgio::Socket, accepted
25
- assert ! accepted.nonblock?
26
24
  flags = accepted.fcntl(Fcntl::F_GETFD)
27
25
  assert_equal Fcntl::FD_CLOEXEC, flags & Fcntl::FD_CLOEXEC
28
26
  assert_nil client.close
@@ -31,7 +29,6 @@ class TestAcceptFlags < Test::Unit::TestCase
31
29
  client = TCPSocket.new(@host, @port)
32
30
  accepted = @srv.kgio_accept(nil, Kgio::SOCK_CLOEXEC|Kgio::SOCK_NONBLOCK)
33
31
  assert_instance_of Kgio::Socket, accepted
34
- assert accepted.nonblock?
35
32
  flags = accepted.fcntl(Fcntl::F_GETFD)
36
33
  assert_equal Fcntl::FD_CLOEXEC, flags & Fcntl::FD_CLOEXEC
37
34
  assert_nil client.close
@@ -40,7 +37,6 @@ class TestAcceptFlags < Test::Unit::TestCase
40
37
  client = TCPSocket.new(@host, @port)
41
38
  accepted = @srv.kgio_accept(nil, Kgio::SOCK_CLOEXEC|Kgio::SOCK_NONBLOCK)
42
39
  assert_instance_of Kgio::Socket, accepted
43
- assert accepted.nonblock?
44
40
  flags = accepted.fcntl(Fcntl::F_GETFD)
45
41
  assert_equal Fcntl::FD_CLOEXEC, flags & Fcntl::FD_CLOEXEC
46
42
  assert_nil client.close
data/test/test_poll.rb CHANGED
@@ -53,6 +53,19 @@ class TestPoll < Test::Unit::TestCase
53
53
  assert diff >= 0.010, "diff=#{diff}"
54
54
  end
55
55
 
56
+ def test_signal_close
57
+ orig = trap(:USR1) { @rd.close }
58
+ res = nil
59
+ thr = Thread.new { sleep 0.100; Process.kill(:USR1, $$) }
60
+ t0 = Time.now
61
+ assert_raises(IOError) { Kgio.poll({@rd => Kgio::POLLIN}) }
62
+ diff = Time.now - t0
63
+ thr.join
64
+ assert diff >= 0.010, "diff=#{diff}"
65
+ ensure
66
+ trap(:USR1, orig)
67
+ end
68
+
56
69
  def test_poll_EINTR
57
70
  ok = false
58
71
  orig = trap(:USR1) { ok = true }
@@ -31,10 +31,17 @@ class TestKgioTcpConnect < Test::Unit::TestCase
31
31
  ready = IO.select(nil, [ sock ])
32
32
  assert_equal sock, ready[1][0]
33
33
  assert_equal nil, sock.kgio_write("HELLO")
34
+
35
+ sock.respond_to?(:close_on_exec?) and
36
+ assert_equal(RUBY_VERSION.to_f >= 2.0, sock.close_on_exec?)
34
37
  end
35
38
 
36
39
  def test_start
37
40
  sock = Kgio::Socket.start(@addr)
41
+
42
+ sock.respond_to?(:close_on_exec?) and
43
+ assert_equal(RUBY_VERSION.to_f >= 2.0, sock.close_on_exec?)
44
+
38
45
  assert_kind_of Kgio::Socket, sock
39
46
  ready = IO.select(nil, [ sock ])
40
47
  assert_equal sock, ready[1][0]
@@ -50,6 +57,10 @@ class TestKgioTcpConnect < Test::Unit::TestCase
50
57
 
51
58
  def test_tcp_socket_new
52
59
  sock = Kgio::TCPSocket.new(@host, @port)
60
+
61
+ sock.respond_to?(:close_on_exec?) and
62
+ assert_equal(RUBY_VERSION.to_f >= 2.0, sock.close_on_exec?)
63
+
53
64
  assert_instance_of Kgio::TCPSocket, sock
54
65
  ready = IO.select(nil, [ sock ])
55
66
  assert_equal sock, ready[1][0]
data/test/test_tryopen.rb CHANGED
@@ -7,6 +7,10 @@ class TestTryopen < Test::Unit::TestCase
7
7
 
8
8
  def test_tryopen_success
9
9
  tmp = Kgio::File.tryopen(__FILE__)
10
+
11
+ tmp.respond_to?(:close_on_exec?) and
12
+ assert_equal(RUBY_VERSION.to_f >= 2.0, tmp.close_on_exec?)
13
+
10
14
  assert_kind_of File, tmp
11
15
  assert_equal File.read(__FILE__), tmp.read
12
16
  assert_equal __FILE__, tmp.path
@@ -34,6 +34,10 @@ class TestKgioUnixConnect < Test::Unit::TestCase
34
34
 
35
35
  def test_unix_socket_new
36
36
  sock = Kgio::UNIXSocket.new(@path)
37
+
38
+ sock.respond_to?(:close_on_exec?) and
39
+ assert_equal(RUBY_VERSION.to_f >= 2.0, sock.close_on_exec?)
40
+
37
41
  assert_instance_of Kgio::UNIXSocket, sock
38
42
  ready = IO.select(nil, [ sock ])
39
43
  assert_equal sock, ready[1][0]
@@ -42,6 +46,10 @@ class TestKgioUnixConnect < Test::Unit::TestCase
42
46
 
43
47
  def test_new
44
48
  sock = Kgio::Socket.new(@addr)
49
+
50
+ sock.respond_to?(:close_on_exec?) and
51
+ assert_equal(RUBY_VERSION.to_f >= 2.0, sock.close_on_exec?)
52
+
45
53
  assert_instance_of Kgio::Socket, sock
46
54
  ready = IO.select(nil, [ sock ])
47
55
  assert_equal sock, ready[1][0]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kgio
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 6
8
+ - 7
9
9
  - 0
10
- version: 2.6.0
10
+ version: 2.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - kgio hackers
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-15 00:00:00 Z
18
+ date: 2011-12-13 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: wrongdoc
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
173
  requirements: []
174
174
 
175
175
  rubyforge_project: rainbows
176
- rubygems_version: 1.8.5
176
+ rubygems_version: 1.8.11
177
177
  signing_key:
178
178
  specification_version: 3
179
179
  summary: kinder, gentler I/O for Ruby