sleepy_penguin 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -42,8 +42,8 @@ static struct timespec *value2timespec(struct timespec *ts, VALUE num)
42
42
  }}
43
43
  {
44
44
  VALUE tmp = rb_inspect(num);
45
- rb_raise(rb_eTypeError, "can't convert %s into timespec",
46
- StringValuePtr(tmp));
45
+ const char *str = StringValueCStr(tmp);
46
+ rb_raise(rb_eTypeError, "can't convert %s into timespec", str);
47
47
  }
48
48
  rb_bug("rb_raise() failed, timespec failed");
49
49
  return NULL;
data/test/helper.rb ADDED
@@ -0,0 +1,17 @@
1
+ $-w = $stdout.sync = $stderr.sync = Thread.abort_on_exception = true
2
+ gem 'minitest'
3
+ require 'minitest/autorun'
4
+ Testcase = begin
5
+ Minitest::Test # minitest 5
6
+ rescue NameError
7
+ Minitest::Unit::TestCase # minitest 4
8
+ end
9
+
10
+ def check_cloexec(io)
11
+ pipe = IO.pipe
12
+ rbimp = Fcntl::FD_CLOEXEC & pipe[0].fcntl(Fcntl::F_GETFD)
13
+ ours = Fcntl::FD_CLOEXEC & io.fcntl(Fcntl::F_GETFD)
14
+ assert_equal rbimp, ours, "CLOEXEC default does not match Ruby implementation"
15
+ ensure
16
+ pipe.each { |io| io.close }
17
+ end
@@ -1,9 +1,9 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  $-w = true
3
3
  Thread.abort_on_exception = true
4
4
  require 'sleepy_penguin/sp'
5
5
 
6
- class TestConstants < Test::Unit::TestCase
6
+ class TestConstants < Testcase
7
7
  def test_constants
8
8
  assert_equal SleepyPenguin::SLEEPY_PENGUIN_VERSION,
9
9
  SP::SLEEPY_PENGUIN_VERSION
data/test/test_epoll.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  require 'fcntl'
3
3
  require 'socket'
4
4
  require 'thread'
@@ -7,7 +7,7 @@ Thread.abort_on_exception = true
7
7
 
8
8
  require 'sleepy_penguin'
9
9
 
10
- class TestEpoll < Test::Unit::TestCase
10
+ class TestEpoll < Testcase
11
11
  include SleepyPenguin
12
12
 
13
13
  def setup
@@ -52,7 +52,7 @@ class TestEpoll < Test::Unit::TestCase
52
52
  @ep.close
53
53
  assert ! epdup.closed?
54
54
  pid = fork do
55
- exit(!epdup.closed? && @ep.closed?)
55
+ exit!(!epdup.closed? && @ep.closed?)
56
56
  end
57
57
  _, status = Process.waitpid2(pid)
58
58
  assert status.success?, status.inspect
@@ -87,7 +87,12 @@ class TestEpoll < Test::Unit::TestCase
87
87
  port = srv.addr[1]
88
88
  addr = Socket.pack_sockaddr_in(port, host)
89
89
  sock = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
90
- assert_raises(Errno::EINPROGRESS) { sock.connect_nonblock(addr) }
90
+ begin
91
+ sock.connect_nonblock(addr)
92
+ exc = nil
93
+ rescue Errno::EINPROGRESS => exc
94
+ end
95
+ assert_kind_of Errno::EINPROGRESS, exc
91
96
  IO.select(nil, [ sock ], [sock ])
92
97
  @ep.add(sock, epflags)
93
98
  tmp = []
@@ -343,11 +348,7 @@ class TestEpoll < Test::Unit::TestCase
343
348
  def test_new
344
349
  @ep.close
345
350
  io = Epoll.new.to_io
346
- if RUBY_VERSION.to_f >= 2.0
347
- assert_equal 1, io.fcntl(Fcntl::F_GETFD)
348
- else
349
- assert_equal 0, io.fcntl(Fcntl::F_GETFD)
350
- end
351
+ check_cloexec(io)
351
352
  end
352
353
 
353
354
  def test_delete
@@ -1,9 +1,9 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  $-w = true
3
3
 
