eventmachine-with-ipv6 1.0.0.beta.4.ipv6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/.gitignore +21 -0
  2. data/.yardopts +7 -0
  3. data/FORK.md +47 -0
  4. data/GNU +281 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +60 -0
  7. data/README.md +109 -0
  8. data/Rakefile +20 -0
  9. data/docs/DocumentationGuidesIndex.md +27 -0
  10. data/docs/GettingStarted.md +521 -0
  11. data/docs/old/ChangeLog +211 -0
  12. data/docs/old/DEFERRABLES +246 -0
  13. data/docs/old/EPOLL +141 -0
  14. data/docs/old/INSTALL +13 -0
  15. data/docs/old/KEYBOARD +42 -0
  16. data/docs/old/LEGAL +25 -0
  17. data/docs/old/LIGHTWEIGHT_CONCURRENCY +130 -0
  18. data/docs/old/PURE_RUBY +75 -0
  19. data/docs/old/RELEASE_NOTES +94 -0
  20. data/docs/old/SMTP +4 -0
  21. data/docs/old/SPAWNED_PROCESSES +148 -0
  22. data/docs/old/TODO +8 -0
  23. data/eventmachine.gemspec +50 -0
  24. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  25. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  26. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  27. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  28. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  29. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  30. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  31. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  32. data/examples/old/ex_channel.rb +43 -0
  33. data/examples/old/ex_queue.rb +2 -0
  34. data/examples/old/ex_tick_loop_array.rb +15 -0
  35. data/examples/old/ex_tick_loop_counter.rb +32 -0
  36. data/examples/old/helper.rb +2 -0
  37. data/ext/binder.cpp +124 -0
  38. data/ext/binder.h +46 -0
  39. data/ext/cmain.cpp +858 -0
  40. data/ext/ed.cpp +1992 -0
  41. data/ext/ed.h +423 -0
  42. data/ext/em.cpp +2358 -0
  43. data/ext/em.h +245 -0
  44. data/ext/eventmachine.h +127 -0
  45. data/ext/extconf.rb +166 -0
  46. data/ext/fastfilereader/extconf.rb +94 -0
  47. data/ext/fastfilereader/mapper.cpp +214 -0
  48. data/ext/fastfilereader/mapper.h +59 -0
  49. data/ext/fastfilereader/rubymain.cpp +127 -0
  50. data/ext/kb.cpp +79 -0
  51. data/ext/page.cpp +107 -0
  52. data/ext/page.h +51 -0
  53. data/ext/pipe.cpp +347 -0
  54. data/ext/project.h +155 -0
  55. data/ext/rubymain.cpp +1280 -0
  56. data/ext/ssl.cpp +468 -0
  57. data/ext/ssl.h +94 -0
  58. data/java/.classpath +8 -0
  59. data/java/.project +17 -0
  60. data/java/src/com/rubyeventmachine/EmReactor.java +571 -0
  61. data/java/src/com/rubyeventmachine/EmReactorException.java +40 -0
  62. data/java/src/com/rubyeventmachine/EventableChannel.java +69 -0
  63. data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +189 -0
  64. data/java/src/com/rubyeventmachine/EventableSocketChannel.java +364 -0
  65. data/lib/em/buftok.rb +110 -0
  66. data/lib/em/callback.rb +58 -0
  67. data/lib/em/channel.rb +64 -0
  68. data/lib/em/completion.rb +304 -0
  69. data/lib/em/connection.rb +728 -0
  70. data/lib/em/deferrable.rb +210 -0
  71. data/lib/em/deferrable/pool.rb +2 -0
  72. data/lib/em/file_watch.rb +73 -0
  73. data/lib/em/future.rb +61 -0
  74. data/lib/em/iterator.rb +270 -0
  75. data/lib/em/messages.rb +66 -0
  76. data/lib/em/pool.rb +151 -0
  77. data/lib/em/process_watch.rb +45 -0
  78. data/lib/em/processes.rb +123 -0
  79. data/lib/em/protocols.rb +36 -0
  80. data/lib/em/protocols/header_and_content.rb +138 -0
  81. data/lib/em/protocols/httpclient.rb +279 -0
  82. data/lib/em/protocols/httpclient2.rb +600 -0
  83. data/lib/em/protocols/line_and_text.rb +125 -0
  84. data/lib/em/protocols/line_protocol.rb +29 -0
  85. data/lib/em/protocols/linetext2.rb +161 -0
  86. data/lib/em/protocols/memcache.rb +331 -0
  87. data/lib/em/protocols/object_protocol.rb +46 -0
  88. data/lib/em/protocols/postgres3.rb +246 -0
  89. data/lib/em/protocols/saslauth.rb +175 -0
  90. data/lib/em/protocols/smtpclient.rb +365 -0
  91. data/lib/em/protocols/smtpserver.rb +640 -0
  92. data/lib/em/protocols/socks4.rb +66 -0
  93. data/lib/em/protocols/stomp.rb +202 -0
  94. data/lib/em/protocols/tcptest.rb +54 -0
  95. data/lib/em/pure_ruby.rb +1017 -0
  96. data/lib/em/queue.rb +71 -0
  97. data/lib/em/resolver.rb +195 -0
  98. data/lib/em/spawnable.rb +84 -0
  99. data/lib/em/streamer.rb +118 -0
  100. data/lib/em/threaded_resource.rb +90 -0
  101. data/lib/em/tick_loop.rb +85 -0
  102. data/lib/em/timers.rb +61 -0
  103. data/lib/em/version.rb +3 -0
  104. data/lib/eventmachine.rb +1517 -0
  105. data/lib/jeventmachine.rb +279 -0
  106. data/rakelib/cpp.rake_example +77 -0
  107. data/rakelib/package.rake +98 -0
  108. data/rakelib/test.rake +8 -0
  109. data/tests/client.crt +31 -0
  110. data/tests/client.key +51 -0
  111. data/tests/em_test_helper.rb +64 -0
  112. data/tests/test_attach.rb +126 -0
  113. data/tests/test_basic.rb +294 -0
  114. data/tests/test_channel.rb +62 -0
  115. data/tests/test_completion.rb +177 -0
  116. data/tests/test_connection_count.rb +33 -0
  117. data/tests/test_defer.rb +18 -0
  118. data/tests/test_deferrable.rb +35 -0
  119. data/tests/test_epoll.rb +134 -0
  120. data/tests/test_error_handler.rb +38 -0
  121. data/tests/test_exc.rb +28 -0
  122. data/tests/test_file_watch.rb +65 -0
  123. data/tests/test_futures.rb +170 -0
  124. data/tests/test_get_sock_opt.rb +37 -0
  125. data/tests/test_handler_check.rb +35 -0
  126. data/tests/test_hc.rb +155 -0
  127. data/tests/test_httpclient.rb +190 -0
  128. data/tests/test_httpclient2.rb +128 -0
  129. data/tests/test_inactivity_timeout.rb +54 -0
  130. data/tests/test_ipv4.rb +128 -0
  131. data/tests/test_ipv6.rb +135 -0
  132. data/tests/test_kb.rb +34 -0
  133. data/tests/test_ltp.rb +138 -0
  134. data/tests/test_ltp2.rb +288 -0
  135. data/tests/test_next_tick.rb +104 -0
  136. data/tests/test_object_protocol.rb +36 -0
  137. data/tests/test_pause.rb +78 -0
  138. data/tests/test_pending_connect_timeout.rb +52 -0
  139. data/tests/test_pool.rb +194 -0
  140. data/tests/test_process_watch.rb +48 -0
  141. data/tests/test_processes.rb +133 -0
  142. data/tests/test_proxy_connection.rb +168 -0
  143. data/tests/test_pure.rb +88 -0
  144. data/tests/test_queue.rb +50 -0
  145. data/tests/test_resolver.rb +55 -0
  146. data/tests/test_running.rb +14 -0
  147. data/tests/test_sasl.rb +47 -0
  148. data/tests/test_send_file.rb +217 -0
  149. data/tests/test_servers.rb +33 -0
  150. data/tests/test_set_sock_opt.rb +41 -0
  151. data/tests/test_shutdown_hooks.rb +23 -0
  152. data/tests/test_smtpclient.rb +55 -0
  153. data/tests/test_smtpserver.rb +57 -0
  154. data/tests/test_spawn.rb +293 -0
  155. data/tests/test_ssl_args.rb +78 -0
  156. data/tests/test_ssl_methods.rb +48 -0
  157. data/tests/test_ssl_verify.rb +82 -0
  158. data/tests/test_threaded_resource.rb +53 -0
  159. data/tests/test_tick_loop.rb +59 -0
  160. data/tests/test_timers.rb +123 -0
  161. data/tests/test_ud.rb +8 -0
  162. data/tests/test_udp46.rb +54 -0
  163. data/tests/test_unbind_reason.rb +48 -0
  164. metadata +319 -0
