[10d2c0]: contrib / sb-bsd-sockets / defpackage.lisp Maximize Restore History

Download this file

defpackage.lisp    124 lines (99 with data), 4.4 kB

  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
(defpackage "SB-BSD-SOCKETS-INTERNAL"
(:nicknames "SOCKINT")
(:shadow close listen)
#+cmu (:shadowing-import-from "CL" with-array-data)
#+sbcl (:shadowing-import-from "SB-KERNEL" with-array-data)
#+cmu (:use "COMMON-LISP" "ALIEN" "SYSTEM" "EXT" "C-CALL")
#+sbcl (:use "COMMON-LISP" "SB-ALIEN" #+nil "SB-SYSTEM" "SB-EXT" "SB-C-CALL"))
;;; SBCL changes a lot of package prefixes. To avoid littering the
;;; code with conditionals, we use the SBCL package prefixes
;;; throughout. This means that we need to create said packages
;;; first, if we're using CMUCL
;;; One thing that this exercise really has made clear is just how much
;;; of the alien stuff is scattered around the cmucl package space
;;; seemingly at random. Hmm.
#+cmu
(eval-when (:compile-toplevel :load-toplevel)
(defun add-package-nickname (name nickname)
(let ((p (find-package name)))
(rename-package p (package-name p)
(cons nickname (package-nicknames name)))))
(add-package-nickname "EXT" "SB-EXT")
(add-package-nickname "ALIEN" "SB-ALIEN")
(add-package-nickname "UNIX" "SB-UNIX")
(add-package-nickname "C-CALL" "SB-C-CALL")
(add-package-nickname "KERNEL" "SB-KERNEL")
(add-package-nickname "SYSTEM" "SB-SYS"))
(defpackage "SB-BSD-SOCKETS"
(:export socket unix-socket inet-socket
make-unix-socket make-inet-socket
socket-bind socket-accept socket-connect
socket-send socket-receive socket-recv
socket-name socket-peername socket-listen
socket-close socket-file-descriptor socket-make-stream
get-protocol-by-name
get-host-by-name get-host-by-address
host-ent
host-ent-addresses host-ent-address
host-ent aliases host-ent-name
name-service-error
;; not sure if these are really good names or not
netdb-internal-error
netdb-success-error
host-not-found-error
try-again-error
no-recovery-error
;; all socket options are also exported, by code in
;; sockopt.lisp
bad-file-descriptor-error
address-in-use-error
interrupted-error
invalid-argument-error
out-of-memory-error
operation-not-supported-error
operation-not-permitted-error
protocol-not-supported-error
socket-type-not-supported-error
network-unreachable-error
make-inet-address
non-blocking-mode
)
(:use "COMMON-LISP" "SB-BSD-SOCKETS-INTERNAL")
(:documentation
"
A thinly-disguised BSD socket API for SBCL. Ideas stolen from the BSD
socket API for C and Graham Barr's IO::Socket classes for Perl.
We represent sockets as CLOS objects, and rename a lot of methods and
arguments to fit Lisp style more closely.
"
))
#||
<h2>Contents</h2>
<ol>
<li> General concepts
<li> Methods applicable to all <a href="#socket">sockets</a>
<li> <a href="#sockopt">Socket Options</a>
<li> Methods applicable to a particular subclass
<ol>
<li> <a href="#internet">INET-SOCKET</a> - Internet Protocol (TCP, UDP, raw) sockets
<li> Methods on <a href="#UNIX-SOCKET">UNIX-SOCKET</a> - Unix-domain sockets
</ol>
<li> <a href="#name-service">Name resolution</a> (DNS, /etc/hosts, &amp;c)
</ol>
<h2>General concepts</h2>
<p>Most of the functions are modelled on the BSD socket API. BSD sockets
are widely supported, portably <i>("portable" by Unix standards, at least)</i>
available on a variety of systems, and documented. There are some
differences in approach where we have taken advantage of some of the more useful features of Common Lisp - briefly
<ul>
<li> Where the C API would typically return -1 and set errno, bsd-sockets
signals an error. All the errors are subclasses of SOCKET-CONDITION
and generally correspond one for one with possible <tt>errno</tt> values
<li> We use multiple return values in many places where the C API would use p[ass-by-reference values
<li> We can often avoid supplying an explicit <i>length</i> argument to
functions because we already know how long the argument is.
<li> IP addresses and ports are represented in slightly friendlier fashion
than "network-endian integers". See the section on <a href="#internet"
>Internet domain</a> sockets for details.
</ul>
|#