Fix STREAM-ELEMENT-MODE for non-fd ANSI-STREAMs
[sbcl.git] / contrib / sb-bsd-sockets / local.lisp
blob9e09aee13194da46f42170539a693b4d2c8ad2a4
1 (in-package :sb-bsd-sockets)
3 (defclass local-socket (socket)
4 ((family :initform sockint::af-local))
5 (:documentation
6 "Class representing local domain (AF_LOCAL) sockets,
7 also known as unix-domain sockets."))
9 (defmethod socket-namestring ((socket local-socket))
10 (ignore-errors (socket-name socket)))
12 (defmethod socket-peerstring ((socket local-socket))
13 (ignore-errors (socket-peername socket)))
15 (defmethod make-sockaddr-for ((socket local-socket)
16 &optional sockaddr &rest address)
17 (let ((filename (first address))
18 (sockaddr (or sockaddr (sockint::allocate-sockaddr-un))))
19 (setf (sockint::sockaddr-un-family sockaddr) sockint::af-local)
20 (when filename
21 (setf (sockint::sockaddr-un-path sockaddr) filename))
22 sockaddr))
24 (defmethod free-sockaddr-for ((socket local-socket) sockaddr)
25 (sockint::free-sockaddr-un sockaddr))
27 (defmethod size-of-sockaddr ((socket local-socket))
28 sockint::size-of-sockaddr-un)
30 (defmethod bits-of-sockaddr ((socket local-socket) sockaddr)
31 "Return the file name of the local socket address SOCKADDR."
32 (let ((name (sockint::sockaddr-un-path sockaddr)))
33 (unless (zerop (length name)) name)))
35 (defclass local-abstract-socket (local-socket) ()
36 (:documentation
37 "Class representing local domain (AF_LOCAL) sockets with addresses
38 in the abstract namespace."))
40 (defmethod make-sockaddr-for ((socket local-abstract-socket)
41 &optional sockaddr &rest address)
42 (check-type address (or null (cons (or string pathname) null)))
43 (let ((path (first address))
44 (sockaddr (or sockaddr (sockint::allocate-sockaddr-un-abstract)))
45 (len 0))
46 (setf (sockint::sockaddr-un-abstract-family sockaddr) sockint::af-local)
47 ;; First byte of the path is always 0.
48 (setf (sb-alien:deref (sockint::sockaddr-un-abstract-path sockaddr) 0) 0)
50 (when path
51 (when (stringp path)
52 (setf path (sb-ext:string-to-octets path)))
53 (setf len (min (- sockint::size-of-sockaddr-un-abstract 3) (length path)))
54 ;; We fill in the rest of the path starting at index 1.
55 (loop for i from 0 below len
56 do (setf (sb-alien:deref (sockint::sockaddr-un-abstract-path
57 sockaddr)
58 (1+ i))
59 (elt path i))))
61 (values sockaddr (+ 3 len))))
63 (defmethod free-sockaddr-for ((socket local-abstract-socket) sockaddr)
64 (sockint::free-sockaddr-un-abstract sockaddr))
66 (defmethod size-of-sockaddr ((socket local-abstract-socket))
67 sockint::size-of-sockaddr-un-abstract)
69 (defmethod bits-of-sockaddr ((socket local-abstract-socket) sockaddr)
70 "Return the contents of the local socket address SOCKADDR."
71 (let* ((path-len (- sockint::size-of-sockaddr-un-abstract 3))
72 (path (make-array `(,path-len)
73 :element-type '(unsigned-byte 8)
74 :initial-element 0)))
75 ;; Exclude the first byte (it's always null) of the address.
76 (loop for i from 1 to path-len
77 do (setf (elt path (1- i))
78 (sb-alien:deref (sockint::sockaddr-un-abstract-path sockaddr)
79 i)))
80 path))