4
4
  require 'sleepy_penguin'
5
5
 
6
- class TestEpollGC < Test::Unit::TestCase
6
+ class TestEpollGC < Testcase
7
7
  include SleepyPenguin
8
8
 
9
9
  def setup
@@ -1,4 +1,4 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  require 'fcntl'
3
3
  require 'socket'
4
4
  require 'thread'
@@ -6,7 +6,7 @@ $-w = true
6
6
  Thread.abort_on_exception = true
7
7
  require 'sleepy_penguin'
8
8
 
9
- class TestEpollIO < Test::Unit::TestCase
9
+ class TestEpollIO < Testcase
10
10
  include SleepyPenguin
11
11
 
12
12
  def setup
@@ -1,4 +1,4 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  begin
3
3
  require 'strace'
4
4
  rescue LoadError
@@ -7,7 +7,7 @@ $-w = true
7
7
 
8
8
  require 'sleepy_penguin'
9
9
 
10
- class TestEpollOptimizations < Test::Unit::TestCase
10
+ class TestEpollOptimizations < Testcase
11
11
  include SleepyPenguin
12
12
  IO_PURGATORY = []
13
13
 
data/test/test_eventfd.rb CHANGED
@@ -1,10 +1,10 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  require 'fcntl'
3
3
  $-w = true
4
4
 
5
5
  require 'sleepy_penguin'
6
6
 
7
- class TestEventFD < Test::Unit::TestCase
7
+ class TestEventFD < Testcase
8
8
  include SleepyPenguin
9
9
 
10
10
  def test_constants
@@ -20,11 +20,7 @@ class TestEventFD < Test::Unit::TestCase
20
20
  def test_new
21
21
  efd = EventFD.new 0
22
22
  assert_kind_of(IO, efd)
23
- if RUBY_VERSION.to_f >= 2.0
24
- assert_equal 1, efd.fcntl(Fcntl::F_GETFD)
25
- else
26
- assert_equal 0, efd.fcntl(Fcntl::F_GETFD)
27
- end
23
+ check_cloexec(efd)
28
24
  end
29
25
 
30
26
  def test_new_nonblock
data/test/test_inotify.rb CHANGED
@@ -1,11 +1,11 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  require 'fcntl'
3
3
  require 'tempfile'
4
4
  require 'set'
5
5
  $-w = true
6
6
  require 'sleepy_penguin'
7
7
 
8
- class TestInotify < Test::Unit::TestCase
8
+ class TestInotify < Testcase
9
9
  include SleepyPenguin
10
10
  attr_reader :ino
11
11
 
@@ -17,11 +17,7 @@ class TestInotify < Test::Unit::TestCase
17
17
  def test_new
18
18
  @ino = Inotify.new
19
19
  assert_kind_of(IO, ino)
20
- if RUBY_VERSION.to_f >= 2.0
21
- assert_equal 1, ino.fcntl(Fcntl::F_GETFD)
22
- else
23
- assert_equal 0, ino.fcntl(Fcntl::F_GETFD)
24
- end
20
+ check_cloexec(ino)
25
21
  end
26
22
 
27
23
  def test_constants
data/test/test_kqueue.rb CHANGED
@@ -1,9 +1,9 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  $-w = true
3
3
  Thread.abort_on_exception = true
4
4
  require 'sleepy_penguin'
5
5
 
6
- class TestKqueue < Test::Unit::TestCase
6
+ class TestKqueue < Testcase
7
7
  include SleepyPenguin
8
8
 
9
9
  def test_kqueue
@@ -1,9 +1,9 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  $-w = true
3
3
  Thread.abort_on_exception = true
4
4
  require 'sleepy_penguin'
5
5
 
6
- class TestKqueueIO < Test::Unit::TestCase
6
+ class TestKqueueIO < Testcase
7
7
  include SleepyPenguin
8
8
 
9
9
  def setup
data/test/test_timerfd.rb CHANGED
@@ -1,10 +1,10 @@
1
- require 'test/unit'
1
+ require './test/helper'
2
2
  require 'fcntl'
3
3
  $-w = true
4
4
 
5
5
  require 'sleepy_penguin'
6
6
 
