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.
- data/LICENSE +1 -1
- data/README.md +4 -9
- data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
- data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
- data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
- data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
- data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
- data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
- data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
- data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
- data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
- data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
- data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
- data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
- data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
- data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
- data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
- data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
- data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
- data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
- data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
- data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
- data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
- data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
- data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
- data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
- data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
- data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
- data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
- data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
- data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
- data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
- data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
- data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
- data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
- data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
- data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
- data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
- data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
- data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
- data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
- data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
- data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
- data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
- data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
- data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
- data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
- data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
- data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
- data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
- data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
- data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
- data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
- data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
- data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
- data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
- data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
- data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
- data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
- data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
- data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
- data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
- data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
- data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
- data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
- data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
- data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
- data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
- data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
- data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
- data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
- data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
- data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
- data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
- data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
- data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
- data/lib/clucumber/vendor/lift/lift.asd +77 -0
- data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
- data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
- data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
- data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
- data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
- data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
- data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
- data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
- data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
- data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
- data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
- data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
- data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
- data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
- data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
- data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
- data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
- data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
- data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
- data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
- data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
- data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
- data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
- data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
- data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
- data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
- data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
- data/lib/clucumber/vendor/usocket/package.lisp +82 -0
- data/lib/clucumber/vendor/usocket/server.lisp +45 -0
- data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
- data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
- data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
- data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
- data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
- data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
- data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
- data/lib/clucumber.rb +29 -7
- 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
|
+
|