@@ -0,0 +1,155 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: project.h
6
+ Date: 06Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+
21
+ #ifndef __Project__H_
22
+ #define __Project__H_
23
+
24
+
25
+ #ifdef OS_WIN32
26
+ #pragma warning(disable:4786)
27
+ #endif
28
+
29
+ #include <iostream>
30
+ #include <map>
31
+ #include <set>
32
+ #include <vector>
33
+ #include <deque>
34
+ #include <string>
35
+ #include <sstream>
36
+ #include <stdexcept>
37
+
38
+
39
+ #ifdef OS_UNIX
40
+ #include <signal.h>
41
+ #include <netdb.h>
42
+ #include <time.h>
43
+ #include <sys/time.h>
44
+ #include <sys/types.h>
45
+ #include <sys/stat.h>
46
+ #include <sys/socket.h>
47
+ #include <sys/un.h>
48
+ #include <sys/resource.h>
49
+ #include <sys/wait.h>
50
+ #include <assert.h>
51
+ #include <unistd.h>
52
+ #include <fcntl.h>
53
+ #include <errno.h>
54
+ #include <netinet/in.h>
55
+ #include <netinet/tcp.h>
56
+ #include <arpa/inet.h>
57
+ #include <pwd.h>
58
+ #include <string.h>
59
+ typedef int SOCKET;
60
+ #define INVALID_SOCKET -1
61
+ #define SOCKET_ERROR -1
62
+ #ifdef OS_SOLARIS8
63
+ #include <strings.h>
64
+ #include <sys/un.h>
65
+ #ifndef AF_LOCAL
66
+ #define AF_LOCAL AF_UNIX
67
+ #endif
68
+ // INADDR_NONE is undefined on Solaris < 8. Thanks to Brett Eisenberg and Tim Pease.
69
+ #ifndef INADDR_NONE
70
+ #define INADDR_NONE ((unsigned long)-1)
71
+ #endif
72
+ #endif /* OS_SOLARIS8 */
73
+
74
+ #ifdef _AIX
75
+ #include <strings.h>
76
+ #ifndef AF_LOCAL
77
+ #define AF_LOCAL AF_UNIX
78
+ #endif
79
+ #endif /* _AIX */
80
+
81
+ #endif /* OS_UNIX */
82
+
83
+ #ifdef OS_WIN32
84
+ // 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
85
+ #define FD_SETSIZE 1024
86
+
87
+ #define WIN32_LEAN_AND_MEAN
88
+ #include <windows.h>
89
+ #include <winsock2.h>
90
+ #include <ws2tcpip.h>
91
+ #include <rpc.h>
92
+ #include <fcntl.h>
93
+ #include <assert.h>
94
+
95
+ typedef int socklen_t;
96
+ typedef int pid_t;
97
+ #endif
98
+
99
+ #if !defined(_MSC_VER) || _MSC_VER > 1500
100
+ #include <stdint.h>
101
+ #endif
102
+
103
+ using namespace std;
104
+
105
+ #ifdef WITH_SSL
106
+ #include <openssl/ssl.h>
107
+ #include <openssl/err.h>
108
+ #endif
109
+
110
+ #ifdef HAVE_EPOLL
111
+ #include <sys/epoll.h>
112
+ #endif
113
+
114
+ #ifdef HAVE_KQUEUE
115
+ #include <sys/event.h>
116
+ #include <sys/queue.h>
117
+ #endif
118
+
119
+ #ifdef HAVE_INOTIFY
120
+ #include <sys/inotify.h>
121
+ #endif
122
+
123
+ #ifdef HAVE_OLD_INOTIFY
124
+ #include <sys/syscall.h>
125
+ #include <linux/inotify.h>
126
+ static inline int inotify_init (void) { return syscall (__NR_inotify_init); }
127
+ static inline int inotify_add_watch (int fd, const char *name, __u32 mask) { return syscall (__NR_inotify_add_watch, fd, name, mask); }
128
+ static inline int inotify_rm_watch (int fd, __u32 wd) { return syscall (__NR_inotify_rm_watch, fd, wd); }
129
+ #define HAVE_INOTIFY 1
130
+ #endif
131
+
132
+ #ifdef HAVE_INOTIFY
133
+ #define INOTIFY_EVENT_SIZE (sizeof(struct inotify_event))
134
+ #endif
135
+
136
+ #ifdef HAVE_WRITEV
137
+ #include <sys/uio.h>
138
+ #endif
139
+
140
+ #if __cplusplus
141
+ extern "C" {
142
+ #endif
143
+ typedef void (*EMCallback)(const unsigned long, int, const char*, const unsigned long);
144
+ #if __cplusplus
145
+ }
146
+ #endif
147
+
148
+ #include "binder.h"
149
+ #include "em.h"
150
+ #include "ed.h"
151
+ #include "page.h"
152
+ #include "ssl.h"
153
+ #include "eventmachine.h"
154
+
155
+ #endif // __Project__H_
@@ -0,0 +1,1280 @@
1
+ /*****************************************************************************
2
+
3
+ $Id$
4
+
5
+ File: rubymain.cpp
6
+ Date: 06Apr06
7
+
8
+ Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
9
+ Gmail: blackhedd
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of either: 1) the GNU General Public License
13
+ as published by the Free Software Foundation; either version 2 of the
14
+ License, or (at your option) any later version; or 2) Ruby's License.
15
+
16
+ See the file COPYING for complete licensing information.
17
+
18
+ *****************************************************************************/
19
+
20
+ #include "project.h"
21
+ #include "eventmachine.h"
22
+ #include <ruby.h>
23
+
24
+ #ifndef RFLOAT_VALUE
25
+ #define RFLOAT_VALUE(arg) RFLOAT(arg)->value
26
+ #endif
27
+
28
+ /*******
29
+ Statics
30
+ *******/
31
+
32
+ static VALUE EmModule;
33
+ static VALUE EmConnection;
34
+ static VALUE EmConnsHash;
35
+ static VALUE EmTimersHash;
36
+
37
+ static VALUE EM_eConnectionError;
38
+ static VALUE EM_eUnknownTimerFired;
39
+ static VALUE EM_eConnectionNotBound;
40
+ static VALUE EM_eUnsupported;
41
+
42
+ static VALUE Intern_at_signature;
43
+ static VALUE Intern_at_timers;
44
+ static VALUE Intern_at_conns;
45
+ static VALUE Intern_at_error_handler;
46
+ static VALUE Intern_event_callback;
47
+ static VALUE Intern_run_deferred_callbacks;
48
+ static VALUE Intern_delete;
49
+ static VALUE Intern_call;
50
+ static VALUE Intern_receive_data;
51
+ static VALUE Intern_receive_error;
52
+ static VALUE Intern_ssl_handshake_completed;
53
+ static VALUE Intern_ssl_verify_peer;
54
+ static VALUE Intern_notify_readable;
55
+ static VALUE Intern_notify_writable;
56
+ static VALUE Intern_proxy_target_unbound;
57
+ static VALUE Intern_proxy_completed;
58
+ static VALUE Intern_connection_completed;
59
+
60
+ static VALUE rb_cProcStatus;
61
+
62
+ struct em_event {
63
+ unsigned long signature;
64
+ int event;
65
+ const char *data_str;
66
+ unsigned long data_num;
67
+ };
68
+
69
+ static inline VALUE ensure_conn(const unsigned long signature)
70
+ {
71
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
72
+ if (conn == Qnil)
73
+ rb_raise (EM_eConnectionNotBound, "unknown connection: %lu", signature);
74
+ return conn;
75
+ }
76
+
77
+
78
+ /****************
79
+ t_event_callback
80
+ ****************/
81
+
82
+ static inline void event_callback (struct em_event* e)
83
+ {
84
+ const unsigned long signature = e->signature;
85
+ int event = e->event;
86
+ const char *data_str = e->data_str;
87
+ const unsigned long data_num = e->data_num;
88
+
89
+ switch (event) {
90
+ case EM_CONNECTION_READ:
91
+ {
92
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
93
+ if (conn == Qnil)
94
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
95
+ rb_funcall (conn, Intern_receive_data, 1, rb_str_new (data_str, data_num));
96
+ return;
97
+ }
98
+ case EM_CONNECTION_SENDERROR:
99
+ {
100
+ VALUE conn = rb_hash_aref (EmConnsHash, ULONG2NUM (signature));
101
+ if (conn == Qnil)
102
+ rb_raise (EM_eConnectionNotBound, "received %lu bytes of data for unknown signature: %lu", data_num, signature);
103
+ rb_funcall (conn, Intern_receive_error, 1, rb_str_new (data_str, data_num));
104
+ return;
105
+ }
106
+ case EM_CONNECTION_ACCEPTED:
107
+ {
108
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
109
+ return;
110
+ }
111
+ case EM_CONNECTION_UNBOUND:
112
+ {
113
+ rb_funcall (EmModule, Intern_event_callback, 3, ULONG2NUM(signature), INT2FIX(event), ULONG2NUM(data_num));
114
+ return;
115
+ }
116
+ case EM_CONNECTION_COMPLETED:
117
+ {
118
+ VALUE conn = ensure_conn(signature);
119
+ rb_funcall (conn, Intern_connection_completed, 0);
120
+ return;
121
+ }
122
+ case EM_CONNECTION_NOTIFY_READABLE:
123
+ {
124
+ VALUE conn = ensure_conn(signature);
125
+ rb_funcall (conn, Intern_notify_readable, 0);
126
+ return;
127
+ }
128
+ case EM_CONNECTION_NOTIFY_WRITABLE:
129
+ {
130
+ VALUE conn = ensure_conn(signature);
131
+ rb_funcall (conn, Intern_notify_writable, 0);
132
+ return;
133
+ }
134
+ case EM_LOOPBREAK_SIGNAL:
135
+ {
136
+ rb_funcall (EmModule, Intern_run_deferred_callbacks, 0);
137
+ return;
138
+ }
139
+ case EM_TIMER_FIRED:
140
+ {
141
+ VALUE timer = rb_funcall (EmTimersHash, Intern_delete, 1, ULONG2NUM (data_num));
142
+ if (timer == Qnil) {
143
+ rb_raise (EM_eUnknownTimerFired, "no such timer: %lu", data_num);
144
+ } else if (timer == Qfalse) {
145
+ /* Timer Canceled */
146
+ } else {
147
+ rb_funcall (timer, Intern_call, 0);
148
+ }
149
+ return;
150
+ }
151
+ #ifdef WITH_SSL
152
+ case EM_SSL_HANDSHAKE_COMPLETED:
153
+ {
154
+ VALUE conn = ensure_conn(signature);
155
+ rb_funcall (conn, Intern_ssl_handshake_completed, 0);
156
+ return;
157
+ }
158
+ case EM_SSL_VERIFY:
159
+ {
160
+ VALUE conn = ensure_conn(signature);
161
+ VALUE should_accept = rb_funcall (conn, Intern_ssl_verify_peer, 1, rb_str_new(data_str, data_num));
162
+ if (RTEST(should_accept))
163
+ evma_accept_ssl_peer (signature);
164
+ return;
165
+ }
166
+ #endif
167
+ case EM_PROXY_TARGET_UNBOUND:
168
+ {
169
+ VALUE conn = ensure_conn(signature);
170
+ rb_funcall (conn, Intern_proxy_target_unbound, 0);
171
+ return;
172
+ }
173
+ case EM_PROXY_COMPLETED:
174
+ {
175
+ VALUE conn = ensure_conn(signature);
176
+ rb_funcall (conn, Intern_proxy_completed, 0);
177
+ return;
178
+ }
179
+ }
180
+ }
181
+
182
+ /*******************
183
+ event_error_handler
184
+ *******************/
185
+
186
+ static void event_error_handler(VALUE unused, VALUE err)
187
+ {
188
+ VALUE error_handler = rb_ivar_get(EmModule, Intern_at_error_handler);
189
+ rb_funcall (error_handler, Intern_call, 1, err);
190
+ }
191
+
192
+ /**********************
193
+ event_callback_wrapper
194
+ **********************/
195
+
196
+ static void event_callback_wrapper (const unsigned long signature, int event, const char *data_str, const unsigned long data_num)
197
+ {
198
+ struct em_event e;
199
+ e.signature = signature;
200
+ e.event = event;
201
+ e.data_str = data_str;
202
+ e.data_num = data_num;
203
+
204
+ if (!rb_ivar_defined(EmModule, Intern_at_error_handler))
205
+ event_callback(&e);
206
+ else
207
+ rb_rescue((VALUE (*)(ANYARGS))event_callback, (VALUE)&e, (VALUE (*)(ANYARGS))event_error_handler, Qnil);
208
+ }
209
+
210
+ /**************************
211
+ t_initialize_event_machine
212
+ **************************/
213
+
214
+ static VALUE t_initialize_event_machine (VALUE self)
215
+ {
216
+ EmConnsHash = rb_ivar_get (EmModule, Intern_at_conns);
217
+ EmTimersHash = rb_ivar_get (EmModule, Intern_at_timers);
218
+ assert(EmConnsHash != Qnil);
219
+ assert(EmTimersHash != Qnil);
220
+ evma_initialize_library ((EMCallback)event_callback_wrapper);
221
+ return Qnil;
222
+ }
223
+
224
+
225
+
226
+ /*****************************
227
+ t_run_machine_without_threads
228
+ *****************************/
229
+
230
+ static VALUE t_run_machine_without_threads (VALUE self)
231
+ {
232
+ evma_run_machine();
233
+ return Qnil;
234
+ }
235
+
236
+
237
+ /*******************
238
+ t_add_oneshot_timer
239
+ *******************/
240
+
241
+ static VALUE t_add_oneshot_timer (VALUE self, VALUE interval)
242
+ {
243
+ const unsigned long f = evma_install_oneshot_timer (FIX2INT (interval));
244
+ if (!f)
245
+ rb_raise (rb_eRuntimeError, "ran out of timers; use #set_max_timers to increase limit");
246
+ return ULONG2NUM (f);
247
+ }
248
+
249
+
250
+ /**************
251
+ t_start_server
252
+ **************/
253
+
254
+ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
255
+ {
256
+ const unsigned long f = evma_create_tcp_server (StringValuePtr(server), FIX2INT(port));
257
+ if (!f)
258
+ rb_raise (rb_eRuntimeError, "no acceptor (port is in use or requires root privileges)");
259
+ return ULONG2NUM (f);
260
+ }
261
+
262
+ /*************
263
+ t_stop_server
264
+ *************/
265
+
266
+ static VALUE t_stop_server (VALUE self, VALUE signature)
267
+ {
268
+ evma_stop_tcp_server (NUM2ULONG (signature));
269
+ return Qnil;
270
+ }
271
+
272
+
273
+ /*******************
274
+ t_start_unix_server
275
+ *******************/
276
+
277
+ static VALUE t_start_unix_server (VALUE self, VALUE filename)
278
+ {
279
+ const unsigned long f = evma_create_unix_domain_server (StringValuePtr(filename));
280
+ if (!f)
281
+ rb_raise (rb_eRuntimeError, "no unix-domain acceptor");
282
+ return ULONG2NUM (f);
283
+ }
284
+
285
+
286
+
287
+ /***********
288
+ t_send_data
289
+ ***********/
290
+
291
+ static VALUE t_send_data (VALUE self, VALUE signature, VALUE data, VALUE data_length)
292
+ {
293
+ int b = evma_send_data_to_connection (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length));
294
+ return INT2NUM (b);
295
+ }
296
+
297
+
298
+ /***********
299
+ t_start_tls
300
+ ***********/
301
+
302
+ static VALUE t_start_tls (VALUE self, VALUE signature)
303
+ {
304
+ evma_start_tls (NUM2ULONG (signature));
305
+ return Qnil;
306
+ }
307
+
308
+ /***************
309
+ t_set_tls_parms
310
+ ***************/
311
+
312
+ static VALUE t_set_tls_parms (VALUE self, VALUE signature, VALUE privkeyfile, VALUE certchainfile, VALUE verify_peer)
313
+ {
314
+ /* set_tls_parms takes a series of positional arguments for specifying such things
315
+ * as private keys and certificate chains.
316
+ * It's expected that the parameter list will grow as we add more supported features.
317
+ * ALL of these parameters are optional, and can be specified as empty or NULL strings.
318
+ */
319
+ evma_set_tls_parms (NUM2ULONG (signature), StringValuePtr (privkeyfile), StringValuePtr (certchainfile), (verify_peer == Qtrue ? 1 : 0));
320
+ return Qnil;
321
+ }
322
+
323
+ /***************
324
+ t_get_peer_cert
325
+ ***************/
326
+
327
+ static VALUE t_get_peer_cert (VALUE self, VALUE signature)
328
+ {
329
+ VALUE ret = Qnil;
330
+
331
+ #ifdef WITH_SSL
332
+ X509 *cert = NULL;
333
+ BUF_MEM *buf;
334
+ BIO *out;
335
+
336
+ cert = evma_get_peer_cert (NUM2ULONG (signature));
337
+
338
+ if (cert != NULL) {
339
+ out = BIO_new(BIO_s_mem());
340
+ PEM_write_bio_X509(out, cert);
341
+ BIO_get_mem_ptr(out, &buf);
342
+ ret = rb_str_new(buf->data, buf->length);
343
+ X509_free(cert);
344
+ BUF_MEM_free(buf);
345
+ }
346
+ #endif
347
+
348
+ return ret;
349
+ }
350
+
351
+ /**************
352
+ t_get_peername
353
+ **************/
354
+
355
+ static VALUE t_get_peername (VALUE self, VALUE signature)
356
+ {
357
+ char buf[1024];
358
+ socklen_t len = sizeof buf;
359
+ if (evma_get_peername (NUM2ULONG (signature), (struct sockaddr_storage*)buf, &len)) {
360
+ return rb_str_new (buf, len);
361
+ }
362
+
363
+ return Qnil;
364
+ }
365
+
366
+ /**************
367
+ t_get_sockname
368
+ **************/
369
+
370
+ static VALUE t_get_sockname (VALUE self, VALUE signature)
371
+ {
372
+ char buf[1024];
373
+ socklen_t len = sizeof buf;
374
+ if (evma_get_sockname (NUM2ULONG (signature), (struct sockaddr_storage*)buf, &len)) {
375
+ return rb_str_new (buf, len);
376
+ }
377
+
378
+ return Qnil;
379
+ }
380
+
381
+ /********************
382
+ t_get_subprocess_pid
383
+ ********************/
384
+
385
+ static VALUE t_get_subprocess_pid (VALUE self, VALUE signature)
386
+ {
387
+ pid_t pid;
388
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
389
+ return INT2NUM (pid);
390
+ }
391
+
392
+ return Qnil;
393
+ }
394
+
395
+ /***********************
396
+ t_get_subprocess_status
397
+ ***********************/
398
+
399
+ static VALUE t_get_subprocess_status (VALUE self, VALUE signature)
400
+ {
401
+ VALUE proc_status = Qnil;
402
+
403
+ int status;
404
+ pid_t pid;
405
+
406
+ if (evma_get_subprocess_status (NUM2ULONG (signature), &status)) {
407
+ if (evma_get_subprocess_pid (NUM2ULONG (signature), &pid)) {
408
+ proc_status = rb_obj_alloc(rb_cProcStatus);
409
+ rb_iv_set(proc_status, "status", INT2FIX(status));
410
+ rb_iv_set(proc_status, "pid", INT2FIX(pid));
411
+ }
412
+ }
413
+
414
+ return proc_status;
415
+ }
416
+
417
+ /**********************
418
+ t_get_connection_count
419
+ **********************/
420
+
421
+ static VALUE t_get_connection_count (VALUE self)
422
+ {
423
+ return INT2NUM(evma_get_connection_count());
424
+ }
425
+
426
+ /*****************************
427
+ t_get_comm_inactivity_timeout
428
+ *****************************/
429
+
430
+ static VALUE t_get_comm_inactivity_timeout (VALUE self, VALUE signature)
431
+ {
432
+ return rb_float_new(evma_get_comm_inactivity_timeout(NUM2ULONG (signature)));
433
+ }
434
+
435
+ /*****************************
436
+ t_set_comm_inactivity_timeout
437
+ *****************************/
438
+
439
+ static VALUE t_set_comm_inactivity_timeout (VALUE self, VALUE signature, VALUE timeout)
440
+ {
441
+ float ti = RFLOAT_VALUE(timeout);
442
+ if (evma_set_comm_inactivity_timeout(NUM2ULONG(signature), ti)) {
443
+ return Qtrue;
444
+ }
445
+ return Qfalse;
446
+ }
447
+
448
+ /*****************************
449
+ t_get_pending_connect_timeout
450
+ *****************************/
451
+
452
+ static VALUE t_get_pending_connect_timeout (VALUE self, VALUE signature)
453
+ {
454
+ return rb_float_new(evma_get_pending_connect_timeout(NUM2ULONG (signature)));
455
+ }
456
+
457
+ /*****************************
458
+ t_set_pending_connect_timeout
459
+ *****************************/
460
+
461
+ static VALUE t_set_pending_connect_timeout (VALUE self, VALUE signature, VALUE timeout)
462
+ {
463
+ float ti = RFLOAT_VALUE(timeout);
464
+ if (evma_set_pending_connect_timeout(NUM2ULONG(signature), ti)) {
465
+ return Qtrue;
466
+ }
467
+ return Qfalse;
468
+ }
469
+
470
+ /***************
471
+ t_send_datagram
472
+ ***************/
473
+
474
+ static VALUE t_send_datagram (VALUE self, VALUE signature, VALUE data, VALUE data_length, VALUE address, VALUE port)
475
+ {
476
+ int b = evma_send_datagram (NUM2ULONG (signature), StringValuePtr (data), FIX2INT (data_length), StringValuePtr(address), FIX2INT(port));
477
+ if (b < 0)
478
+ rb_raise (EM_eConnectionError, "error in sending datagram"); // FIXME: this could be more specific.
479
+ return INT2NUM (b);
480
+ }
481
+
482
+
483
+ /******************
484
+ t_close_connection
485
+ ******************/
486
+
487
+ static VALUE t_close_connection (VALUE self, VALUE signature, VALUE after_writing)
488
+ {
489
+ evma_close_connection (NUM2ULONG (signature), ((after_writing == Qtrue) ? 1 : 0));
490
+ return Qnil;
491
+ }
492
+
493
+ /********************************
494
+ t_report_connection_error_status
495
+ ********************************/
496
+
497
+ static VALUE t_report_connection_error_status (VALUE self, VALUE signature)
498
+ {
499
+ int b = evma_report_connection_error_status (NUM2ULONG (signature));
500
+ return INT2NUM (b);
501
+ }
502
+
503
+
504
+
505
+ /****************
506
+ t_connect_server
507
+ ****************/
508
+
509
+ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port)
510
+ {
511
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
512
+ // Specifically, if the value of port comes in as a string rather than an integer,
513
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
514
+
515
+ try {
516
+ const unsigned long f = evma_connect_to_server (NULL, 0, StringValuePtr(server), NUM2INT(port));
517
+ if (!f)
518
+ rb_raise (EM_eConnectionError, "no connection");
519
+ return ULONG2NUM (f);
520
+ } catch (std::runtime_error e) {
521
+ rb_raise (EM_eConnectionError, e.what());
522
+ }
523
+ return Qnil;
524
+ }
525
+
526
+ /*********************
527
+ t_bind_connect_server
528
+ *********************/
529
+
530
+ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port, VALUE server, VALUE port)
531
+ {
532
+ // Avoid FIX2INT in this case, because it doesn't deal with type errors properly.
533
+ // Specifically, if the value of port comes in as a string rather than an integer,
534
+ // NUM2INT will throw a type error, but FIX2INT will generate garbage.
535
+
536
+ try {
537
+ const unsigned long f = evma_connect_to_server (StringValuePtr(bind_addr), NUM2INT(bind_port), StringValuePtr(server), NUM2INT(port));
538
+ if (!f)
539
+ rb_raise (EM_eConnectionError, "no connection");
540
+ return ULONG2NUM (f);
541
+ } catch (std::runtime_error e) {
542
+ rb_raise (EM_eConnectionError, e.what());
543
+ }
544
+ return Qnil;
545
+ }
546
+
547
+ /*********************
548
+ t_connect_unix_server
549
+ *********************/
550
+
551
+ static VALUE t_connect_unix_server (VALUE self, VALUE serversocket)
552
+ {
553
+ const unsigned long f = evma_connect_to_unix_server (StringValuePtr(serversocket));
554
+ if (!f)
555
+ rb_raise (rb_eRuntimeError, "no connection");
556
+ return ULONG2NUM (f);
557
+ }
558
+
559
+ /***********
560
+ t_attach_fd
561
+ ***********/
562
+
563
+ static VALUE t_attach_fd (VALUE self, VALUE file_descriptor, VALUE watch_mode)
564
+ {
565
+ const unsigned long f = evma_attach_fd (NUM2INT(file_descriptor), watch_mode == Qtrue);
566
+ if (!f)
567
+ rb_raise (rb_eRuntimeError, "no connection");
568
+ return ULONG2NUM (f);
569
+ }
570
+
571
+ /***********
572
+ t_detach_fd
573
+ ***********/
574
+
575
+ static VALUE t_detach_fd (VALUE self, VALUE signature)
576
+ {
577
+ return INT2NUM(evma_detach_fd (NUM2ULONG (signature)));
578
+ }
579
+
580
+ /**************
581
+ t_get_sock_opt
582
+ **************/
583
+
584
+ static VALUE t_get_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname)
585
+ {
586
+ int fd = evma_get_file_descriptor (NUM2ULONG (signature));
587
+ int level = NUM2INT(lev), option = NUM2INT(optname);
588
+ socklen_t len = 128;
589
+ char buf[128];
590
+
591
+ if (getsockopt(fd, level, option, buf, &len) < 0)
592
+ rb_sys_fail("getsockopt");
593
+
594
+ return rb_str_new(buf, len);
595
+ }
596
+
597
+ /**************
598
+ t_set_sock_opt
599
+ **************/
600
+
601
+ static VALUE t_set_sock_opt (VALUE self, VALUE signature, VALUE lev, VALUE optname, VALUE optval)
602
+ {
603
+ int fd = evma_get_file_descriptor (NUM2ULONG (signature));
604
+ int level = NUM2INT(lev), option = NUM2INT(optname);
605
+ int i;
606
+ void *v;
607
+ socklen_t len;
608
+
609
+ switch (TYPE(optval)) {
610
+ case T_FIXNUM:
611
+ i = FIX2INT(optval);
612
+ goto numval;
613
+ case T_FALSE:
614
+ i = 0;
615
+ goto numval;
616
+ case T_TRUE:
617
+ i = 1;
618
+ numval:
619
+ v = (void*)&i; len = sizeof(i);
620
+ break;
621
+ default:
622
+ StringValue(optval);
623
+ v = RSTRING_PTR(optval);
624
+ len = RSTRING_LENINT(optval);
625
+ break;
626
+ }
627
+
628
+
629
+ if (setsockopt(fd, level, option, (char *)v, len) < 0)
630
+ rb_sys_fail("setsockopt");
631
+
632
+ return INT2FIX(0);
633
+ }
634
+
635
+ /********************
636
+ t_is_notify_readable
637
+ ********************/
638
+
639
+ static VALUE t_is_notify_readable (VALUE self, VALUE signature)
640
+ {
641
+ return evma_is_notify_readable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
642
+ }
643
+
644
+ /*********************
645
+ t_set_notify_readable
646
+ *********************/
647
+
648
+ static VALUE t_set_notify_readable (VALUE self, VALUE signature, VALUE mode)
649
+ {
650
+ evma_set_notify_readable(NUM2ULONG (signature), mode == Qtrue);
651
+ return Qnil;
652
+ }
653
+
654
+ /********************
655
+ t_is_notify_readable
656
+ ********************/
657
+
658
+ static VALUE t_is_notify_writable (VALUE self, VALUE signature)
659
+ {
660
+ return evma_is_notify_writable(NUM2ULONG (signature)) ? Qtrue : Qfalse;
661
+ }
662
+
663
+ /*********************
664
+ t_set_notify_writable
665
+ *********************/
666
+
667
+ static VALUE t_set_notify_writable (VALUE self, VALUE signature, VALUE mode)
668
+ {
669
+ evma_set_notify_writable(NUM2ULONG (signature), mode == Qtrue);
670
+ return Qnil;
671
+ }
672
+
673
+ /*********************
674
+ t_set_error_handling
675
+ *********************/
676
+
677
+ static VALUE t_set_error_handling (VALUE self, VALUE signature, VALUE mode)
678
+ {
679
+ evma_set_error_handling(NUM2ULONG (signature), NUM2INT(mode));
680
+ return Qnil;
681
+ }
682
+
683
+ /*******
684
+ t_pause
685
+ *******/
686
+
687
+ static VALUE t_pause (VALUE self, VALUE signature)
688
+ {
689
+ return evma_pause(NUM2ULONG (signature)) ? Qtrue : Qfalse;
690
+ }
691
+
692
+ /********
693
+ t_resume
694
+ ********/
695
+
696
+ static VALUE t_resume (VALUE self, VALUE signature)
697
+ {
698
+ return evma_resume(NUM2ULONG (signature)) ? Qtrue : Qfalse;
699
+ }
700
+
701
+ /**********
702
+ t_paused_p
703
+ **********/
704
+
705
+ static VALUE t_paused_p (VALUE self, VALUE signature)
706
+ {
707
+ return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
708
+ }
709
+
710
+ /*********************
711
+ t_num_close_scheduled
712
+ *********************/
713
+
714
+ static VALUE t_num_close_scheduled (VALUE self)
715
+ {
716
+ return INT2FIX(evma_num_close_scheduled());
717
+ }
718
+
719
+ /*****************
720
+ t_open_udp_socket
721
+ *****************/
722
+
723
+ static VALUE t_open_udp_socket (VALUE self, VALUE server, VALUE port)
724
+ {
725
+ const unsigned long f = evma_open_datagram_socket (StringValuePtr(server), FIX2INT(port));
726
+ if (!f)
727
+ rb_raise (rb_eRuntimeError, "no datagram socket");
728
+ return ULONG2NUM (f);
729
+ }
730
+
731
+
732
+
733
+ /*****************
734
+ t_release_machine
735
+ *****************/
736
+
737
+ static VALUE t_release_machine (VALUE self)
738
+ {
739
+ evma_release_library();
740
+ return Qnil;
741
+ }
742
+
743
+
744
+ /******
745
+ t_stop
746
+ ******/
747
+
748
+ static VALUE t_stop (VALUE self)
749
+ {
750
+ evma_stop_machine();
751
+ return Qnil;
752
+ }
753
+
754
+ /******************
755
+ t_signal_loopbreak
756
+ ******************/
757
+
758
+ static VALUE t_signal_loopbreak (VALUE self)
759
+ {
760
+ evma_signal_loopbreak();
761
+ return Qnil;
762
+ }
763
+
764
+ /**************
765
+ t_library_type
766
+ **************/
767
+
768
+ static VALUE t_library_type (VALUE self)
769
+ {
770
+ return rb_eval_string (":extension");
771
+ }
772
+
773
+
774
+
775
+ /*******************
776
+ t_set_timer_quantum
777
+ *******************/
778
+
779
+ static VALUE t_set_timer_quantum (VALUE self, VALUE interval)
780
+ {
781
+ evma_set_timer_quantum (FIX2INT (interval));
782
+ return Qnil;
783
+ }
784
+
785
+ /********************
786
+ t_get_max_timer_count
787
+ ********************/
788
+
789
+ static VALUE t_get_max_timer_count (VALUE self)
790
+ {
791
+ return INT2FIX (evma_get_max_timer_count());
792
+ }
793
+
794
+ /********************
795
+ t_set_max_timer_count
796
+ ********************/
797
+
798
+ static VALUE t_set_max_timer_count (VALUE self, VALUE ct)
799
+ {
800
+ evma_set_max_timer_count (FIX2INT (ct));
801
+ return Qnil;
802
+ }
803
+
804
+ /***************
805
+ t_setuid_string
806
+ ***************/
807
+
808
+ static VALUE t_setuid_string (VALUE self, VALUE username)
809
+ {
810
+ evma_setuid_string (StringValuePtr (username));
811
+ return Qnil;
812
+ }
813
+
814
+
815
+
816
+ /**************
817
+ t_invoke_popen
818
+ **************/
819
+
820
+ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
821
+ {
822
+ // 1.8.7+
823
+ #ifdef RARRAY_LEN
824
+ int len = RARRAY_LEN(cmd);
825
+ #else
826
+ int len = RARRAY (cmd)->len;
827
+ #endif
828
+ if (len >= 2048)
829
+ rb_raise (rb_eRuntimeError, "too many arguments to popen");
830
+ char *strings [2048];
831
+ for (int i=0; i < len; i++) {
832
+ VALUE ix = INT2FIX (i);
833
+ VALUE s = rb_ary_aref (1, &ix, cmd);
834
+ strings[i] = StringValuePtr (s);
835
+ }
836
+ strings[len] = NULL;
837
+
838
+ const unsigned long f = evma_popen (strings);
839
+ if (!f) {
840
+ char *err = strerror (errno);
841
+ char buf[100];
842
+ memset (buf, 0, sizeof(buf));
843
+ snprintf (buf, sizeof(buf)-1, "no popen: %s", (err?err:"???"));
844
+ rb_raise (rb_eRuntimeError, "%s", buf);
845
+ }
846
+ return ULONG2NUM (f);
847
+ }
848
+
849
+
850
+ /***************
851
+ t_read_keyboard
852
+ ***************/
853
+
854
+ static VALUE t_read_keyboard (VALUE self)
855
+ {
856
+ const unsigned long f = evma_open_keyboard();
857
+ if (!f)
858
+ rb_raise (rb_eRuntimeError, "no keyboard reader");
859
+ return ULONG2NUM (f);
860
+ }
861
+
862
+
863
+ /****************
864
+ t_watch_filename
865
+ ****************/
866
+
867
+ static VALUE t_watch_filename (VALUE self, VALUE fname)
868
+ {
869
+ try {
870
+ return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
871
+ } catch (std::runtime_error e) {
872
+ rb_raise (EM_eUnsupported, e.what());
873
+ }
874
+ return Qnil;
875
+ }
876
+
877
+
878
+ /******************
879
+ t_unwatch_filename
880
+ ******************/
881
+
882
+ static VALUE t_unwatch_filename (VALUE self, VALUE sig)
883
+ {
884
+ evma_unwatch_filename(NUM2ULONG (sig));
885
+ return Qnil;
886
+ }
887
+
888
+
889
+ /***********
890
+ t_watch_pid
891
+ ***********/
892
+
893
+ static VALUE t_watch_pid (VALUE self, VALUE pid)
894
+ {
895
+ try {
896
+ return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
897
+ } catch (std::runtime_error e) {
898
+ rb_raise (EM_eUnsupported, e.what());
899
+ }
900
+ return Qnil;
901
+ }
902
+
903
+
904
+ /*************
905
+ t_unwatch_pid
906
+ *************/
907
+
908
+ static VALUE t_unwatch_pid (VALUE self, VALUE sig)
909
+ {
910
+ evma_unwatch_pid(NUM2ULONG (sig));
911
+ return Qnil;
912
+ }
913
+
914
+
915
+ /**********
916
+ t__epoll_p
917
+ **********/
918
+
919
+ static VALUE t__epoll_p (VALUE self)
920
+ {
921
+ #ifdef HAVE_EPOLL
922
+ return Qtrue;
923
+ #else
924
+ return Qfalse;
925
+ #endif
926
+ }
927
+
928
+ /********
929
+ t__epoll
930
+ ********/
931
+
932
+ static VALUE t__epoll (VALUE self)
933
+ {
934
+ evma_set_epoll (1);
935
+ return Qtrue;
936
+ }
937
+
938
+ /***********
939
+ t__epoll_set
940
+ ***********/
941
+
942
+ static VALUE t__epoll_set (VALUE self, VALUE val)
943
+ {
944
+ if (t__epoll_p(self) == Qfalse)
945
+ rb_raise (EM_eUnsupported, "epoll is not supported on this platform");
946
+
947
+ evma_set_epoll (val == Qtrue ? 1 : 0);
948
+ return val;
949
+ }
950
+
951
+
952
+ /***********
953
+ t__kqueue_p
954
+ ***********/
955
+
956
+ static VALUE t__kqueue_p (VALUE self)
957
+ {
958
+ #ifdef HAVE_KQUEUE
959
+ return Qtrue;
960
+ #else
961
+ return Qfalse;
962
+ #endif
963
+ }
964
+
965
+ /*********
966
+ t__kqueue
967
+ *********/
968
+
969
+ static VALUE t__kqueue (VALUE self)
970
+ {
971
+ evma_set_kqueue (1);
972
+ return Qtrue;
973
+ }
974
+
975
+ /*************
976
+ t__kqueue_set
977
+ *************/
978
+
979
+ static VALUE t__kqueue_set (VALUE self, VALUE val)
980
+ {
981
+ if (t__kqueue_p(self) == Qfalse)
982
+ rb_raise (EM_eUnsupported, "kqueue is not supported on this platform");
983
+
984
+ evma_set_kqueue (val == Qtrue ? 1 : 0);
985
+ return val;
986
+ }
987
+
988
+
989
+ /********
990
+ t__ssl_p
991
+ ********/
992
+
993
+ static VALUE t__ssl_p (VALUE self)
994
+ {
995
+ #ifdef WITH_SSL
996
+ return Qtrue;
997
+ #else
998
+ return Qfalse;
999
+ #endif
1000
+ }
1001
+
1002
+
1003
+ /****************
1004
+ t_send_file_data
1005
+ ****************/
1006
+
1007
+ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
1008
+ {
1009
+
1010
+ /* The current implementation of evma_send_file_data_to_connection enforces a strict
1011
+ * upper limit on the file size it will transmit (currently 32K). The function returns
1012
+ * zero on success, -1 if the requested file exceeds its size limit, and a positive
1013
+ * number for other errors.
1014
+ * TODO: Positive return values are actually errno's, which is probably the wrong way to
1015
+ * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno.
1016
+ */
1017
+
1018
+ int b = evma_send_file_data_to_connection (NUM2ULONG (signature), StringValuePtr(filename));
1019
+ if (b == -1)
1020
+ rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
1021
+ if (b > 0) {
1022
+ char *err = strerror (b);
1023
+ char buf[1024];
1024
+ memset (buf, 0, sizeof(buf));
1025
+ snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???"));
1026
+
1027
+ rb_raise (rb_eIOError, "%s", buf);
1028
+ }
1029
+
1030
+ return INT2NUM (0);
1031
+ }
1032
+
1033
+
1034
+ /*******************
1035
+ t_set_rlimit_nofile
1036
+ *******************/
1037
+
1038
+ static VALUE t_set_rlimit_nofile (VALUE self, VALUE arg)
1039
+ {
1040
+ arg = (NIL_P(arg)) ? -1 : NUM2INT (arg);
1041
+ return INT2NUM (evma_set_rlimit_nofile (arg));
1042
+ }
1043
+
1044
+ /***************************
1045
+ conn_get_outbound_data_size
1046
+ ***************************/
1047
+
1048
+ static VALUE conn_get_outbound_data_size (VALUE self)
1049
+ {
1050
+ VALUE sig = rb_ivar_get (self, Intern_at_signature);
1051
+ return INT2NUM (evma_get_outbound_data_size (NUM2ULONG (sig)));
1052
+ }
1053
+
1054
+
1055
+ /******************************
1056
+ conn_associate_callback_target
1057
+ ******************************/
1058
+
1059
+ static VALUE conn_associate_callback_target (VALUE self, VALUE sig)
1060
+ {
1061
+ // No-op for the time being.
1062
+ return Qnil;
1063
+ }
1064
+
1065
+
1066
+ /***************
1067
+ t_get_loop_time
1068
+ ****************/
1069
+
1070
+ static VALUE t_get_loop_time (VALUE self)
1071
+ {
1072
+ #ifndef HAVE_RB_TIME_NEW
1073
+ static VALUE cTime = rb_path2class("Time");
1074
+ static ID at = rb_intern("at");
1075
+ #endif
1076
+
1077
+ uint64_t current_time = evma_get_current_loop_time();
1078
+ if (current_time != 0) {
1079
+ #ifndef HAVE_RB_TIME_NEW
1080
+ return rb_funcall(cTime, at, 2, INT2NUM(current_time / 1000000), INT2NUM(current_time % 1000000));
1081
+ #else
1082
+ return rb_time_new(current_time / 1000000, current_time % 1000000);
1083
+ #endif
1084
+ }
1085
+ return Qnil;
1086
+ }
1087
+
1088
+
1089
+ /*************
1090
+ t_start_proxy
1091
+ **************/
1092
+
1093
+ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VALUE length)
1094
+ {
1095
+ try {
1096
+ evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
1097
+ } catch (std::runtime_error e) {
1098
+ rb_raise (EM_eConnectionError, e.what());
1099
+ }
1100
+ return Qnil;
1101
+ }
1102
+
1103
+
1104
+ /************
1105
+ t_stop_proxy
1106
+ *************/
1107
+
1108
+ static VALUE t_stop_proxy (VALUE self, VALUE from)
1109
+ {
1110
+ try{
1111
+ evma_stop_proxy(NUM2ULONG (from));
1112
+ } catch (std::runtime_error e) {
1113
+ rb_raise (EM_eConnectionError, e.what());
1114
+ }
1115
+ return Qnil;
1116
+ }
1117
+
1118
+
1119
+ /************************
1120
+ t_get_heartbeat_interval
1121
+ *************************/
1122
+
1123
+ static VALUE t_get_heartbeat_interval (VALUE self)
1124
+ {
1125
+ return rb_float_new(evma_get_heartbeat_interval());
1126
+ }
1127
+
1128
+
1129
+ /************************
1130
+ t_set_heartbeat_interval
1131
+ *************************/
1132
+
1133
+ static VALUE t_set_heartbeat_interval (VALUE self, VALUE interval)
1134
+ {
1135
+ float iv = RFLOAT_VALUE(interval);
1136
+ if (evma_set_heartbeat_interval(iv))
1137
+ return Qtrue;
1138
+ return Qfalse;
1139
+ }
1140
+
1141
+
1142
+ /*********************
1143
+ Init_rubyeventmachine
1144
+ *********************/
1145
+
1146
+ extern "C" void Init_rubyeventmachine()
1147
+ {
1148
+ // Lookup Process::Status for get_subprocess_status
1149
+ VALUE rb_mProcess = rb_const_get(rb_cObject, rb_intern("Process"));
1150
+ rb_cProcStatus = rb_const_get(rb_mProcess, rb_intern("Status"));
1151
+
1152
+ // Tuck away some symbol values so we don't have to look 'em up every time we need 'em.
1153
+ Intern_at_signature = rb_intern ("@signature");
1154
+ Intern_at_timers = rb_intern ("@timers");
1155
+ Intern_at_conns = rb_intern ("@conns");
1156
+ Intern_at_error_handler = rb_intern("@error_handler");
1157
+
1158
+ Intern_event_callback = rb_intern ("event_callback");
1159
+ Intern_run_deferred_callbacks = rb_intern ("run_deferred_callbacks");
1160
+ Intern_delete = rb_intern ("delete");
1161
+ Intern_call = rb_intern ("call");
1162
+ Intern_receive_data = rb_intern ("receive_data");
1163
+ Intern_receive_error = rb_intern ("receive_error");
1164
+ Intern_ssl_handshake_completed = rb_intern ("ssl_handshake_completed");
1165
+ Intern_ssl_verify_peer = rb_intern ("ssl_verify_peer");
1166
+ Intern_notify_readable = rb_intern ("notify_readable");
1167
+ Intern_notify_writable = rb_intern ("notify_writable");
1168
+ Intern_proxy_target_unbound = rb_intern ("proxy_target_unbound");
1169
+ Intern_proxy_completed = rb_intern ("proxy_completed");
1170
+ Intern_connection_completed = rb_intern ("connection_completed");
1171
+
1172
+ // INCOMPLETE, we need to define class Connections inside module EventMachine
1173
+ // run_machine and run_machine_without_threads are now identical.
1174
+ // Must deprecate the without_threads variant.
1175
+ EmModule = rb_define_module ("EventMachine");
1176
+ EmConnection = rb_define_class_under (EmModule, "Connection", rb_cObject);
1177
+
1178
+ rb_define_class_under (EmModule, "NoHandlerForAcceptedConnection", rb_eRuntimeError);
1179
+ EM_eConnectionError = rb_define_class_under (EmModule, "ConnectionError", rb_eRuntimeError);
1180
+ EM_eConnectionNotBound = rb_define_class_under (EmModule, "ConnectionNotBound", rb_eRuntimeError);
1181
+ EM_eUnknownTimerFired = rb_define_class_under (EmModule, "UnknownTimerFired", rb_eRuntimeError);
1182
+ EM_eUnsupported = rb_define_class_under (EmModule, "Unsupported", rb_eRuntimeError);
1183
+
1184
+ rb_define_module_function (EmModule, "initialize_event_machine", (VALUE(*)(...))t_initialize_event_machine, 0);
1185
+ rb_define_module_function (EmModule, "run_machine", (VALUE(*)(...))t_run_machine_without_threads, 0);
1186
+ rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
1187
+ rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
1188
+ rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
1189
+ rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
1190
+ rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
1191
+ rb_define_module_function (EmModule, "set_tls_parms", (VALUE(*)(...))t_set_tls_parms, 4);
1192
+ rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
1193
+ rb_define_module_function (EmModule, "get_peer_cert", (VALUE(*)(...))t_get_peer_cert, 1);
1194
+ rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
1195
+ rb_define_module_function (EmModule, "send_datagram", (VALUE(*)(...))t_send_datagram, 5);
1196
+ rb_define_module_function (EmModule, "close_connection", (VALUE(*)(...))t_close_connection, 2);
1197
+ rb_define_module_function (EmModule, "report_connection_error_status", (VALUE(*)(...))t_report_connection_error_status, 1);
1198
+ rb_define_module_function (EmModule, "connect_server", (VALUE(*)(...))t_connect_server, 2);
1199
+ rb_define_module_function (EmModule, "bind_connect_server", (VALUE(*)(...))t_bind_connect_server, 4);
1200
+ rb_define_module_function (EmModule, "connect_unix_server", (VALUE(*)(...))t_connect_unix_server, 1);
1201
+
1202
+ rb_define_module_function (EmModule, "attach_fd", (VALUE (*)(...))t_attach_fd, 2);
1203
+ rb_define_module_function (EmModule, "detach_fd", (VALUE (*)(...))t_detach_fd, 1);
1204
+ rb_define_module_function (EmModule, "get_sock_opt", (VALUE (*)(...))t_get_sock_opt, 3);
1205
+ rb_define_module_function (EmModule, "set_sock_opt", (VALUE (*)(...))t_set_sock_opt, 4);
1206
+ rb_define_module_function (EmModule, "set_notify_readable", (VALUE (*)(...))t_set_notify_readable, 2);
1207
+ rb_define_module_function (EmModule, "set_notify_writable", (VALUE (*)(...))t_set_notify_writable, 2);
1208
+ rb_define_module_function (EmModule, "set_error_handling", (VALUE (*)(...))t_set_error_handling, 2);
1209
+ rb_define_module_function (EmModule, "is_notify_readable", (VALUE (*)(...))t_is_notify_readable, 1);
1210
+ rb_define_module_function (EmModule, "is_notify_writable", (VALUE (*)(...))t_is_notify_writable, 1);
1211
+
1212
+ rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
1213
+ rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
1214
+ rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
1215
+ rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0);
1216
+
1217
+ rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
1218
+ rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
1219
+
1220
+ rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
1221
+ rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
1222
+
1223
+ rb_define_module_function (EmModule, "watch_pid", (VALUE (*)(...))t_watch_pid, 1);
1224
+ rb_define_module_function (EmModule, "unwatch_pid", (VALUE (*)(...))t_unwatch_pid, 1);
1225
+
1226
+ rb_define_module_function (EmModule, "current_time", (VALUE(*)(...))t_get_loop_time, 0);
1227
+
1228
+ rb_define_module_function (EmModule, "open_udp_socket", (VALUE(*)(...))t_open_udp_socket, 2);
1229
+ rb_define_module_function (EmModule, "read_keyboard", (VALUE(*)(...))t_read_keyboard, 0);
1230
+ rb_define_module_function (EmModule, "release_machine", (VALUE(*)(...))t_release_machine, 0);
1231
+ rb_define_module_function (EmModule, "stop", (VALUE(*)(...))t_stop, 0);
1232
+ rb_define_module_function (EmModule, "signal_loopbreak", (VALUE(*)(...))t_signal_loopbreak, 0);
1233
+ rb_define_module_function (EmModule, "library_type", (VALUE(*)(...))t_library_type, 0);
1234
+ rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
1235
+ rb_define_module_function (EmModule, "get_max_timer_count", (VALUE(*)(...))t_get_max_timer_count, 0);
1236
+ rb_define_module_function (EmModule, "set_max_timer_count", (VALUE(*)(...))t_set_max_timer_count, 1);
1237
+ rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
1238
+ rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
1239
+ rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
1240
+ rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
1241
+ rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
1242
+
1243
+ rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
1244
+ rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
1245
+ rb_define_module_function (EmModule, "get_subprocess_pid", (VALUE(*)(...))t_get_subprocess_pid, 1);
1246
+ rb_define_module_function (EmModule, "get_subprocess_status", (VALUE(*)(...))t_get_subprocess_status, 1);
1247
+ rb_define_module_function (EmModule, "get_comm_inactivity_timeout", (VALUE(*)(...))t_get_comm_inactivity_timeout, 1);
1248
+ rb_define_module_function (EmModule, "set_comm_inactivity_timeout", (VALUE(*)(...))t_set_comm_inactivity_timeout, 2);
1249
+ rb_define_module_function (EmModule, "get_pending_connect_timeout", (VALUE(*)(...))t_get_pending_connect_timeout, 1);
1250
+ rb_define_module_function (EmModule, "set_pending_connect_timeout", (VALUE(*)(...))t_set_pending_connect_timeout, 2);
1251
+ rb_define_module_function (EmModule, "set_rlimit_nofile", (VALUE(*)(...))t_set_rlimit_nofile, 1);
1252
+ rb_define_module_function (EmModule, "get_connection_count", (VALUE(*)(...))t_get_connection_count, 0);
1253
+
1254
+ rb_define_module_function (EmModule, "epoll", (VALUE(*)(...))t__epoll, 0);
1255
+ rb_define_module_function (EmModule, "epoll=", (VALUE(*)(...))t__epoll_set, 1);
1256
+ rb_define_module_function (EmModule, "epoll?", (VALUE(*)(...))t__epoll_p, 0);
1257
+
1258
+ rb_define_module_function (EmModule, "kqueue", (VALUE(*)(...))t__kqueue, 0);
1259
+ rb_define_module_function (EmModule, "kqueue=", (VALUE(*)(...))t__kqueue_set, 1);
1260
+ rb_define_module_function (EmModule, "kqueue?", (VALUE(*)(...))t__kqueue_p, 0);
1261
+
1262
+ rb_define_module_function (EmModule, "ssl?", (VALUE(*)(...))t__ssl_p, 0);
1263
+
1264
+ rb_define_method (EmConnection, "get_outbound_data_size", (VALUE(*)(...))conn_get_outbound_data_size, 0);
1265
+ rb_define_method (EmConnection, "associate_callback_target", (VALUE(*)(...))conn_associate_callback_target, 1);
1266
+
1267
+ rb_define_const (EmModule, "TimerFired", INT2NUM(100));
1268
+ rb_define_const (EmModule, "ConnectionData", INT2NUM(101));
1269
+ rb_define_const (EmModule, "ConnectionUnbound", INT2NUM(102));
1270
+ rb_define_const (EmModule, "ConnectionAccepted", INT2NUM(103));
1271
+ rb_define_const (EmModule, "ConnectionCompleted", INT2NUM(104));
1272
+ rb_define_const (EmModule, "LoopbreakSignalled", INT2NUM(105));
1273
+
1274
+ rb_define_const (EmModule, "ConnectionNotifyReadable", INT2NUM(106));
1275
+ rb_define_const (EmModule, "ConnectionNotifyWritable", INT2NUM(107));
1276
+
1277
+ rb_define_const (EmModule, "SslHandshakeCompleted", INT2NUM(108));
1278
+
1279
+ }
1280
+