clucumber 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +4 -9
  3. data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
  4. data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
  5. data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
  6. data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
  7. data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
  8. data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
  9. data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
  10. data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
  11. data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
  12. data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
  13. data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
  14. data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
  15. data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
  16. data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
  17. data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
  18. data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
  19. data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
  20. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
  21. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
  22. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
  23. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
  24. data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
  25. data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
  26. data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
  27. data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
  28. data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
  29. data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
  30. data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
  31. data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
  32. data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
  33. data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
  34. data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
  35. data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
  36. data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
  37. data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
  38. data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
  39. data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
  40. data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
  41. data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
  42. data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
  43. data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
  44. data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
  45. data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
  46. data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
  47. data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
  48. data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
  49. data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
  50. data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
  51. data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
  52. data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
  53. data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
  54. data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
  55. data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
  56. data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
  57. data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
  58. data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
  59. data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
  60. data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
  61. data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
  62. data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
  63. data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
  64. data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
  65. data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
  66. data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
  67. data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
  68. data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
  69. data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
  70. data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
  71. data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
  72. data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
  73. data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
  74. data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
  75. data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
  76. data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
  77. data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
  78. data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
  79. data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
  80. data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
  81. data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
  82. data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
  83. data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
  84. data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
  85. data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
  86. data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
  87. data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
  88. data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
  89. data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
  90. data/lib/clucumber/vendor/lift/lift.asd +77 -0
  91. data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
  92. data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
  93. data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
  94. data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
  95. data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
  96. data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
  97. data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
  98. data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
  99. data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
  100. data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
  101. data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
  102. data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
  103. data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
  104. data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
  105. data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
  106. data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
  107. data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
  108. data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
  109. data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
  110. data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
  111. data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
  112. data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
  113. data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
  114. data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
  115. data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
  116. data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
  117. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
  118. data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
  119. data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
  120. data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
  121. data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
  122. data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
  123. data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
  124. data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
  125. data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
  126. data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
  127. data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
  128. data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
  129. data/lib/clucumber/vendor/usocket/package.lisp +82 -0
  130. data/lib/clucumber/vendor/usocket/server.lisp +45 -0
  131. data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
  132. data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
  133. data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
  134. data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
  135. data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
  136. data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
  137. data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
  138. data/lib/clucumber.rb +29 -7
  139. metadata +151 -5
