1 (defpackage "SB-BSD-SOCKETS-INTERNAL"
4 #+cmu
(:shadowing-import-from
"CL" with-array-data
)
5 #+sbcl
(:shadowing-import-from
"SB-KERNEL" with-array-data
)
7 #+cmu
(:use
"COMMON-LISP" "ALIEN" "SYSTEM" "EXT" "C-CALL")
8 #+sbcl
(:use
"COMMON-LISP" "SB-ALIEN" #+nil
"SB-SYSTEM" "SB-EXT" "SB-C-CALL"))
10 ;;; SBCL changes a lot of package prefixes. To avoid littering the
11 ;;; code with conditionals, we use the SBCL package prefixes
12 ;;; throughout. This means that we need to create said packages
13 ;;; first, if we're using CMUCL
15 ;;; One thing that this exercise really has made clear is just how much
16 ;;; of the alien stuff is scattered around the cmucl package space
17 ;;; seemingly at random. Hmm.
20 (eval-when (:compile-toplevel
:load-toplevel
)
21 (defun add-package-nickname (name nickname
)
22 (let ((p (find-package name
)))
23 (rename-package p
(package-name p
)
24 (cons nickname
(package-nicknames name
)))))
25 (add-package-nickname "EXT" "SB-EXT")
26 (add-package-nickname "ALIEN" "SB-ALIEN")
27 (add-package-nickname "UNIX" "SB-UNIX")
28 (add-package-nickname "C-CALL" "SB-C-CALL")
29 (add-package-nickname "KERNEL" "SB-KERNEL")
30 (add-package-nickname "SYSTEM" "SB-SYS"))
32 (defpackage "SB-BSD-SOCKETS"
33 (:export socket unix-socket inet-socket
34 make-unix-socket make-inet-socket
35 socket-bind socket-accept socket-connect
36 socket-send socket-receive socket-recv
37 socket-name socket-peername socket-listen
38 socket-close socket-file-descriptor socket-make-stream
41 get-host-by-name get-host-by-address
43 host-ent-addresses host-ent-address
44 host-ent aliases host-ent-name
46 ;; not sure if these are really good names or not
53 ;; all socket options are also exported, by code in
56 bad-file-descriptor-error
59 invalid-argument-error
61 operation-not-supported-error
62 operation-not-permitted-error
63 protocol-not-supported-error
64 socket-type-not-supported-error
65 network-unreachable-error
71 (:use
"COMMON-LISP" "SB-BSD-SOCKETS-INTERNAL")
75 A thinly-disguised BSD socket API for SBCL. Ideas stolen from the BSD
76 socket API for C and Graham Barr's IO::Socket classes for Perl.
78 We represent sockets as CLOS objects, and rename a lot of methods and
79 arguments to fit Lisp style more closely.
90 <li
> Methods applicable to all
<a href
="#socket">sockets
</a
>
91 <li
> <a href
="#sockopt">Socket Options
</a
>
92 <li
> Methods applicable to a particular subclass
94 <li
> <a href
="#internet">INET-SOCKET
</a
> - Internet Protocol
(TCP, UDP
, raw
) sockets
95 <li
> Methods on
<a href
="#UNIX-SOCKET">UNIX-SOCKET
</a
> - Unix-domain sockets
97 <li
> <a href
="#name-service">Name resolution
</a
> (DNS, /etc
/hosts
, &
;c)
100 <h2
>General concepts
</h2
>
102 <p
>Most of the functions are modelled on the BSD socket API. BSD sockets
103 are widely supported
, portably
<i
>("portable" by Unix standards
, at least
)</i
>
104 available on a variety of systems
, and documented. There are some
105 differences in approach where we have taken advantage of some of the more useful features of Common Lisp - briefly
108 <li
> Where the C API would typically return -
1 and set errno
, bsd-sockets
109 signals an error. All the errors are subclasses of SOCKET-CONDITION
110 and generally correspond one for one with possible
<tt
>errno
</tt
> values
112 <li
> We use multiple return values in many places where the C API would use p
[ass-by-reference values
114 <li
> We can often avoid supplying an explicit
<i
>length
</i
> argument to
115 functions because we already know how long the argument is.
117 <li
> IP addresses and ports are represented in slightly friendlier fashion
118 than
"network-endian integers". See the section on
<a href
="#internet"
119 >Internet domain
</a
> sockets for details.