7
- class TestTimerFD < Test::Unit::TestCase
7
+ class TestTimerFD < Testcase
8
8
  include SleepyPenguin
9
9
 
10
10
  def test_constants
@@ -15,11 +15,7 @@ class TestTimerFD < Test::Unit::TestCase
15
15
  def test_create
16
16
  tfd = TimerFD.new
17
17
  assert_kind_of(IO, tfd)
18
- if RUBY_VERSION.to_f >= 2.0
19
- assert_equal 1, tfd.fcntl(Fcntl::F_GETFD)
20
- else
21
- assert_equal 0, tfd.fcntl(Fcntl::F_GETFD)
22
- end
18
+ check_cloexec(tfd)
23
19
  end
24
20
 
25
21
  def test_create_nonblock
metadata CHANGED
@@ -1,61 +1,63 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sleepy_penguin
3
- version: !ruby/object:Gem::Version
4
- version: 3.2.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
5
  prerelease:
6
+ segments:
7
+ - 3
8
+ - 3
9
+ - 0
10
+ version: 3.3.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - sleepy_penguin hackers
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2013-07-16 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2013-12-30 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: wrongdoc
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '1.5'
22
- type: :development
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '1.5'
30
- - !ruby/object:Gem::Dependency
31
- name: strace_me
32
- requirement: !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
33
24
  none: false
34
- requirements:
25
+ requirements:
35
26
  - - ~>
36
- - !ruby/object:Gem::Version
37
- version: '1.0'
27
+ - !ruby/object:Gem::Version
28
+ hash: 5
29
+ segments:
30
+ - 1
31
+ - 5
32
+ version: "1.5"
38
33
  type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: strace_me
39
37
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
38
+ requirement: &id002 !ruby/object:Gem::Requirement
41
39
  none: false
42
- requirements:
40
+ requirements:
43
41
  - - ~>
44
- - !ruby/object:Gem::Version
45
- version: '1.0'
46
- description: ! 'sleepy_penguin provides access to newer, Linux-only system calls to
47
- wait
48
-
42
+ - !ruby/object:Gem::Version
43
+ hash: 15
44
+ segments:
45
+ - 1
46
+ - 0
47
+ version: "1.0"
48
+ type: :development
49
+ version_requirements: *id002
50
+ description: |-
51
+ sleepy_penguin provides access to newer, Linux-only system calls to wait
49
52
  on events from traditionally non-I/O sources. Bindings to the eventfd,
50
-
51
53
  timerfd, inotify, and epoll interfaces are provided. Experimental support
52
-
53
- for kqueue on FreeBSD (and likely OpenBSD/NetBSD) are also provided.'
54
+ for kqueue on FreeBSD (and likely OpenBSD/NetBSD) are also provided.
54
55
  email: sleepy.penguin@librelist.org
55
56
  executables: []
56
- extensions:
57
+
58
+ extensions:
57
59
  - ext/sleepy_penguin/extconf.rb
58
- extra_rdoc_files:
60
+ extra_rdoc_files:
59
61
  - LICENSE
60
62
  - README
61
63
  - TODO
@@ -73,10 +75,9 @@ extra_rdoc_files:
73
75
  - ext/sleepy_penguin/eventfd.c
74
76
  - ext/sleepy_penguin/init.c
75
77
  - ext/sleepy_penguin/inotify.c
76
- - ext/sleepy_penguin/signalfd.c
77
78
  - ext/sleepy_penguin/timerfd.c
78
79
  - ext/sleepy_penguin/kqueue.c
79
- files:
80
+ files:
80
81
  - .document
81
82
  - .gitignore
82
83
  - .manifest
@@ -99,11 +100,11 @@ files:
99
100
  - ext/sleepy_penguin/init.c
100
101
  - ext/sleepy_penguin/inotify.c
101
102
  - ext/sleepy_penguin/kqueue.c
103
+ - ext/sleepy_penguin/missing_clock_gettime.h
102
104
  - ext/sleepy_penguin/missing_epoll.h
103
105
  - ext/sleepy_penguin/missing_inotify.h
104
106
  - ext/sleepy_penguin/missing_rb_thread_fd_close.h