@@ -0,0 +1,424 @@
1
+ ;;;; $Id: sbcl.lisp 515 2010-01-07 18:26:06Z ctian $
2
+ ;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/sbcl.lisp $
3
+
4
+ ;;;; See LICENSE for licensing information.
5
+
6
+ (in-package :usocket)
7
+
8
+ ;; There's no way to preload the sockets library other than by requiring it
9
+ ;;
10
+ ;; ECL sockets has been forked off sb-bsd-sockets and implements the
11
+ ;; same interface. We use the same file for now.
12
+ #+ecl
13
+ (eval-when (:compile-toplevel :load-toplevel :execute)
14
+ (require :sockets))
15
+
16
+ #+sbcl
17
+ (progn
18
+ #-win32
19
+ (defun get-host-name ()
20
+ (sb-unix:unix-gethostname))
21
+
22
+ ;; we assume winsock has already been loaded, after all,
23
+ ;; we already loaded sb-bsd-sockets and sb-alien
24
+ #+win32
25
+ (defun get-host-name ()
26
+ (sb-alien:with-alien ((buf (sb-alien:array sb-alien:char 256)))
27
+ (let ((result (sb-alien:alien-funcall
28
+ (sb-alien:extern-alien "gethostname"
29
+ (sb-alien:function sb-alien:int
30
+ (* sb-alien:char)
31
+ sb-alien:int))
32
+ (sb-alien:cast buf (* sb-alien:char))
33
+ 256)))
34
+ (when (= result 0)
35
+ (sb-alien:cast buf sb-alien:c-string))))))
36
+
37
+
38
+ #+ecl
39
+ (progn
40
+
41
+ #-:wsock
42
+ (ffi:clines
43
+ "#include <errno.h>"
44
+ "#include <sys/socket.h>")
45
+ #+:wsock
46
+ (ffi:clines
47
+ "#ifndef FD_SETSIZE"
48
+ "#define FD_SETSIZE 1024"
49
+ "#endif"
50
+ "#include <winsock2.h>")
51
+
52
+ (ffi:clines
53
+ #+:msvc "#include <time.h>"
54
+ #-:msvc "#include <sys/time.h>"
55
+ "#include <ecl/ecl-inl.h>")
56
+
57
+ #+:prefixed-api
58
+ (ffi:clines
59
+ "#define CONS(x, y) ecl_cons((x), (y))"
60
+ "#define MAKE_INTEGER(x) ecl_make_integer((x))")
61
+ #-:prefixed-api
62
+ (ffi:clines
63
+ "#define CONS(x, y) make_cons((x), (y))"
64
+ "#define MAKE_INTEGER(x) make_integer((x))")
65
+
66
+ (defun fd-setsize ()
67
+ (ffi:c-inline () () :fixnum
68
+ "FD_SETSIZE" :one-liner t))
69
+
70
+ (defun fdset-alloc ()
71
+ (ffi:c-inline () () :pointer-void
72
+ "ecl_alloc_atomic(sizeof(fd_set))" :one-liner t))
73
+
74
+ (defun fdset-zero (fdset)
75
+ (ffi:c-inline (fdset) (:pointer-void) :void
76
+ "FD_ZERO((fd_set*)#0)" :one-liner t))
77
+
78
+ (defun fdset-set (fdset fd)
79
+ (ffi:c-inline (fdset fd) (:pointer-void :fixnum) :void
80
+ "FD_SET(#1,(fd_set*)#0)" :one-liner t))
81
+
82
+ (defun fdset-clr (fdset fd)
83
+ (ffi:c-inline (fdset fd) (:pointer-void :fixnum) :void
84
+ "FD_CLR(#1,(fd_set*)#0)" :one-liner t))
85
+
86
+ (defun fdset-fd-isset (fdset fd)
87
+ (ffi:c-inline (fdset fd) (:pointer-void :fixnum) :bool
88
+ "FD_ISSET(#1,(fd_set*)#0)" :one-liner t))
89
+
90
+ (declaim (inline fd-setsize
91
+ fdset-alloc
92
+ fdset-zero
93
+ fdset-set
94
+ fdset-clr
95
+ fdset-fd-isset))
96
+
97
+ (defun get-host-name ()
98
+ (ffi:c-inline
99
+ () () :object
100
+ "{ char *buf = ecl_alloc_atomic(257);
101
+
102
+ if (gethostname(buf,256) == 0)
103
+ @(return) = make_simple_base_string(buf);
104
+ else
105
+ @(return) = Cnil;
106
+ }" :one-liner nil :side-effects nil))
107
+
108
+ (defun read-select (wl to-secs &optional (to-musecs 0))
109
+ (let* ((sockets (wait-list-waiters wl))
110
+ (rfds (wait-list-%wait wl))
111
+ (max-fd (reduce #'(lambda (x y)
112
+ (let ((sy (sb-bsd-sockets:socket-file-descriptor
113
+ (socket y))))
114
+ (if (< x sy) sy x)))
115
+ (cdr sockets)
116
+ :initial-value (sb-bsd-sockets:socket-file-descriptor
117
+ (socket (car sockets))))))
118
+ (fdset-zero rfds)
119
+ (dolist (sock sockets)
120
+ (fdset-set rfds (sb-bsd-sockets:socket-file-descriptor
121
+ (socket sock))))
122
+ (let ((count
123
+ (ffi:c-inline (to-secs to-musecs rfds max-fd)
124
+ (t :unsigned-int :pointer-void :int)
125
+ :int
126
+ "
127
+ int count;
128
+ struct timeval tv;
129
+
130
+ if (#0 != Cnil) {
131
+ tv.tv_sec = fixnnint(#0);
132
+ tv.tv_usec = #1;
133
+ }
134
+ @(return) = select(#3 + 1, (fd_set*)#2, NULL, NULL,
135
+ (#0 != Cnil) ? &tv : NULL);
136
+ " :one-liner nil)))
137
+ (cond
138
+ ((= 0 count)
139
+ (values nil nil))
140
+ ((< count 0)
141
+ ;; check for EINTR and EAGAIN; these should not err
142
+ (values nil (ffi:c-inline () () :int "errno" :one-liner t)))
143
+ (t
144
+ (dolist (sock sockets)
145
+ (when (fdset-fd-isset rfds (sb-bsd-sockets:socket-file-descriptor
146
+ (socket sock)))
147
+ (setf (state sock) :READ))))))))
148
+
149
+
150
+ )
151
+
152
+ (defun map-socket-error (sock-err)
153
+ (map-errno-error (sb-bsd-sockets::socket-error-errno sock-err)))
154
+
155
+ (defparameter +sbcl-condition-map+
156
+ '((interrupted-error . interrupted-condition)))
157
+
158
+ (defparameter +sbcl-error-map+
159
+ `((sb-bsd-sockets:address-in-use-error . address-in-use-error)
160
+ (sb-bsd-sockets::no-address-error . address-not-available-error)
161
+ (sb-bsd-sockets:bad-file-descriptor-error . bad-file-descriptor-error)
162
+ (sb-bsd-sockets:connection-refused-error . connection-refused-error)
163
+ (sb-bsd-sockets:invalid-argument-error . invalid-argument-error)
164
+ (sb-bsd-sockets:no-buffers-error . no-buffers-error)
165
+ (sb-bsd-sockets:operation-not-supported-error
166
+ . operation-not-supported-error)
167
+ (sb-bsd-sockets:operation-not-permitted-error
168
+ . operation-not-permitted-error)
169
+ (sb-bsd-sockets:protocol-not-supported-error
170
+ . protocol-not-supported-error)
171
+ #-ecl
172
+ (sb-bsd-sockets:unknown-protocol
173
+ . protocol-not-supported-error)
174
+ (sb-bsd-sockets:socket-type-not-supported-error
175
+ . socket-type-not-supported-error)
176
+ (sb-bsd-sockets:network-unreachable-error . network-unreachable-error)
177
+ (sb-bsd-sockets:operation-timeout-error . timeout-error)
178
+ #-ecl
179
+ (sb-sys:io-timeout . timeout-error)
180
+ (sb-bsd-sockets:socket-error . ,#'map-socket-error)
181
+
182
+ ;; Nameservice errors: mapped to unknown-error
183
+ #-ecl #-ecl #-ecl
184
+ (sb-bsd-sockets:no-recovery-error . ns-no-recovery-error)
185
+ (sb-bsd-sockets:try-again-error . ns-try-again-condition)
186
+ (sb-bsd-sockets:host-not-found-error . ns-host-not-found-error)))
187
+
188
+ (defun handle-condition (condition &optional (socket nil))
189
+ "Dispatch correct usocket condition."
190
+ (typecase condition
191
+ (serious-condition (let* ((usock-error (cdr (assoc (type-of condition)
192
+ +sbcl-error-map+)))
193
+ (usock-error (if (functionp usock-error)
194
+ (funcall usock-error condition)
195
+ usock-error)))
196
+ (when usock-error
197
+ (error usock-error :socket socket))))
198
+ (condition (let* ((usock-cond (cdr (assoc (type-of condition)
199
+ +sbcl-condition-map+)))
200
+ (usock-cond (if (functionp usock-cond)
201
+ (funcall usock-cond condition)
202
+ usock-cond)))
203
+ (if usock-cond
204
+ (signal usock-cond :socket socket))))))
205
+
206
+ (defun socket-connect (host port &key (protocol :stream) (element-type 'character)
207
+ timeout deadline (nodelay t nodelay-specified)
208
+ local-host local-port
209
+ &aux
210
+ (sockopt-tcp-nodelay-p
211
+ (fboundp 'sb-bsd-sockets::sockopt-tcp-nodelay)))
212
+ (when deadline (unsupported 'deadline 'socket-connect))
213
+ (when timeout (unsupported 'timeout 'socket-connect))
214
+ (when (and nodelay-specified
215
+ ;; 20080802: ECL added this function to its sockets
216
+ ;; package today. There's no guarantee the functions
217
+ ;; we need are available, but we can make sure not to
218
+ ;; call them if they aren't
219
+ (not sockopt-tcp-nodelay-p))
220
+ (unsupported 'nodelay 'socket-connect))
221
+
222
+ (let ((socket (make-instance 'sb-bsd-sockets:inet-socket
223
+ :type protocol
224
+ :protocol (case protocol
225
+ (:stream :tcp)
226
+ (:datagram :udp)))))
227
+ (handler-case
228
+ (ecase protocol
229
+ (:stream
230
+ (let* ((stream
231
+ (sb-bsd-sockets:socket-make-stream socket
232
+ :input t
233
+ :output t
234
+ :buffering :full
235
+ :element-type element-type))
236
+ ;;###FIXME: The above line probably needs an :external-format
237
+ (usocket (make-stream-socket :stream stream :socket socket))
238
+ (ip (host-to-vector-quad host)))
239
+ ;; binghe: use SOCKOPT-TCP-NODELAY as internal symbol
240
+ ;; to pass compilation on ECL without it.
241
+ (when (and nodelay-specified sockopt-tcp-nodelay-p)
242
+ (setf (sb-bsd-sockets::sockopt-tcp-nodelay socket) nodelay))
243
+ (when (or local-host local-port)
244
+ (sb-bsd-sockets:socket-bind socket
245
+ (host-to-vector-quad
246
+ (or local-host *wildcard-host*))
247
+ (or local-port *auto-port*)))
248
+ (with-mapped-conditions (usocket)
249
+ (sb-bsd-sockets:socket-connect socket ip port))
250
+ usocket))
251
+ (:datagram
252
+ (when (or local-host local-port)
253
+ (sb-bsd-sockets:socket-bind socket
254
+ (host-to-vector-quad
255
+ (or local-host *wildcard-host*))
256
+ (or local-port *auto-port*)))
257
+ (when (and host port)
258
+ (sb-bsd-sockets:socket-connect socket (host-to-vector-quad host) port))
259
+ (make-datagram-socket socket)))
260
+ (t (c)
261
+ ;; Make sure we don't leak filedescriptors
262
+ (sb-bsd-sockets:socket-close socket)
263
+ (error c)))))
264
+
265
+ (defun socket-listen (host port
266
+ &key reuseaddress
267
+ (reuse-address nil reuse-address-supplied-p)
268
+ (backlog 5)
269
+ (element-type 'character))
270
+ (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
271
+ (ip (host-to-vector-quad host))
272
+ (sock (make-instance 'sb-bsd-sockets:inet-socket
273
+ :type :stream :protocol :tcp)))
274
+ (handler-case
275
+ (with-mapped-conditions ()
276
+ (setf (sb-bsd-sockets:sockopt-reuse-address sock) reuseaddress)
277
+ (sb-bsd-sockets:socket-bind sock ip port)
278
+ (sb-bsd-sockets:socket-listen sock backlog)
279
+ (make-stream-server-socket sock :element-type element-type))
280
+ (t (c)
281
+ ;; Make sure we don't leak filedescriptors
282
+ (sb-bsd-sockets:socket-close sock)
283
+ (error c)))))
284
+
285
+ (defmethod socket-accept ((socket stream-server-usocket) &key element-type)
286
+ (with-mapped-conditions (socket)
287
+ (let ((sock (sb-bsd-sockets:socket-accept (socket socket))))
288
+ (make-stream-socket
289
+ :socket sock
290
+ :stream (sb-bsd-sockets:socket-make-stream
291
+ sock
292
+ :input t :output t :buffering :full
293
+ :element-type (or element-type
294
+ (element-type socket)))))))
295
+
296
+ ;; Sockets and their associated streams are modelled as
297
+ ;; different objects. Be sure to close the stream (which
298
+ ;; closes the socket too) when closing a stream-socket.
299
+ (defmethod socket-close ((usocket usocket))
300
+ (when (wait-list usocket)
301
+ (remove-waiter (wait-list usocket) usocket))
302
+ (with-mapped-conditions (usocket)
303
+ (sb-bsd-sockets:socket-close (socket usocket))))
304
+
305
+ (defmethod socket-close ((usocket stream-usocket))
306
+ (when (wait-list usocket)
307
+ (remove-waiter (wait-list usocket) usocket))
308
+ (with-mapped-conditions (usocket)
309
+ (close (socket-stream usocket))))
310
+
311
+ (defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
312
+ (with-mapped-conditions (socket)
313
+ (let* ((s (socket socket))
314
+ (dest (if (and host port) (list (host-to-vector-quad host) port) nil)))
315
+ (sb-bsd-sockets:socket-send s buffer length :address dest))))
316
+
317
+ (defmethod socket-receive ((socket datagram-usocket) buffer length
318
+ &key (element-type '(unsigned-byte 8)))
319
+ (with-mapped-conditions (socket)
320
+ (let ((s (socket socket)))
321
+ (sb-bsd-sockets:socket-receive s buffer length :element-type element-type))))
322
+
323
+ (defmethod get-local-name ((usocket usocket))
324
+ (sb-bsd-sockets:socket-name (socket usocket)))
325
+
326
+ (defmethod get-peer-name ((usocket stream-usocket))
327
+ (sb-bsd-sockets:socket-peername (socket usocket)))
328
+
329
+ (defmethod get-local-address ((usocket usocket))
330
+ (nth-value 0 (get-local-name usocket)))
331
+
332
+ (defmethod get-peer-address ((usocket stream-usocket))
333
+ (nth-value 0 (get-peer-name usocket)))
334
+
335
+ (defmethod get-local-port ((usocket usocket))
336
+ (nth-value 1 (get-local-name usocket)))
337
+
338
+ (defmethod get-peer-port ((usocket stream-usocket))
339
+ (nth-value 1 (get-peer-name usocket)))
340
+
341
+
342
+ (defun get-host-by-address (address)
343
+ (with-mapped-conditions ()
344
+ (sb-bsd-sockets::host-ent-name
345
+ (sb-bsd-sockets:get-host-by-address address))))
346
+
347
+ (defun get-hosts-by-name (name)
348
+ (with-mapped-conditions ()
349
+ (sb-bsd-sockets::host-ent-addresses
350
+ (sb-bsd-sockets:get-host-by-name name))))
351
+
352
+ #+(and sbcl (not win32))
353
+ (progn
354
+
355
+ (defun %setup-wait-list (wait-list)
356
+ (declare (ignore wait-list)))
357
+
358
+ (defun %add-waiter (wait-list waiter)
359
+ (push (socket waiter) (wait-list-%wait wait-list)))
360
+
361
+ (defun %remove-waiter (wait-list waiter)
362
+ (setf (wait-list-%wait wait-list)
363
+ (remove (socket waiter) (wait-list-%wait wait-list))))
364
+
365
+
366
+
367
+ (defun wait-for-input-internal (sockets &key timeout)
368
+ (with-mapped-conditions ()
369
+ (sb-alien:with-alien ((rfds (sb-alien:struct sb-unix:fd-set)))
370
+ (sb-unix:fd-zero rfds)
371
+ (dolist (socket (wait-list-%wait sockets))
372
+ (sb-unix:fd-set
373
+ (sb-bsd-sockets:socket-file-descriptor socket)
374
+ rfds))
375
+ (multiple-value-bind
376
+ (secs musecs)
377
+ (split-timeout (or timeout 1))
378
+ (multiple-value-bind
379
+ (count err)
380
+ (sb-unix:unix-fast-select
381
+ (1+ (reduce #'max (wait-list-%wait sockets)
382
+ :key #'sb-bsd-sockets:socket-file-descriptor))
383
+ (sb-alien:addr rfds) nil nil
384
+ (when timeout secs) (when timeout musecs))
385
+ (if (null count)
386
+ (unless (= err sb-unix:EINTR)
387
+ (error (map-errno-error err)))
388
+ (when (< 0 count)
389
+ ;; process the result...
390
+ (dolist (x (wait-list-waiters sockets))
391
+ (when (sb-unix:fd-isset
392
+ (sb-bsd-sockets:socket-file-descriptor
393
+ (socket x))
394
+ rfds)
395
+ (setf (state x) :READ))))))))))
396
+ ) ; progn
397
+
398
+ #+(and sbcl win32)
399
+ (warn "wait-for-input not (yet!) supported...")
400
+
401
+ #+ecl
402
+ (progn
403
+ (defun wait-for-input-internal (wl &key timeout)
404
+ (with-mapped-conditions ()
405
+ (multiple-value-bind
406
+ (secs usecs)
407
+ (split-timeout (or timeout 1))
408
+ (multiple-value-bind
409
+ (result-fds err)
410
+ (read-select wl (when timeout secs) usecs)
411
+ (unless (null err)
412
+ (error (map-errno-error err)))))))
413
+
414
+ (defun %setup-wait-list (wl)
415
+ (setf (wait-list-%wait wl)
416
+ (fdset-alloc)))
417
+
418
+ (defun %add-waiter (wl w)
419
+ (declare (ignore wl w)))
420
+
421
+ (defun %remove-waiter (wl w)
422
+ (declare (ignore wl w)))
423
+
424
+ )
@@ -0,0 +1,261 @@
1
+ ;;;; $Id: scl.lisp 515 2010-01-07 18:26:06Z ctian $
2
+ ;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/scl.lisp $
3
+
4
+ ;;;; See LICENSE for licensing information.
5
+
6
+ (in-package :usocket)
7
+
8
+ (defparameter +scl-error-map+
9
+ (append +unix-errno-condition-map+
10
+ +unix-errno-error-map+))
11
+
12
+ (defun scl-map-socket-error (err &key condition socket)
13
+ (let ((usock-err (cdr (assoc err +scl-error-map+ :test #'member))))
14
+ (cond (usock-err
15
+ (if (subtypep usock-err 'error)
16
+ (error usock-err :socket socket)
17
+ (signal usock-err :socket socket)))
18
+ (t
19
+ (error 'unknown-error
20
+ :socket socket
21
+ :real-error condition)))))
22
+
23
+ (defun handle-condition (condition &optional (socket nil))
24
+ "Dispatch correct usocket condition."
25
+ (typecase condition
26
+ (ext::socket-error
27
+ (scl-map-socket-error (ext::socket-errno condition)
28
+ :socket socket
29
+ :condition condition))))
30
+
31
+ (defun socket-connect (host port &key (protocol :stream) (element-type 'character)
32
+ timeout deadline (nodelay t nodelay-specified)
33
+ (local-host nil local-host-p)
34
+ (local-port nil local-port-p)
35
+ &aux
36
+ (patch-udp-p (fboundp 'ext::inet-socket-send-to)))
37
+ (declare (ignore nodelay))
38
+ (when nodelay-specified (unsupported 'nodelay 'socket-connect))
39
+ (when deadline (unsupported 'deadline 'socket-connect))
40
+ (when timeout (unsupported 'timeout 'socket-connect))
41
+ (when (and local-host-p (not patch-udp-p))
42
+ (unsupported 'local-host 'socket-connect :minimum "1.3.9"))
43
+ (when (and local-port-p (not patch-udp-p))
44
+ (unsupported 'local-port 'socket-connect :minimum "1.3.9"))
45
+
46
+ (let ((socket))
47
+ (ecase protocol
48
+ (:stream
49
+ (setf socket (let ((args (list (host-to-hbo host) port :kind protocol)))
50
+ (when (and patch-udp-p (or local-host-p local-port-p))
51
+ (nconc args (list :local-host (when local-host
52
+ (host-to-hbo local-host))
53
+ :local-port local-port)))
54
+ (with-mapped-conditions (socket)
55
+ (apply #'ext:connect-to-inet-socket args))))
56
+ (let ((stream (sys:make-fd-stream socket :input t :output t
57
+ :element-type element-type
58
+ :buffering :full)))
59
+ (make-stream-socket :socket socket :stream stream)))
60
+ (:datagram
61
+ (when (not patch-udp-p)
62
+ (error 'unsupported
63
+ :feature '(protocol :datagram)
64
+ :context 'socket-connect
65
+ :minumum "1.3.9"))
66
+ (setf socket
67
+ (if (and host port)
68
+ (let ((args (list (host-to-hbo host) port :kind protocol)))
69
+ (when (and patch-udp-p (or local-host-p local-port-p))
70
+ (nconc args (list :local-host (when local-host
71
+ (host-to-hbo local-host))
72
+ :local-port local-port)))
73
+ (with-mapped-conditions (socket)
74
+ (apply #'ext:connect-to-inet-socket args)))
75
+ (if (or local-host-p local-port-p)
76
+ (with-mapped-conditions ()
77
+ (ext:create-inet-listener (or local-port 0)
78
+ protocol
79
+ :host (when local-host
80
+ (if (ip= local-host *wildcard-host*)
81
+ 0
82
+ (host-to-hbo local-host)))))
83
+ (with-mapped-conditions ()
84
+ (ext:create-inet-socket protocol)))))
85
+ (let ((usocket (make-datagram-socket socket)))
86
+ (ext:finalize usocket #'(lambda ()
87
+ (when (%open-p usocket)
88
+ (ext:close-socket socket))))
89
+ usocket)))))
90
+
91
+ (defun socket-listen (host port
92
+ &key reuseaddress
93
+ (reuse-address nil reuse-address-supplied-p)
94
+ (backlog 5)
95
+ (element-type 'character))
96
+ (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
97
+ (host (if (ip= host *wildcard-host*)
98
+ 0
99
+ (host-to-hbo host)))
100
+ (server-sock
101
+ (with-mapped-conditions ()
102
+ (ext:create-inet-listener port :stream
103
+ :host host
104
+ :reuse-address reuseaddress
105
+ :backlog backlog))))
106
+ (make-stream-server-socket server-sock :element-type element-type)))
107
+
108
+ (defmethod socket-accept ((usocket stream-server-usocket) &key element-type)
109
+ (with-mapped-conditions (usocket)
110
+ (let* ((sock (ext:accept-tcp-connection (socket usocket)))
111
+ (stream (sys:make-fd-stream sock :input t :output t
112
+ :element-type (or element-type
113
+ (element-type usocket))
114
+ :buffering :full)))
115
+ (make-stream-socket :socket sock :stream stream))))
116
+
117
+ ;; Sockets and their associated streams are modelled as
118
+ ;; different objects. Be sure to close the socket stream
119
+ ;; when closing stream-sockets; it makes sure buffers
120
+ ;; are flushed and the socket is closed correctly afterwards.
121
+ (defmethod socket-close ((usocket usocket))
122
+ "Close socket."
123
+ (when (wait-list usocket)
124
+ (remove-waiter (wait-list usocket) usocket))
125
+ (with-mapped-conditions (usocket)
126
+ (ext:close-socket (socket usocket))))
127
+
128
+ (defmethod socket-close ((usocket stream-usocket))
129
+ "Close socket."
130
+ (when (wait-list usocket)
131
+ (remove-waiter (wait-list usocket) usocket))
132
+ (with-mapped-conditions (usocket)
133
+ (close (socket-stream usocket))))
134
+
135
+ (defmethod socket-close :after ((socket datagram-usocket))
136
+ (setf (%open-p socket) nil))
137
+
138
+ (defmethod socket-send ((socket datagram-usocket) buffer length &key host port)
139
+ (let ((s (socket socket))
140
+ (host (if host (host-to-hbo host))))
141
+ (multiple-value-bind (result errno)
142
+ (ext:inet-socket-send-to s buffer length
143
+ :remote-host host :remote-port port)
144
+ (or result
145
+ (scl-map-socket-error errno :socket socket)))))
146
+
147
+ (defmethod socket-receive ((socket datagram-usocket) buffer length &key)
148
+ (let ((s (socket socket)))
149
+ (let ((real-buffer (or buffer
150
+ (make-array length :element-type '(unsigned-byte 8))))
151
+ (real-length (or length
152
+ (length buffer))))
153
+ (multiple-value-bind (result errno remote-host remote-port)
154
+ (ext:inet-socket-receive-from s real-buffer real-length)
155
+ (if result
156
+ (values real-buffer result remote-host remote-port)
157
+ (scl-map-socket-error errno :socket socket))))))
158
+
159
+ (defmethod get-local-name ((usocket usocket))
160
+ (multiple-value-bind (address port)
161
+ (with-mapped-conditions (usocket)
162
+ (ext:get-socket-host-and-port (socket usocket)))
163
+ (values (hbo-to-vector-quad address) port)))
164
+
165
+ (defmethod get-peer-name ((usocket stream-usocket))
166
+ (multiple-value-bind (address port)
167
+ (with-mapped-conditions (usocket)
168
+ (ext:get-peer-host-and-port (socket usocket)))
169
+ (values (hbo-to-vector-quad address) port)))
170
+
171
+ (defmethod get-local-address ((usocket usocket))
172
+ (nth-value 0 (get-local-name usocket)))
173
+
174
+ (defmethod get-peer-address ((usocket stream-usocket))
175
+ (nth-value 0 (get-peer-name usocket)))
176
+
177
+ (defmethod get-local-port ((usocket usocket))
178
+ (nth-value 1 (get-local-name usocket)))
179
+
180
+ (defmethod get-peer-port ((usocket stream-usocket))
181
+ (nth-value 1 (get-peer-name usocket)))
182
+
183
+
184
+ (defun get-host-by-address (address)
185
+ (multiple-value-bind (host errno)
186
+ (ext:lookup-host-entry (host-byte-order address))
187
+ (cond (host
188
+ (ext:host-entry-name host))
189
+ (t
190
+ (let ((condition (cdr (assoc errno +unix-ns-error-map+))))
191
+ (cond (condition
192
+ (error condition :host-or-ip address))
193
+ (t
194
+ (error 'ns-unknown-error :host-or-ip address
195
+ :real-error errno))))))))
196
+
197
+ (defun get-hosts-by-name (name)
198
+ (multiple-value-bind (host errno)
199
+ (ext:lookup-host-entry name)
200
+ (cond (host
201
+ (mapcar #'hbo-to-vector-quad
202
+ (ext:host-entry-addr-list host)))
203
+ (t
204
+ (let ((condition (cdr (assoc errno +unix-ns-error-map+))))
205
+ (cond (condition
206
+ (error condition :host-or-ip name))
207
+ (t
208
+ (error 'ns-unknown-error :host-or-ip name
209
+ :real-error errno))))))))
210
+
211
+ (defun get-host-name ()
212
+ (unix:unix-gethostname))
213
+
214
+
215
+ ;;
216
+ ;;
217
+ ;; WAIT-LIST part
218
+ ;;
219
+
220
+
221
+ (defun %add-waiter (wl waiter)
222
+ (declare (ignore wl waiter)))
223
+
224
+ (defun %remove-waiter (wl waiter)
225
+ (declare (ignore wl waiter)))
226
+
227
+ (defun %setup-wait-list (wl)
228
+ (declare (ignore wl)))
229
+
230
+ (defun wait-for-input-internal (wait-list &key timeout)
231
+ (let* ((sockets (wait-list-waiters wait-list))
232
+ (pollfd-size (alien:alien-size (alien:struct unix::pollfd) :bytes))
233
+ (nfds (length sockets))
234
+ (bytes (* nfds pollfd-size)))
235
+ (alien:with-bytes (fds-sap bytes)
236
+ (do ((sockets sockets (rest sockets))
237
+ (base 0 (+ base 8)))
238
+ ((endp sockets))
239
+ (let ((fd (socket (first sockets))))
240
+ (setf (sys:sap-ref-32 fds-sap base) fd)
241
+ (setf (sys:sap-ref-16 fds-sap (+ base 4)) unix::pollin)))
242
+ (multiple-value-bind (result errno)
243
+ (let ((thread:*thread-whostate* "Poll wait")
244
+ (timeout (if timeout
245
+ (truncate (* timeout 1000))
246
+ -1)))
247
+ (declare (inline unix:unix-poll))
248
+ (unix:unix-poll (alien:sap-alien fds-sap
249
+ (* (alien:struct unix::pollfd)))
250
+ nfds timeout))
251
+ (cond ((not result)
252
+ (error "~@<Polling error: ~A~:@>"
253
+ (unix:get-unix-error-msg errno)))
254
+ (t
255
+ (do ((sockets sockets (rest sockets))
256
+ (base 0 (+ base 8)))
257
+ ((endp sockets))
258
+ (let ((flags (sys:sap-ref-16 fds-sap (+ base 6))))
259
+ (unless (zerop (logand flags unix::pollin))
260
+ (setf (state (first sockets)) :READ))))))))))
261
+