ecl.lisp - clic - Clic is an command line interactive client for gopher written in Common LISP
HTML git clone git://bitreich.org/clic/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/clic/
DIR Log
DIR Files
DIR Refs
DIR Tags
DIR README
DIR LICENSE
---
ecl.lisp (5141B)
---
1 ;;;; -*- Mode: Lisp -*-
2
3 ;;;; Foreign functions defined by ECL's DFFI, used for #+ecl-bytecmp only.
4 ;;;; See LICENSE for licensing information.
5
6 (in-package :usocket)
7
8 #+(and ecl-bytecmp windows)
9 (eval-when (:load-toplevel :execute)
10 (ffi:load-foreign-library "ws2_32.dll" :module "ws2_32"))
11
12 #+(and ecl-bytecmp windows)
13 (progn
14 (ffi:def-function ("gethostname" c-gethostname)
15 ((name (* :unsigned-char))
16 (len :int))
17 :returning :int
18 :module "ws2_32")
19
20 (defun get-host-name ()
21 "Returns the hostname"
22 (ffi:with-foreign-object (name '(:array :unsigned-char 256))
23 (when (zerop (c-gethostname (ffi:char-array-to-pointer name) 256))
24 (ffi:convert-from-foreign-string name))))
25
26 (ffi:def-foreign-type ws-socket :unsigned-int)
27 (ffi:def-foreign-type ws-dword :unsigned-long)
28 (ffi:def-foreign-type ws-event :unsigned-int)
29
30 (ffi:def-struct wsa-network-events
31 (network-events :long)
32 (error-code (:array :int 10)))
33
34 (ffi:def-function ("WSACreateEvent" wsa-event-create)
35 ()
36 :returning ws-event
37 :module "ws2_32")
38
39 (ffi:def-function ("WSACloseEvent" c-wsa-event-close)
40 ((event-object ws-event))
41 :returning :int
42 :module "ws2_32")
43
44 (defun wsa-event-close (ws-event)
45 (not (zerop (c-wsa-event-close ws-event))))
46
47 (ffi:def-function ("WSAEnumNetworkEvents" wsa-enum-network-events)
48 ((socket ws-socket)
49 (event-object ws-event)
50 (network-events (* wsa-network-events)))
51 :returning :int
52 :module "ws2_32")
53
54 (ffi:def-function ("WSAEventSelect" wsa-event-select)
55 ((socket ws-socket)
56 (event-object ws-event)
57 (network-events :long))
58 :returning :int
59 :module "ws2_32")
60
61 (ffi:def-function ("WSAWaitForMultipleEvents" c-wsa-wait-for-multiple-events)
62 ((number-of-events ws-dword)
63 (events (* ws-event))
64 (wait-all-p :int)
65 (timeout ws-dword)
66 (alertable-p :int))
67 :returning ws-dword
68 :module "ws2_32")
69
70 (defun wsa-wait-for-multiple-events (number-of-events events wait-all-p timeout alertable-p)
71 (c-wsa-wait-for-multiple-events number-of-events
72 events
73 (if wait-all-p -1 0)
74 timeout
75 (if alertable-p -1 0)))
76
77 (ffi:def-function ("ioctlsocket" wsa-ioctlsocket)
78 ((socket ws-socket)
79 (cmd :long)
80 (argp (* :unsigned-long)))
81 :returning :int
82 :module "ws2_32")
83
84 (ffi:def-function ("WSAGetLastError" wsa-get-last-error)
85 ()
86 :returning :int
87 :module "ws2_32")
88
89 (defun maybe-wsa-error (rv &optional socket)
90 (unless (zerop rv)
91 (raise-usock-err (wsa-get-last-error) socket)))
92
93 (defun bytes-available-for-read (socket)
94 (ffi:with-foreign-object (int-ptr :unsigned-long)
95 (maybe-wsa-error (wsa-ioctlsocket (socket-handle socket) fionread int-ptr)
96 socket)
97 (let ((int (ffi:deref-pointer int-ptr :unsigned-long)))
98 (prog1 int
99 (when (plusp int)
100 (setf (state socket) :read))))))
101
102 (defun map-network-events (func network-events)
103 (let ((event-map (ffi:get-slot-value network-events 'wsa-network-events 'network-events))
104 (error-array (ffi:get-slot-pointer network-events 'wsa-network-events 'error-code)))
105 (unless (zerop event-map)
106 (dotimes (i fd-max-events)
107 (unless (zerop (ldb (byte 1 i) event-map))
108 (funcall func (ffi:deref-array error-array '(:array :int 10) i)))))))
109
110 (defun update-ready-and-state-slots (sockets)
111 (dolist (socket sockets)
112 (if (%ready-p socket)
113 (progn
114 (setf (state socket) :READ))
115 (ffi:with-foreign-object (network-events 'wsa-network-events)
116 (let ((rv (wsa-enum-network-events (socket-handle socket) 0 network-events)))
117 (if (zerop rv)
118 (map-network-events
119 #'(lambda (err-code)
120 (if (zerop err-code)
121 (progn
122 (setf (state socket) :READ)
123 (when (stream-server-usocket-p socket)
124 (setf (%ready-p socket) t)))
125 (raise-usock-err err-code socket)))
126 network-events)
127 (maybe-wsa-error rv socket)))))))
128
129 (defun os-wait-list-%wait (wait-list)
130 (ffi:deref-pointer (wait-list-%wait wait-list) 'ws-event))
131
132 (defun (setf os-wait-list-%wait) (value wait-list)
133 (setf (ffi:deref-pointer (wait-list-%wait wait-list) 'ws-event) value))
134
135 (defun free-wait-list (wl)
136 (when (wait-list-p wl)
137 (unless (null (wait-list-%wait wl))
138 (wsa-event-close (os-wait-list-%wait wl))
139 (ffi:free-foreign-object (wait-list-%wait wl))
140 (setf (wait-list-%wait wl) nil))))
141
142 (defun %setup-wait-list (wait-list)
143 (setf (wait-list-%wait wait-list)
144 (ffi:allocate-foreign-object 'ws-event))
145 (setf (os-wait-list-%wait wait-list)
146 (wsa-event-create))
147 (ext:set-finalizer wait-list #'free-wait-list))
148
149 (defun os-socket-handle (usocket)
150 (socket-handle usocket))
151
152 ) ; #+(and ecl-bytecmp windows)