1 (in-package :sb-bsd-sockets)
3 (defclass local-socket (socket)
4 ((family :initform sockint::af-local))
5 (:documentation "Class representing local domain (AF_LOCAL) sockets,
6 also known as unix-domain sockets."))
8 (defmethod socket-namestring ((socket local-socket))
9 (ignore-errors (socket-name socket)))
11 (defmethod socket-peerstring ((socket local-socket))
12 (ignore-errors (socket-peername socket)))
14 (defmethod make-sockaddr-for ((socket local-socket)
15 &optional sockaddr &rest address &aux (filename (first address)))
16 (let ((sockaddr (or sockaddr (sockint::allocate-sockaddr-un))))
17 (setf (sockint::sockaddr-un-family sockaddr) sockint::af-local)
19 (setf (sockint::sockaddr-un-path sockaddr) filename))
22 (defmethod free-sockaddr-for ((socket local-socket) sockaddr)
23 (sockint::free-sockaddr-un sockaddr))
25 (defmethod size-of-sockaddr ((socket local-socket))
26 sockint::size-of-sockaddr-un)
28 (defmethod bits-of-sockaddr ((socket local-socket) sockaddr)
29 "Return the file name of the local socket address SOCKADDR."
30 (let ((name (sockint::sockaddr-un-path sockaddr)))
31 (if (zerop (length name)) nil name)))
33 (defclass local-abstract-socket (local-socket) ()
34 (:documentation "Class representing local domain (AF_LOCAL) sockets with
35 addresses in the abstract namespace."))
37 (defmethod make-sockaddr-for ((socket local-abstract-socket)
38 &optional sockaddr &rest address
39 &aux (path (first address)))
40 (let ((sockaddr (or sockaddr (sockint::allocate-sockaddr-un-abstract)))
42 (setf (sockint::sockaddr-un-abstract-family sockaddr) sockint::af-local)
43 ;;First byte of the path is always 0.
44 (setf (sb-alien:deref (sockint::sockaddr-un-abstract-path sockaddr) 0) 0)
48 (setf path (sb-ext:string-to-octets path)))
49 (setf len (min (- sockint::size-of-sockaddr-un-abstract 3) (length path)))
50 ;;We fill in the rest of the path starting at index 1.
51 (loop for i from 0 below len
52 do (setf (sb-alien:deref (sockint::sockaddr-un-abstract-path
56 (values sockaddr (+ 3 len))))
58 (defmethod free-sockaddr-for ((socket local-abstract-socket) sockaddr)
59 (sockint::free-sockaddr-un-abstract sockaddr))
61 (defmethod size-of-sockaddr ((socket local-abstract-socket))
62 sockint::size-of-sockaddr-un-abstract)
64 (defmethod bits-of-sockaddr ((socket local-abstract-socket) sockaddr)
65 "Return the contents of the local socket address SOCKADDR."
66 (let* ((path-len (- sockint::size-of-sockaddr-un-abstract 3))
67 (path (make-array `(,path-len)
68 :element-type '(unsigned-byte 8)
70 ;;exclude the first byte (it's always null) of the address
71 (loop for i from 1 to path-len
72 do (setf (elt path (1- i))
73 (sb-alien:deref (sockint::sockaddr-un-abstract-path sockaddr)
77 (defmethod socket-connect ((socket local-abstract-socket) &rest peer
78 &aux (path (first peer)))
79 (multiple-value-bind (sockaddr addr-len)
80 (make-sockaddr-for socket nil path)
82 (if (= (sockint::connect (socket-file-descriptor socket)
86 (socket-error "connect"))
87 (free-sockaddr-for socket sockaddr))))
89 (defmethod socket-bind ((socket local-abstract-socket)
90 &rest address &aux (path (first address)))
91 (multiple-value-bind (sockaddr addr-len)
92 (make-sockaddr-for socket nil path)
94 (if (= (sockint::bind (socket-file-descriptor socket)
98 (socket-error "bind"))
99 (free-sockaddr-for socket sockaddr))))