-
Notifications
You must be signed in to change notification settings - Fork 25
/
nanomsg.sls
454 lines (403 loc) · 10.8 KB
/
nanomsg.sls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
;;
;; Copyright 2016 Aldo Nicolas Bruno
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
#!r6rs
(library
(nanomsg)
(export
nanomsg-library-init
nn-errno nn-strerror nn-bind nn-send nn-recv nn-connect nn-poll nn-close
nn-socket nn-assert nn-shutdown nn-freemsg nn-recvmsg nn-sendmsg
nn-strerror nn-setsockopt nn-setsockopt/int
nn-getsockopt nn-get-statistic nn-device nn-symbol
NN_MSG
NN_SOCKADDR_MAX
NN_SOL_SOCKET
NN_LINGER
NN_SNDBUF
NN_RCVBUF
NN_SNDTIMEO
NN_RCVTIMEO
NN_RECONNECT_IVL
NN_RECONNECT_IVL_MAX
NN_SNDPRIO
NN_RCVPRIO
NN_SNDFD
NN_RCVFD
NN_DOMAIN
NN_PROTOCOL
NN_IPV4ONLY
NN_SOCKET_NAME
NN_RCVMAXSIZE
NN_MAXTTL
NN_DONTWAIT
NN_POLLIN
NN_POLLOUT
NN_STAT_ESTABLISHED_CONNECTIONS
NN_STAT_ACCEPTED_CONNECTIONS
NN_STAT_DROPPED_CONNECTIONS
NN_STAT_BROKEN_CONNECTIONS
NN_STAT_CONNECT_ERRORS
NN_STAT_BIND_ERRORS
NN_STAT_ACCEPT_ERRORS
NN_STAT_CURRENT_CONNECTIONS
NN_STAT_INPROGRESS_CONNECTIONS
NN_STAT_CURRENT_EP_ERRORS
NN_STAT_MESSAGES_SENT
NN_STAT_MESSAGES_RECEIVED
NN_STAT_BYTES_SENT
NN_STAT_BYTES_RECEIVED
NN_STAT_CURRENT_SND_PRIORITY
;NN_PROTO_PAIR
NN_PAIR
;NN_PROTO_PUBSUB
NN_PUB
NN_SUB
NN_SUB_SUBSCRIBE
NN_SUB_UNSUBSCRIBE
;NN_PROTO_REQREP
NN_REQ
NN_REP
NN_REQ_RESEND_IVL
NN_TCP
NN_TCP_NODELAY
;NN_PROTO_PIPELINE
NN_PUSH
NN_PULL
;NN_PROTO_BUS
;NN_PROTO_SURVEY
NN_SURVEYOR
NN_RESPONDENT
NN_SURVEYOR_DEADLINE
NN_INPROC
NN_IPC
;NN_IPC_SEC_ATTR
;NN_IPC_OUTBUFSZ
;NN_IPC_INBUFSZ
NN_WS
NN_WS_MSG_TYPE
NN_WS_MSG_TYPE_TEXT
NN_WS_MSG_TYPE_BINARY
NN_BUS
NN_NS_NAMESPACE
NN_NS_VERSION
NN_NS_DOMAIN
NN_NS_TRANSPORT
NN_NS_PROTOCOL
NN_NS_OPTION_LEVEL
NN_NS_SOCKET_OPTION
NN_NS_TRANSPORT_OPTION
NN_NS_OPTION_TYPE
NN_NS_OPTION_UNIT
NN_NS_FLAG
NN_NS_ERROR
NN_NS_LIMIT
NN_NS_EVENT
NN_NS_STATISTIC
NN_TYPE_NONE
NN_TYPE_INT
NN_TYPE_STR
NN_UNIT_NONE
NN_UNIT_BYTES
NN_UNIT_MILLISECONDS
NN_UNIT_PRIORITY
NN_UNIT_BOOLEAN
NN_UNIT_MESSAGES
NN_UNIT_COUNTER
AF_SP AF_SP_RAW
NN_NOTSUP
NN_EPROTONOSUPPORT
NN_ENOBUFS
NN_ENETDOWN
NN_EADDRINUSE
NN_EADDRNOTAVAIL
NN_ECONNREFUSED
NN_EINPROGRESS
NN_ENOTSOCK
NN_EAFNOSUPPORT
NN_EPROTO
NN_EAGAIN
NN_EBADF
NN_EINVAL
NN_EMFILE
NN_EFAULT
NN_EACCES
NN_EACCESS
NN_ENETRESET
NN_ENETUNREACH
NN_EHOSTUNREACH
NN_ENOTCONN
NN_EMSGSIZE
NN_ETIMEDOUT
NN_ECONNABORTED
NN_ECONNRESET
NN_ENOPROTOOPT
NN_EISCONN
NN_ESOCKTNOSUPPORT
NN_ETERM
NN_EFSM
EADDRINUSE
EADDRNOTAVAIL
EAFNOSUPPORT
EAGAIN
EBADF
ECONNREFUSED
EFAULT
EFSM
EINPROGRESS
EINTR
EINVAL
EMFILE
ENAMETOOLONG
ENETDOWN
ENOBUFS
ENODEV
ENOMEM
ENOPROTOOPT
ENOTSOCK
ENOTSUP
EPROTO
EPROTONOSUPPORT
ETERM
ETIMEDOUT
EACCES
ECONNABORTED
ECONNRESET
EHOSTUNREACH
EMSGSIZE
ENETRESET
ENETUNREACH
ENOTCONN
NN_VERSION_CURRENT
NN_VERSION_REVISION
NN_VERSION_AGE
) ;export
(import (ffi-utils) (chezscheme))
(define (nanomsg-library-init . t)
(load-shared-object (if (null? t) "libnanomsg.so" (car t))))
(define-syntax define-nn-func
(lambda (x)
(syntax-case x ()
[(_ ret-type name ((arg-name arg-type) ...) c-name)
(with-syntax
([function-ftype
(datum->syntax #'name
(string->symbol
(string-append
(symbol->string
(syntax->datum #'name)) "-ft")))] )
#`(begin
(define (name arg-name ...)
(define-ftype function-ftype (function (arg-type ...) ret-type))
(let* ([function-fptr (make-ftype-pointer function-ftype c-name)]
[function (ftype-ref function-ftype () function-fptr)])
(let ([result (function arg-name ...)])
#,(if (and (eq? (datum ret-type) 'int)
(not (eq? (datum name) 'nn-errno)))
#'(if (< result 0)
(let ([errno (nn-errno)])
(if (= errno EAGAIN)
#f
(errorf 'name "returned error ~d: ~d"
errno (nn-strerror errno))))
result)
#'result))))))])))
(define-syntax nn-error
(syntax-rules ()
((_ name n )
(define-syntax name (identifier-syntax (+ 156384712 n))))))
(nn-error NN_NOTSUP 1)
(nn-error NN_EPROTONOSUPPORT 2)
(nn-error NN_ENOBUFS 3)
(nn-error NN_ENETDOWN 4)
(nn-error NN_EADDRINUSE 5)
(nn-error NN_EADDRNOTAVAIL 6)
(nn-error NN_ECONNREFUSED 7)
(nn-error NN_EINPROGRESS 8)
(nn-error NN_ENOTSOCK 9)
(nn-error NN_EAFNOSUPPORT 10)
(nn-error NN_EPROTO 11)
(nn-error NN_EAGAIN 12)
(nn-error NN_EBADF 13)
(nn-error NN_EINVAL 14)
(nn-error NN_EMFILE 15)
(nn-error NN_EFAULT 16)
(nn-error NN_EACCES 17)
(nn-error NN_EACCESS 17)
(nn-error NN_ENETRESET 18)
(nn-error NN_ENETUNREACH 19)
(nn-error NN_EHOSTUNREACH 20)
(nn-error NN_ENOTCONN 21)
(nn-error NN_EMSGSIZE 22)
(nn-error NN_ETIMEDOUT 23)
(nn-error NN_ECONNABORTED 24)
(nn-error NN_ECONNRESET 25)
(nn-error NN_ENOPROTOOPT 26)
(nn-error NN_EISCONN 27)
(nn-error NN_ESOCKTNOSUPPORT 28)
(nn-error NN_ETERM 53)
(nn-error NN_EFSM 54)
(define NN_MSG -1)
(define-syntax nn-define
(syntax-rules ()
((_ name n)
(define-syntax name (identifier-syntax n)))))
(define-nn-func int nn-errno () "nn_errno")
(define-nn-func int nn-socket ((domain int) (protocol int))
"nn_socket")
(define-nn-func string nn-symbol ((index int) (value (* int)))
"nn_symbol")
;; THIS WAS/CAN BE USED TO GENERATE THE nn-define stuff in nanomsg/symbols.ss
;; TODO: can this be a macro that we call after loading the library?
;; but still. it will not be possible to export these because we cannot
;; dynamically add export entries?
(define (nn-gen-symbols)
(define ptr (make-ftype-pointer int (foreign-alloc (ftype-sizeof int))))
(let loop ([i 0])
(let ([sym (nn-symbol i ptr)])
(if sym
(begin
(printf "(nn-define ~d ~d)~n" sym (ftype-ref int () ptr))
(loop (+ 1 i))))))
(foreign-free (ftype-pointer-address ptr)))
(include "nanomsg/symbols.ss")
(define-nn-func int nn-close ((s int)) "nn_close")
(define-nn-func int nn-setsockopt ((s int) (level int) (option int)
(optval void*) (optval-len size_t))
"nn_setsockopt")
(define (nn-setsockopt/int s level option optval)
(define o #f)
(define r #f)
(dynamic-wind
(lambda ()
(set! o (make-ftype-pointer int (foreign-alloc (ftype-sizeof int)))))
(lambda ()
(ftype-set! int () o optval)
(set! r (nn-setsockopt s level option (ftype-pointer-address o)
(ftype-sizeof int))))
(lambda ()
(if o (foreign-free (ftype-pointer-address o)))))
r)
(define-nn-func int nn-getsockopt ((s int) (level int) (option int)
(optval void*) (optval-len (* size_t)))
"nn_getsockopt")
(define-nn-func int nn-bind ((s int) (addr string)) "nn_bind")
(define-nn-func int nn-connect ((s int) (addr string)) "nn_connect")
(define-nn-func int nn-shutdown ((s int) (how int)) "nn_shutdown")
(define-nn-func int nn-send% ((s int) (buf u8*) (len size_t) (flags int))
"nn_send")
(define (nn-send s buf flags)
(let* ([len (bytevector-length buf)]
[r (nn-send% s buf len flags)])
(if (not (= r len))
(errorf 'nn-send "bytes sent ~d/~d" r len)
r)))
(define-nn-func int nn-recv% ((s int) (buf void*) (len size_t) (flags int))
"nn_recv")
;; (define (char*->string fptr . bytes)
;; (let f ([i 0])
;; (let ([c (ftype-ref char () fptr i)])
;; (if (or (char=? c #\nul) (and bytes (>= (+ 1 i) (car bytes))))
;; (make-string i)
;; (let ([str (f (fx+ i 1))])
;; (string-set! str i c)
;; str)))))
(define nn-recv
(case-lambda
[(s flags)
(define b #f)
(define r #f)
(dynamic-wind
(lambda ()
(set! b (make-ftype-pointer void* (foreign-alloc (ftype-sizeof void*))))
(set! r (nn-recv% s (ftype-pointer-address b) NN_MSG flags)))
(lambda ()
(if (and r (> r 0))
(let ([c (make-ftype-pointer char (ftype-ref void* () b))])
(char*->bytevector c r))))
(lambda ()
(if (and r (> r 0))
(nn-freemsg (ftype-ref void* () b)))
(if b (foreign-free (ftype-pointer-address b)))))]
[(s buf len flags)
(define b #f)
(define r #f)
(dynamic-wind
(lambda ()
(set! b (make-ftype-pointer void* (foreign-alloc (ftype-sizeof void*))))
(set! r (nn-recv% s (ftype-pointer-address b) len flags)))
(lambda ()
(if (and r (> r 0))
(let ([c (make-ftype-pointer char (ftype-ref void* () b))])
(set-box! buf (char*->bytevector c r)))
(set-box! buf #f)))
(lambda ()
(if (and r (> r 0))
(nn-freemsg (ftype-ref void* () b)))
(if b (foreign-free (ftype-pointer-address b)))))
r]))
(define-nn-func int nn-sendmsg ((s int) (msghdr (* nn-msghdr)) (flags int))
"nn_sendmsg")
(define-nn-func int nn-freemsg ((msg void*)) "nn_freemsg")
(define-ftype nn-iovec
(struct
(iov_base void*)
(iov_len size_t)))
(define-ftype nn-msghdr
(struct
(msg_iov (* nn-iovec))
(msg_iovlen int)
(msg_control void*)
(msg_controllen size_t)))
(define-ftype nn-cmsghdr
(struct
(cmsg_len size_t)
(cmsg_level int)
(cmsg_type int)))
(define-nn-func int nn-recvmsg ((s int) (msghdr (* nn-cmsghdr)) (flags int))
"nn_recvmsg")
(define-ftype nn-pollfd
(struct (fd int) (events short) (revents short)))
(define-nn-func int nn-poll ((fds (* nn-pollfd)) (nfds int) (timeout int))
"nn_poll")
(define-nn-func int nn-device ((s1 int) (s2 int)) "nn_device")
(define-nn-func int nn-get-statistic ((s int) (stat int))
"nn_get_statistic")
(define-ftype nn_req_handle
(union
(i int)
(ptr void*)))
(define-flags nn_protocol
(pair NN_PAIR)
(pub NN_PUB) (sub NN_SUB)
(pull NN_PULL) (push NN_PUSH)
(req NN_REQ) (rep NN_REP)
(surveyor NN_SURVEYOR) (respondent NN_RESPONDENT)
(bus NN_BUS))
;; nanomsg domain (AF_SP)
(define-flags nn_domain
(sp AF_SP)
(raw AF_SP_RAW))
;; ==================== socket flags
(define-nn-func string nn-strerror ((errno int)) "nn_strerror")
;; let val pass unless it is negative, in which case gulp with the nn
;; error-string. on EAGAIN, return #f.
(define (nn-assert val)
(if (< val 0)
(if (= (nn-errno)
NN_EAGAIN
#f ;; signal EGAIN with #f, other errors will throw
(error (nn-strerror (nn-errno)) val))
val)))
);;library