105
107
  - ext/sleepy_penguin/missing_rb_update_max_fd.h
106
- - ext/sleepy_penguin/signalfd.c
107
108
  - ext/sleepy_penguin/sleepy_penguin.h
108
109
  - ext/sleepy_penguin/timerfd.c
109
110
  - ext/sleepy_penguin/util.c
@@ -119,6 +120,7 @@ files:
119
120
  - pkg.mk
120
121
  - setup.rb
121
122
  - sleepy_penguin.gemspec
123
+ - test/helper.rb
122
124
  - test/test_constants.rb
123
125
  - test/test_epoll.rb
124
126
  - test/test_epoll_gc.rb
@@ -128,45 +130,48 @@ files:
128
130
  - test/test_inotify.rb
129
131
  - test/test_kqueue.rb
130
132
  - test/test_kqueue_io.rb
131
- - test/test_signalfd.rb
132
- - test/test_signalfd_siginfo.rb
133
133
  - test/test_timerfd.rb
134
134
  homepage: http://bogomips.org/sleepy_penguin/
135
- licenses:
135
+ licenses:
136
136
  - LGPLv2.1
137
137
  - LGPLv3
138
138
  post_install_message:
139
- rdoc_options:
139
+ rdoc_options:
140
140
  - -t
141
141
  - sleepy_penguin - Linux I/O events for Ruby
142
142
  - -W
143
143
  - http://bogomips.org/sleepy_penguin.git/tree/%s
144
- require_paths:
144
+ require_paths:
145
145
  - lib
146
- required_ruby_version: !ruby/object:Gem::Requirement
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
147
  none: false
148
- requirements:
149
- - - ! '>='
150
- - !ruby/object:Gem::Version
151
- version: '0'
152
- required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
156
  none: false
154
- requirements:
155
- - - ! '>='
156
- - !ruby/object:Gem::Version
157
- version: '0'
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ hash: 3
161
+ segments:
162
+ - 0
163
+ version: "0"
158
164
  requirements: []
165
+
159
166
  rubyforge_project: rainbows
160
- rubygems_version: 1.8.23
167
+ rubygems_version: 1.8.24
161
168
  signing_key:
162
169
  specification_version: 3
163
170
  summary: Linux I/O events for Ruby
164
- test_files:
171
+ test_files:
165
172
  - test/test_epoll_optimizations.rb
166
173
  - test/test_constants.rb
167
- - test/test_signalfd_siginfo.rb
168
174
  - test/test_epoll.rb
169
- - test/test_signalfd.rb
170
175
  - test/test_kqueue_io.rb
171
176
  - test/test_inotify.rb
172
177
  - test/test_kqueue.rb
