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,260 @@
1
+ ;;;; $Id: clisp.lisp 515 2010-01-07 18:26:06Z ctian $
2
+ ;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/clisp.lisp $
3
+
4
+ ;;;; See LICENSE for licensing information.
5
+
6
+ (in-package :usocket)
7
+
8
+
9
+ ;; utility routine for looking up the current host name
10
+ (FFI:DEF-CALL-OUT get-host-name-internal
11
+ (:name "gethostname")
12
+ (:arguments (name (FFI:C-PTR (FFI:C-ARRAY-MAX ffi:character 256))
13
+ :OUT :ALLOCA)
14
+ (len ffi:int))
15
+ #+win32 (:library "WS2_32")
16
+ (:language #-win32 :stdc
17
+ #+win32 :stdc-stdcall)
18
+ (:return-type ffi:int))
19
+
20
+
21
+ (defun get-host-name ()
22
+ (multiple-value-bind (retcode name)
23
+ (get-host-name-internal 256)
24
+ (when (= retcode 0)
25
+ name)))
26
+
27
+
28
+ #+win32
29
+ (defun remap-maybe-for-win32 (z)
30
+ (mapcar #'(lambda (x)
31
+ (cons (mapcar #'(lambda (y)
32
+ (+ 10000 y))
33
+ (car x))
34
+ (cdr x)))
35
+ z))
36
+
37
+ (defparameter +clisp-error-map+
38
+ #+win32
39
+ (append (remap-maybe-for-win32 +unix-errno-condition-map+)
40
+ (remap-maybe-for-win32 +unix-errno-error-map+))
41
+ #-win32
42
+ (append +unix-errno-condition-map+
43
+ +unix-errno-error-map+))
44
+
45
+ (defun handle-condition (condition &optional (socket nil))
46
+ "Dispatch correct usocket condition."
47
+ (typecase condition
48
+ (system::simple-os-error
49
+ (let ((usock-err
50
+ (cdr (assoc (car (simple-condition-format-arguments condition))
51
+ +clisp-error-map+ :test #'member))))
52
+ (when usock-err ;; don't claim the error if we don't know
53
+ ;; it's actually a socket error ...
54
+ (if (subtypep usock-err 'error)
55
+ (error usock-err :socket socket)
56
+ (signal usock-err :socket socket)))))))
57
+
58
+ (defun socket-connect (host port &key (protocol :stream) (element-type 'character)
59
+ timeout deadline (nodelay t nodelay-specified)
60
+ local-host local-port)
61
+ (declare (ignore nodelay))
62
+ (when timeout (unsupported 'timeout 'socket-connect))
63
+ (when deadline (unsupported 'deadline 'socket-connect))
64
+ (when nodelay-specified (unsupported 'nodelay 'socket-connect))
65
+ (when local-host (unsupported 'local-host 'socket-connect))
66
+ (when local-port (unsupported 'local-port 'socket-connect))
67
+
68
+ (let ((socket)
69
+ (hostname (host-to-hostname host)))
70
+ (with-mapped-conditions (socket)
71
+ (setf socket
72
+ (if timeout
73
+ (socket:socket-connect port hostname
74
+ :element-type element-type
75
+ :buffered t
76
+ :timeout timeout)
77
+ (socket:socket-connect port hostname
78
+ :element-type element-type
79
+ :buffered t))))
80
+ (make-stream-socket :socket socket
81
+ :stream socket))) ;; the socket is a stream too
82
+
83
+ (defun socket-listen (host port
84
+ &key reuseaddress
85
+ (reuse-address nil reuse-address-supplied-p)
86
+ (backlog 5)
87
+ (element-type 'character))
88
+ ;; clisp 2.39 sets SO_REUSEADDRESS to 1 by default; no need to
89
+ ;; to explicitly turn it on; unfortunately, there's no way to turn it off...
90
+ (declare (ignore reuseaddress reuse-address reuse-address-supplied-p))
91
+ (let ((sock (apply #'socket:socket-server
92
+ (append (list port
93
+ :backlog backlog)
94
+ (when (ip/= host *wildcard-host*)
95
+ (list :interface host))))))
96
+ (with-mapped-conditions ()
97
+ (make-stream-server-socket sock :element-type element-type))))
98
+
99
+ (defmethod socket-accept ((socket stream-server-usocket) &key element-type)
100
+ (let ((stream
101
+ (with-mapped-conditions (socket)
102
+ (socket:socket-accept (socket socket)
103
+ :element-type (or element-type
104
+ (element-type socket))))))
105
+ (make-stream-socket :socket stream
106
+ :stream stream)))
107
+
108
+ ;; Only one close method required:
109
+ ;; sockets and their associated streams
110
+ ;; are the same object
111
+ (defmethod socket-close ((usocket usocket))
112
+ "Close socket."
113
+ (when (wait-list usocket)
114
+ (remove-waiter (wait-list usocket) usocket))
115
+ (with-mapped-conditions (usocket)
116
+ (close (socket usocket))))
117
+
118
+ (defmethod socket-close ((usocket stream-server-usocket))
119
+ (when (wait-list usocket)
120
+ (remove-waiter (wait-list usocket) usocket))
121
+ (socket:socket-server-close (socket usocket)))
122
+
123
+ (defmethod get-local-name ((usocket usocket))
124
+ (multiple-value-bind
125
+ (address port)
126
+ (socket:socket-stream-local (socket usocket) t)
127
+ (values (dotted-quad-to-vector-quad address) port)))
128
+
129
+ (defmethod get-peer-name ((usocket stream-usocket))
130
+ (multiple-value-bind
131
+ (address port)
132
+ (socket:socket-stream-peer (socket usocket) t)
133
+ (values (dotted-quad-to-vector-quad address) port)))
134
+
135
+ (defmethod get-local-address ((usocket usocket))
136
+ (nth-value 0 (get-local-name usocket)))
137
+
138
+ (defmethod get-peer-address ((usocket stream-usocket))
139
+ (nth-value 0 (get-peer-name usocket)))
140
+
141
+ (defmethod get-local-port ((usocket usocket))
142
+ (nth-value 1 (get-local-name usocket)))
143
+
144
+ (defmethod get-peer-port ((usocket stream-usocket))
145
+ (nth-value 1 (get-peer-name usocket)))
146
+
147
+
148
+ (defun %setup-wait-list (wait-list)
149
+ (declare (ignore wait-list)))
150
+
151
+ (defun %add-waiter (wait-list waiter)
152
+ (push (cons (socket waiter) NIL) (wait-list-%wait wait-list)))
153
+
154
+ (defun %remove-waiter (wait-list waiter)
155
+ (setf (wait-list-%wait wait-list)
156
+ (remove (socket waiter) (wait-list-%wait wait-list) :key #'car)))
157
+
158
+ (defmethod wait-for-input-internal (wait-list &key timeout)
159
+ (with-mapped-conditions ()
160
+ (multiple-value-bind
161
+ (secs musecs)
162
+ (split-timeout (or timeout 1))
163
+ (dolist (x (wait-list-%wait wait-list))
164
+ (setf (cdr x) :INPUT))
165
+ (let* ((request-list (wait-list-%wait wait-list))
166
+ (status-list (if timeout
167
+ (socket:socket-status request-list secs musecs)
168
+ (socket:socket-status request-list)))
169
+ (sockets (wait-list-waiters wait-list)))
170
+ (do* ((x (pop sockets) (pop sockets))
171
+ (y (pop status-list) (pop status-list)))
172
+ ((null x))
173
+ (when (eq y :INPUT)
174
+ (setf (state x) :READ)))
175
+ wait-list))))
176
+
177
+
178
+ ;;
179
+ ;; UDP/Datagram sockets!
180
+ ;;
181
+
182
+ #+rawsock
183
+ (progn
184
+
185
+ (defun make-sockaddr_in ()
186
+ (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0))
187
+
188
+ (declaim (inline fill-sockaddr_in))
189
+ (defun fill-sockaddr_in (sockaddr_in ip port)
190
+ (port-to-octet-buffer sockaddr_in port)
191
+ (ip-to-octet-buffer sockaddr_in ip :start 2)
192
+ sockaddr_in)
193
+
194
+ (defun socket-create-datagram (local-port
195
+ &key (local-host *wildcard-host*)
196
+ remote-host
197
+ remote-port)
198
+ (let ((sock (rawsock:socket :inet :dgram 0))
199
+ (lsock_addr (fill-sockaddr_in (make-sockaddr_in)
200
+ local-host local-port))
201
+ (rsock_addr (when remote-host
202
+ (fill-sockaddr_in (make-sockaddr_in)
203
+ remote-host (or remote-port
204
+ local-port)))))
205
+ (bind sock lsock_addr)
206
+ (when rsock_addr
207
+ (connect sock rsock_addr))
208
+ (make-datagram-socket sock :connected-p (if rsock_addr t nil))))
209
+
210
+ (defun socket-receive (socket buffer &key (size (length buffer)))
211
+ "Returns the buffer, the number of octets copied into the buffer (received)
212
+ and the address of the sender as values."
213
+ (let* ((sock (socket socket))
214
+ (sockaddr (when (not (connected-p socket))
215
+ (rawsock:make-sockaddr)))
216
+ (rv (if sockaddr
217
+ (rawsock:recvfrom sock buffer sockaddr
218
+ :start 0
219
+ :end size)
220
+ (rawsock:recv sock buffer
221
+ :start 0
222
+ :end size))))
223
+ (values buffer
224
+ rv
225
+ (list (ip-from-octet-buffer (sockaddr-data sockaddr) 4)
226
+ (port-from-octet-buffer (sockaddr-data sockaddr) 2)))))
227
+
228
+ (defun socket-send (socket buffer &key address (size (length buffer)))
229
+ "Returns the number of octets sent."
230
+ (let* ((sock (socket socket))
231
+ (sockaddr (when address
232
+ (rawsock:make-sockaddr :INET
233
+ (fill-sockaddr_in
234
+ (make-sockaddr_in)
235
+ (host-byte-order
236
+ (second address))
237
+ (first address)))))
238
+ (rv (if address
239
+ (rawsock:sendto sock buffer sockaddr
240
+ :start 0
241
+ :end size)
242
+ (rawsock:send sock buffer
243
+ :start 0
244
+ :end size))))
245
+ rv))
246
+
247
+ (defmethod socket-close ((usocket datagram-usocket))
248
+ (when (wait-list usocket)
249
+ (remove-waiter (wait-list usocket) usocket))
250
+ (rawsock:sock-close (socket usocket)))
251
+
252
+ )
253
+
254
+ #-rawsock
255
+ (progn
256
+ (warn "This image doesn't contain the RAWSOCK package.
257
+ To enable UDP socket support, please be sure to use the -Kfull parameter
258
+ at startup, or to enable RAWSOCK support during compilation.")
259
+
260
+ )
@@ -0,0 +1,266 @@
1
+ ;;;; $Id: cmucl.lisp 515 2010-01-07 18:26:06Z ctian $
2
+ ;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/cmucl.lisp $
3
+
4
+ ;;;; See LICENSE for licensing information.
5
+
6
+ (in-package :usocket)
7
+
8
+ #+win32
9
+ (defun remap-for-win32 (z)
10
+ (mapcar #'(lambda (x)
11
+ (cons (mapcar #'(lambda (y)
12
+ (+ 10000 y))
13
+ (car x))
14
+ (cdr x)))
15
+ z))
16
+
17
+ (defparameter +cmucl-error-map+
18
+ #+win32
19
+ (append (remap-for-win32 +unix-errno-condition-map+)
20
+ (remap-for-win32 +unix-errno-error-map+))
21
+ #-win32
22
+ (append +unix-errno-condition-map+
23
+ +unix-errno-error-map+))
24
+
25
+ (defun cmucl-map-socket-error (err &key condition socket)
26
+ (let ((usock-err
27
+ (cdr (assoc err +cmucl-error-map+ :test #'member))))
28
+ (if usock-err
29
+ (if (subtypep usock-err 'error)
30
+ (error usock-err :socket socket)
31
+ (signal usock-err :socket socket))
32
+ (error 'unknown-error
33
+ :socket socket
34
+ :real-error condition))))
35
+
36
+ ;; CMUCL error handling is brain-dead: it doesn't preserve any
37
+ ;; information other than the OS error string from which the
38
+ ;; error can be determined. The OS error string isn't good enough
39
+ ;; given that it may have been localized (l10n).
40
+ ;;
41
+ ;; The above applies to versions pre 19b; 19d and newer are expected to
42
+ ;; contain even better error reporting.
43
+ ;;
44
+ ;;
45
+ ;; Just catch the errors and encapsulate them in an unknown-error
46
+ (defun handle-condition (condition &optional (socket nil))
47
+ "Dispatch correct usocket condition."
48
+ (typecase condition
49
+ (ext::socket-error (cmucl-map-socket-error (ext::socket-errno condition)
50
+ :socket socket
51
+ :condition condition))))
52
+
53
+ (defun socket-connect (host port &key (protocol :stream) (element-type 'character)
54
+ timeout deadline (nodelay t nodelay-specified)
55
+ (local-host nil local-host-p)
56
+ (local-port nil local-port-p)
57
+ &aux
58
+ (local-bind-p (fboundp 'ext::bind-inet-socket)))
59
+ (declare (ignore nodelay))
60
+ (when timeout (unsupported 'timeout 'socket-connect))
61
+ (when deadline (unsupported 'deadline 'socket-connect))
62
+ (when nodelay-specified (unsupported 'nodelay 'socket-connect))
63
+ (when (and local-host-p (not local-bind-p))
64
+ (unsupported 'local-host 'socket-connect :minimum "Snapshot 2008-08 (19E)"))
65
+ (when (and local-port-p (not local-bind-p))
66
+ (unsupported 'local-port 'socket-connect :minimum "Snapshot 2008-08 (19E)"))
67
+
68
+ (let ((socket))
69
+ (ecase protocol
70
+ (:stream
71
+ (setf socket
72
+ (let ((args (list (host-to-hbo host) port protocol)))
73
+ (when (and local-bind-p (or local-host-p local-port-p))
74
+ (nconc args (list :local-host (when local-host
75
+ (host-to-hbo local-host))
76
+ :local-port local-port)))
77
+ (with-mapped-conditions (socket)
78
+ (apply #'ext:connect-to-inet-socket args))))
79
+ (if socket
80
+ (let* ((stream (sys:make-fd-stream socket :input t :output t
81
+ :element-type element-type
82
+ :buffering :full))
83
+ ;;###FIXME the above line probably needs an :external-format
84
+ (usocket (make-stream-socket :socket socket
85
+ :stream stream)))
86
+ usocket)
87
+ (let ((err (unix:unix-errno)))
88
+ (when err (cmucl-map-socket-error err)))))
89
+ (:datagram
90
+ (setf socket
91
+ (if (and host port)
92
+ (let ((args (list (host-to-hbo host) port protocol)))
93
+ (when (and local-bind-p (or local-host-p local-port-p))
94
+ (nconc args (list :local-host (when local-host
95
+ (host-to-hbo local-host))
96
+ :local-port local-port)))
97
+ (with-mapped-conditions (socket)
98
+ (apply #'ext:connect-to-inet-socket args)))
99
+ (if (or local-host-p local-port-p)
100
+ (with-mapped-conditions (socket)
101
+ (apply #'ext:create-inet-listener
102
+ (nconc (list (or local-port 0) protocol)
103
+ (when (and local-host-p
104
+ (ip/= local-host *wildcard-host*))
105
+ (list :host (host-to-hbo local-host))))))
106
+ (with-mapped-conditions (socket)
107
+ (ext:create-inet-socket protocol)))))
108
+ (if socket
109
+ (let ((usocket (make-datagram-socket socket)))
110
+ (ext:finalize usocket #'(lambda () (when (%open-p usocket)
111
+ (ext:close-socket socket))))
112
+ usocket)
113
+ (let ((err (unix:unix-errno)))
114
+ (when err (cmucl-map-socket-error err))))))))
115
+
116
+ (defun socket-listen (host port
117
+ &key reuseaddress
118
+ (reuse-address nil reuse-address-supplied-p)
119
+ (backlog 5)
120
+ (element-type 'character))
121
+ (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress))
122
+ (server-sock
123
+ (with-mapped-conditions ()
124
+ (apply #'ext:create-inet-listener
125
+ (nconc (list port :stream
126
+ :backlog backlog
127
+ :reuse-address reuseaddress)
128
+ (when (ip/= host *wildcard-host*)
129
+ (list :host
130
+ (host-to-hbo host))))))))
131
+ (make-stream-server-socket server-sock :element-type element-type)))
132
+
133
+ (defmethod socket-accept ((usocket stream-server-usocket) &key element-type)
134
+ (with-mapped-conditions (usocket)
135
+ (let* ((sock (ext:accept-tcp-connection (socket usocket)))
136
+ (stream (sys:make-fd-stream sock :input t :output t
137
+ :element-type (or element-type
138
+ (element-type usocket))
139
+ :buffering :full)))
140
+ (make-stream-socket :socket sock :stream stream))))
141
+
142
+ ;; Sockets and socket streams are represented
143
+ ;; by different objects. Be sure to close the
144
+ ;; socket stream when closing a stream socket.
145
+ (defmethod socket-close ((usocket stream-usocket))
146
+ "Close socket."
147
+ (when (wait-list usocket)
148
+ (remove-waiter (wait-list usocket) usocket))
149
+ (with-mapped-conditions (usocket)
150
+ (close (socket-stream usocket))))
151
+
152
+ (defmethod socket-close ((usocket usocket))
153
+ "Close socket."
154
+ (when (wait-list usocket)
155
+ (remove-waiter (wait-list usocket) usocket))
156
+ (with-mapped-conditions (usocket)
157
+ (ext:close-socket (socket usocket))))
158
+
159
+ (defmethod socket-close :after ((socket datagram-usocket))
160
+ (setf (%open-p socket) nil))
161
+
162
+ (defmethod socket-send ((usocket datagram-usocket) buffer length &key host port)
163
+ (with-mapped-conditions (usocket)
164
+ (ext:inet-sendto (socket usocket) buffer length (if host (host-to-hbo host)) port)))
165
+
166
+ (defmethod socket-receive ((usocket datagram-usocket) buffer length &key)
167
+ (let ((real-buffer (or buffer
168
+ (make-array length :element-type '(unsigned-byte 8))))
169
+ (real-length (or length
170
+ (length buffer))))
171
+ (multiple-value-bind (nbytes remote-host remote-port)
172
+ (with-mapped-conditions (usocket)
173
+ (ext:inet-recvfrom (socket usocket) real-buffer real-length))
174
+ (when (plusp nbytes)
175
+ (values real-buffer nbytes remote-host remote-port)))))
176
+
177
+ (defmethod get-local-name ((usocket usocket))
178
+ (multiple-value-bind
179
+ (address port)
180
+ (ext:get-socket-host-and-port (socket usocket))
181
+ (values (hbo-to-vector-quad address) port)))
182
+
183
+ (defmethod get-peer-name ((usocket stream-usocket))
184
+ (multiple-value-bind
185
+ (address port)
186
+ (ext:get-peer-host-and-port (socket usocket))
187
+ (values (hbo-to-vector-quad address) port)))
188
+
189
+ (defmethod get-local-address ((usocket usocket))
190
+ (nth-value 0 (get-local-name usocket)))
191
+
192
+ (defmethod get-peer-address ((usocket stream-usocket))
193
+ (nth-value 0 (get-peer-name usocket)))
194
+
195
+ (defmethod get-local-port ((usocket usocket))
196
+ (nth-value 1 (get-local-name usocket)))
197
+
198
+ (defmethod get-peer-port ((usocket stream-usocket))
199
+ (nth-value 1 (get-peer-name usocket)))
200
+
201
+
202
+ (defun lookup-host-entry (host)
203
+ (multiple-value-bind
204
+ (entry errno)
205
+ (ext:lookup-host-entry host)
206
+ (if entry
207
+ entry
208
+ ;;###The constants below work on *most* OSes, but are defined as the
209
+ ;; constants mentioned in C
210
+ (let ((exception
211
+ (second (assoc errno
212
+ '((1 ns-host-not-found-error) ;; HOST_NOT_FOUND
213
+ (2 ns-no-recovery-error) ;; NO_DATA
214
+ (3 ns-no-recovery-error) ;; NO_RECOVERY
215
+ (4 ns-try-again)))))) ;; TRY_AGAIN
216
+ (when exception
217
+ (error exception))))))
218
+
219
+
220
+ (defun get-host-by-address (address)
221
+ (handler-case (ext:host-entry-name
222
+ (lookup-host-entry (host-byte-order address)))
223
+ (condition (condition) (handle-condition condition))))
224
+
225
+ (defun get-hosts-by-name (name)
226
+ (handler-case (mapcar #'hbo-to-vector-quad
227
+ (ext:host-entry-addr-list
228
+ (lookup-host-entry name)))
229
+ (condition (condition) (handle-condition condition))))
230
+
231
+ (defun get-host-name ()
232
+ (unix:unix-gethostname))
233
+
234
+ (defun %setup-wait-list (wait-list)
235
+ (declare (ignore wait-list)))
236
+
237
+ (defun %add-waiter (wait-list waiter)
238
+ (push (socket waiter) (wait-list-%wait wait-list)))
239
+
240
+ (defun %remove-waiter (wait-list waiter)
241
+ (setf (wait-list-%wait wait-list)
242
+ (remove (socket waiter) (wait-list-%wait wait-list))))
243
+
244
+ (defun wait-for-input-internal (wait-list &key timeout)
245
+ (with-mapped-conditions ()
246
+ (alien:with-alien ((rfds (alien:struct unix:fd-set)))
247
+ (unix:fd-zero rfds)
248
+ (dolist (socket (wait-list-%wait wait-list))
249
+ (unix:fd-set socket rfds))
250
+ (multiple-value-bind
251
+ (secs musecs)
252
+ (split-timeout (or timeout 1))
253
+ (multiple-value-bind
254
+ (count err)
255
+ (unix:unix-fast-select (1+ (reduce #'max
256
+ (wait-list-%wait wait-list)))
257
+ (alien:addr rfds) nil nil
258
+ (when timeout secs) musecs)
259
+ (if (<= 0 count)
260
+ ;; process the result...
261
+ (dolist (x (wait-list-waiters wait-list))
262
+ (when (unix:fd-isset (socket x) rfds)
263
+ (setf (state x) :READ)))
264
+ (progn
265
+ ;;###FIXME generate an error, except for EINTR
266
+ )))))))