1 ;;;; -*- Mode: lisp; indent-tabs-mode: nil -*-
3 ;;; bsd.lisp --- Bindings for BSD sockets (and Winsock).
5 ;;; Copyright (C) 2005-2006, Matthew Backes <lucca@accela.net>
6 ;;; Copyright (C) 2005-2006, Dan Knapp <dankna@accela.net> and
7 ;;; Copyright (C) 2007, Stelian Ionescu <stelian.ionescu-zeus@poste.it>
8 ;;; Copyright (C) 2007, Luis Oliveira <loliveira@common-lisp.net>
10 ;;; Permission is hereby granted, free of charge, to any person
11 ;;; obtaining a copy of this software and associated documentation
12 ;;; files (the "Software"), to deal in the Software without
13 ;;; restriction, including without limitation the rights to use, copy,
14 ;;; modify, merge, publish, distribute, sublicense, and/or sell copies
15 ;;; of the Software, and to permit persons to whom the Software is
16 ;;; furnished to do so, subject to the following conditions:
18 ;;; The above copyright notice and this permission notice shall be
19 ;;; included in all copies or substantial portions of the Software.
21 ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 ;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 ;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 ;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 ;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 ;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 ;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 ;;; DEALINGS IN THE SOFTWARE.
30 (in-package :net.sockets
)
32 ;;; Simple wrapper around DEFCFUN that uses the stdcall calling
33 ;;; convention on windows.
34 (defmacro deforeign
(name-and-opts return-type
&body args
)
35 (multiple-value-bind (lisp-name c-name options
)
36 (cffi::parse-name-and-options name-and-opts
)
38 (appendf options
'(:calling-convention
:stdcall
))
39 `(defcfun (,c-name
,lisp-name
,@options
) ,return-type
42 (defmacro define-socket-call
(name return-type
&body args
)
43 `(deforeign ,name
(errno-wrapper ,return-type
44 :error-generator signal-socket-error
)
52 (define-foreign-type fd-type
()
57 (defmethod translate-to-foreign (fd (type fd-type
))
62 (define-socket-call "accept" :int
63 "Accept an incoming connection, returning the file descriptor."
65 (address :pointer
) ; sockaddr-foo
68 (define-socket-call "bind" :int
69 "Bind a socket to a particular local address."
74 (define-socket-call ("connect" %connect
) :int
75 "Create an outgoing connection on a given socket."
77 (address :pointer
) ; sockaddr-foo
80 (define-socket-call "getpeername" :int
85 (define-socket-call "getsockname" :int
90 (define-socket-call "getsockopt" :int
91 "Retrieve socket configuration."
98 (define-socket-call "listen" :int
99 "Mark a bound socket as listening for incoming connections."
103 (define-socket-call "recv" ssize
109 (define-socket-call "recvfrom" ssize
118 (define-socket-call "recvmsg" ssize
123 (define-socket-call "send" ssize
130 (define-socket-call "sendmsg" ssize
135 (define-socket-call "sendto" ssize
143 (define-socket-call "setsockopt" :int
144 "Configure a socket."
151 (define-socket-call ("shutdown" %shutdown
) :int
155 ;;; SOCKET is emulated in winsock.lisp.
157 (define-socket-call "socket" :int
158 "Create a BSD socket."
164 (define-socket-call "sockatmark" :int
168 (define-socket-call ("socketpair" %socketpair
) :int
175 (defun socketpair (domain type protocol
)
176 (with-foreign-object (filedes :int
2)
177 (%socketpair domain type protocol filedes
)
178 (values (mem-aref filedes
:int
0)
179 (mem-aref filedes
:int
1))))
184 (defconstant unix-path-max
185 (- size-of-sockaddr-un
(foreign-slot-offset 'sockaddr-un
'path
)))
189 ;;; TODO: more socket stuff, deal with this later
191 (define-socket-call "freeaddrinfo" :void
194 (defcfun "getaddrinfo"
196 :error-predicate
(lambda (x) (not (zerop x
)))
197 :error-generator signal-resolver-error
)
203 ;;; For systems with missing or broken getaddrinfo().
204 (defcfun "gethostbyaddr" hostent
210 (defcfun "getservbyport" servent
214 ;;; Winsock's getnameinfo() return values are compatible with POSIX
215 ;;; even though they have WSA_* counterparts.
217 ;;; <http://msdn2.microsoft.com/en-us/library/ms738532.aspx>
218 (defcfun "getnameinfo"
220 :error-predicate
(lambda (x) (not (zerop x
)))
221 :error-generator signal-resolver-error
)
230 (define-socket-call "getprotobyname" :pointer
233 (define-socket-call "getprotobynumber" :pointer
239 (define-socket-call "inet_ntop" :string
247 (errno-wrapper :int
:error-predicate
(lambda (x) (not (plusp x
))))
254 ;;; On windows, these functions are only available on Vista or later.
257 (defcfun "if_nametoindex"
258 (errno-wrapper :unsigned-int
:error-predicate zerop
)
261 (define-socket-call "if_indextoname" :string
262 (ifindex :unsigned-int
)
265 (define-socket-call "if_nameindex" :pointer
266 "Return all network interface names and indexes")
268 (define-socket-call "if_freenameindex" :void