@@ -1,342 +0,0 @@
1
- #ifdef HAVE_SYS_SIGNALFD_H
2
- #include "sleepy_penguin.h"
3
- #include <signal.h>
4
- #include <sys/signalfd.h>
5
- static VALUE ssi_members;
6
- static VALUE cSigInfo;
7
-
8
- /* converts a Symbol, String, or Fixnum to an integer signal */
9
- static int sig2int(VALUE sig)
10
- {
11
- static VALUE list;
12
- const char *ptr;
13
- long len;
14
-
15
- if (TYPE(sig) == T_FIXNUM)
16
- return FIX2INT(sig);
17
-
18
- sig = rb_obj_as_string(sig);
19
- len = RSTRING_LEN(sig);
20
- ptr = RSTRING_PTR(sig);
21
-
22
- if (len > 3 && !memcmp("SIG", ptr, 3))
23
- sig = rb_str_new(ptr + 3, len - 3);
24
-
25
- if (!list) {
26
- VALUE tmp = rb_const_get(rb_cObject, rb_intern("Signal"));
27
-
28
- list = rb_funcall(tmp, rb_intern("list"), 0, 0);
29
- rb_global_variable(&list);
30
- }
31
-
32
- sig = rb_hash_aref(list, sig);
33
- if (NIL_P(sig))
34
- rb_raise(rb_eArgError, "invalid signal: %s", ptr);
35
-
36
- return NUM2INT(sig);
37
- }
38
-
39
- /* fills sigset_t with an Array of signals */
40
- static void value2sigset(sigset_t *mask, VALUE set)
41
- {
42
- sigemptyset(mask);
43
-
44
- switch (TYPE(set)) {
45
- case T_NIL: return;
46
- case T_ARRAY: {
47
- VALUE *ptr = RARRAY_PTR(set);
48
- long len = RARRAY_LEN(set);
49
-
50
- while (--len >= 0)
51
- sigaddset(mask, sig2int(*ptr++));
52
- }
53
- break;
54
- default:
55
- sigaddset(mask, sig2int(set));
56
- }
57
- }
58
-
59
- static int cur_flags(int fd)
60
- {
61
- int rv = 0;
62
- #ifdef SFD_CLOEXEC
63
- {
64
- int flags = fcntl(fd, F_GETFD);
65
- if (flags == -1) rb_sys_fail("fcntl(F_GETFD)");
66
- if (flags & FD_CLOEXEC) rv |= SFD_CLOEXEC;
67
- }
68
- #endif
69
- #ifdef SFD_NONBLOCK
70
- {
71
- int flags = fcntl(fd, F_GETFL);
72
- if (flags == -1) rb_sys_fail("fcntl(F_GETFL)");
73
- if (flags & O_NONBLOCK) rv |= SFD_NONBLOCK;
74
- }
75
- #endif
76
- return rv;
77
- }
78
-
79
- /*
80
- * call-seq:
81
- * sfd.update!(signals[, flags]) -> sfd
82
- *
83
- * Updates the signal mask watched for by the given +sfd+.
84
- * Takes the same arguments as SignalFD.new.
85
- */
86
- static VALUE update_bang(int argc, VALUE *argv, VALUE self)
87
- {
88
- VALUE vmask, vflags;
89
- sigset_t mask;
90
- int flags;
91
- int fd = rb_sp_fileno(self);
92
- int rc;
93
-
94
- rb_scan_args(argc, argv, "02", &vmask, &vflags);
95
- flags = NIL_P(vflags) ? cur_flags(fd)
96
- : rb_sp_get_flags(self, vflags, 0);
97
- value2sigset(&mask, vmask);
98
-
99
- rc = signalfd(fd, &mask, flags);
100
- if (rc < 0)
101
- rb_sys_fail("signalfd");
102
- return self;
103
- }
104
-
105
- /*
106
- * call-seq:
107
- * SignalFD.new(signals[, flags]) -> SignalFD IO object
108
- *
109
- * Creates a new SignalFD object to watch given +signals+ with +flags+.
110
- *
111
- * +signals+ is an Array of signal names or a single signal name that
112
- * Signal.trap understands:
113
- *
114
- * signals = [ :USR1, "USR2" ]
115
- * signals = :USR1
116
- * signals = 15
117
- *
118
- * Starting with Linux 2.6.27, +flags+ may be a mask that consists of any
119
- * of the following:
120
- *
121
- * - :CLOEXEC - set the close-on-exec flag on the new object
122
- * - :NONBLOCK - set the non-blocking I/O flag on the new object
123
- */
124
- static VALUE s_new(int argc, VALUE *argv, VALUE klass)
125
- {
126
- VALUE vmask, vflags, rv;
127
- sigset_t mask;
128
- int flags;
129
- int fd;
130
-
131
- rb_scan_args(argc, argv, "02", &vmask, &vflags);
132
- flags = rb_sp_get_flags(klass, vflags, RB_SP_CLOEXEC(SFD_CLOEXEC));
133
- value2sigset(&mask, vmask);
134
-
135
- fd = signalfd(-1, &mask, flags);
136
- if (fd < 0) {
137
- if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
138
- rb_gc();
139
- fd = signalfd(-1, &mask, flags);
140
- }
141
- if (fd < 0)
142
- rb_sys_fail("signalfd");
143
- }
144
-
145
-
146
- rv = INT2FIX(fd);
147
- return rb_call_super(1, &rv);
148
- }
149
-
150
- static VALUE ssi_alloc(VALUE klass)
151
- {
152
- struct signalfd_siginfo *ssi = ALLOC(struct signalfd_siginfo);
153
-
154
- return Data_Wrap_Struct(klass, NULL, -1, ssi);
155
- }
156
-
157
- /* :nodoc: */
158
- static VALUE ssi_init(VALUE self)
159
- {
160
- struct signalfd_siginfo *ssi = DATA_PTR(self);
161
-
162
- memset(ssi, 0, sizeof(struct signalfd_siginfo));
163
- return self;
164
- }
165
-
166
- static VALUE sfd_read(void *args)
167
- {
168
- struct signalfd_siginfo *ssi = args;
169
- int fd = ssi->ssi_fd;
170
- ssize_t r = read(fd, ssi, sizeof(struct signalfd_siginfo));
171
-
172
- return (VALUE)r;
173
- }
174
-
175
- /*
176
- * call-seq:
177
- * sfd.take([nonblock]) -> SignalFD::SigInfo object or +nil+
178
- *
179
- * Returns the next SigInfo object representing a received signal.
180
- * If +nonblock+ is specified and true, this may return +nil+
181
- */
182
- static VALUE sfd_take(int argc, VALUE *argv, VALUE self)
183
- {
184
- VALUE rv = ssi_alloc(cSigInfo);
185
- struct signalfd_siginfo *ssi = DATA_PTR(rv);
186
- ssize_t r;
187
- int fd;
188
- VALUE nonblock;
189
-
190
- rb_scan_args(argc, argv, "01", &nonblock);
191
- fd = rb_sp_fileno(self);
192
- if (RTEST(nonblock))
193
- rb_sp_set_nonblock(fd);
194
- else
195
- blocking_io_prepare(fd);
196
- retry:
197
- ssi->ssi_fd = fd;
198
- r = (ssize_t)rb_sp_fd_region(sfd_read, ssi, fd);
199
- if (r < 0) {
200
- if (errno == EAGAIN && RTEST(nonblock))
201
- return Qnil;
202
- if (rb_sp_wait(rb_io_wait_readable, self, &fd))
203
- goto retry;
204
- rb_sys_fail("read(signalfd)");
205
- }
206
- if (r == 0)
207
- rb_eof_error(); /* does this ever happen? */
208
- return rv;
209
- }
210
-
211
- #define SSI_READER_FUNC(FN, FIELD) \
212
- static VALUE ssi_##FIELD(VALUE self) { \
213
- struct signalfd_siginfo *ssi = DATA_PTR(self); \
214
- return FN(ssi->ssi_##FIELD); \
215
- }
216
-
217
- SSI_READER_FUNC(UINT2NUM,signo)
218
- SSI_READER_FUNC(INT2NUM,errno)
219
- SSI_READER_FUNC(INT2NUM,code)
220
- SSI_READER_FUNC(UINT2NUM,pid)
221
- SSI_READER_FUNC(UINT2NUM,uid)
222
- SSI_READER_FUNC(INT2NUM,fd)
223
- SSI_READER_FUNC(UINT2NUM,tid)
224
- SSI_READER_FUNC(UINT2NUM,band)
225
- SSI_READER_FUNC(UINT2NUM,overrun)
226
- SSI_READER_FUNC(UINT2NUM,trapno)
227
- SSI_READER_FUNC(INT2NUM,status)
228
- SSI_READER_FUNC(INT2NUM,int)
229
- SSI_READER_FUNC(ULL2NUM,ptr)
230
- SSI_READER_FUNC(ULL2NUM,utime)
231
- SSI_READER_FUNC(ULL2NUM,stime)
232
- SSI_READER_FUNC(ULL2NUM,addr)
233
-
234
- void sleepy_penguin_init_signalfd(void)
235
- {
236
- VALUE mSleepyPenguin, cSignalFD;
237
-
238
- mSleepyPenguin = rb_define_module("SleepyPenguin");
239
-
240
- /*
241
- * Document-class: SleepyPenguin::SignalFD
242
- *
243
- * Use of this class is NOT recommended. Ruby itself has a great
244
- * signal handling API and its implementation conflicts with this.
245
- *
246
- * This class is currently disabled and the documentation is only
247
- * provided to describe what it would look like.
248
- *
249
- * A SignalFD is an IO object for accepting signals. It provides
250
- * an alternative to Signal.trap that may be monitored using
251
- * IO.select or Epoll.
252
- *
253
- * SignalFD appears interact unpredictably with YARV (Ruby 1.9) signal
254
- * handling and has been unreliable in our testing. Since Ruby has a
255
- * decent signal handling interface anyways, this class is less useful
256
- * than signalfd() in a C-only environment.
257
- *
258
- * It is not supported at all.
259
- */
260
- cSignalFD = rb_define_class_under(mSleepyPenguin, "SignalFD", rb_cIO);
261
-
262
- /*
263
- * Document-class: SleepyPenguin::SignalFD::SigInfo
264
- *
265
- * This class is returned by SignalFD#take. It consists of the
266
- * following read-only members:
267
- *
268
- * - signo - signal number
269
- * - errno - error number
270
- * - code - signal code
271
- * - pid - PID of sender
272
- * - uid - real UID of sender
273
- * - fd - file descriptor (SIGIO)
274
- * - tid - kernel timer ID (POSIX timers)
275
- * - band - band event (SIGIO)
276
- * - overrun - POSIX timer overrun count
277
- * - trapno - trap number that caused hardware-generated signal
278
- * - exit status or signal (SIGCHLD)
279
- * - int - integer sent by sigqueue(2)
280
- * - ptr - Pointer sent by sigqueue(2)
281
- * - utime - User CPU time consumed (SIGCHLD)
282
- * - stime - System CPU time consumed (SIGCHLD)
283
- * - addr - address that generated a hardware-generated signal
284
- */
285
- cSigInfo = rb_define_class_under(cSignalFD, "SigInfo", rb_cObject);
286
- rb_define_alloc_func(cSigInfo, ssi_alloc);
287
- rb_define_private_method(cSigInfo, "initialize", ssi_init, 0);
288
-
289
- /* TODO: si_code values */
290
-
291
- rb_define_singleton_method(cSignalFD, "new", s_new, -1);
292
- #ifdef SFD_NONBLOCK
293
- NODOC_CONST(cSignalFD, "NONBLOCK", INT2NUM(SFD_NONBLOCK));
294
- #endif
295
- #ifdef SFD_CLOEXEC
296
- NODOC_CONST(cSignalFD, "CLOEXEC", INT2NUM(SFD_CLOEXEC));
297
- #endif
298
-
299
- rb_define_method(cSignalFD, "take", sfd_take, -1);
300
- rb_define_method(cSignalFD, "update!", update_bang, -1);
301
- ssi_members = rb_ary_new();
302
-
303
- NODOC_CONST(cSigInfo, "MEMBERS", ssi_members);
304
-
305
- /*
306
- * the minimum signal number for real-time signals,
307
- * 34 on NPTL-based systems
308
- */
309
- rb_define_const(cSignalFD, "RTMIN", INT2NUM(SIGRTMIN));
310
-
311
- /*
312
- * the maximum signal number for real-time signals,
313
- * 64 on NPTL-based systems
314
- */
315
- rb_define_const(cSignalFD, "RTMAX", INT2NUM(SIGRTMAX));
316
-
317
- #define SSI_READER(FIELD) do { \
318
- rb_define_method(cSigInfo, #FIELD, ssi_##FIELD, 0); \
319
- rb_ary_push(ssi_members, ID2SYM(rb_intern(#FIELD))); \
320
- } while (0)
321
-
322
- SSI_READER(signo);
323
- SSI_READER(errno);
324
- SSI_READER(code);
325
- SSI_READER(pid);
326
- SSI_READER(uid);
327
- SSI_READER(fd);
328
- SSI_READER(tid);
329
- SSI_READER(band);
330
- SSI_READER(overrun);
331
- SSI_READER(trapno);
332
- SSI_READER(status);
333
- SSI_READER(int);
334
- SSI_READER(ptr);
335
- SSI_READER(utime);
336
- SSI_READER(stime);
337
- SSI_READER(addr);
338
- rb_obj_freeze(ssi_members);
339
-
340
- rb_require("sleepy_penguin/signalfd/sig_info");
341
- }
342
- #endif /* HAVE_SYS_SIGNALFD_H */