diff --git a/cffi-socket.asd b/cffi-socket.asd
new file mode 100644
index 0000000..a1dc58a
--- /dev/null
+++ b/cffi-socket.asd
@@ -0,0 +1,15 @@
+
+(in-package :common-lisp-user)
+
+(defpackage :cffi-socket.system
+ (:use :common-lisp :asdf))
+
+(in-package :cffi-socket.system)
+
+(defsystem "cffi-socket"
+ :defsystem-depends-on ("cffi-grovel")
+ :depends-on ("cffi" "cffi-errno" "cffi-unistd")
+ :components
+ ((:file "package")
+ (:cffi-grovel-file "grovel-socket" :depends-on ("package"))
+ (:file "cffi-socket" :depends-on ("grovel-socket"))))
diff --git a/cffi-socket.lisp b/cffi-socket.lisp
new file mode 100644
index 0000000..1ee43aa
--- /dev/null
+++ b/cffi-socket.lisp
@@ -0,0 +1,179 @@
+
+(in-package :cffi-socket)
+
+;; Sockets
+
+(deftype file-descriptor ()
+ `(unsigned-byte (1- (* 8 (foreign-type-size :int)))))
+
+(defcfun ("socket" c-socket) :int
+ (domain :int)
+ (type :int)
+ (protocol :int))
+
+(defun socket (domain type protocol)
+ (let ((s (c-socket domain type protocol)))
+ (when (< s 0)
+ (error-errno "socket"))
+ s))
+
+(defmacro with-socket ((var domain type protocol) &body body)
+ `(let ((,var (socket ,domain ,type ,protocol)))
+ (unwind-protect (progn ,@body)
+ (unistd:close ,var))))
+
+(defcstruct sockaddr
+ (sa-family sa-family-t)
+ (sa-data :char :count 14))
+
+(defcfun ("bind" c-bind) :int
+ (sockfd :int)
+ (addr (:pointer (:struct sockaddr)))
+ (addrlen :int))
+
+(defcfun "htons" uint16-t
+ (hostshort uint16-t))
+
+;; IP
+
+(defcstruct sockaddr-in
+ (sin-family sa-family-t)
+ (sin-port in-port-t)
+ (sin-addr uint32-t)
+ (sin-zero :unsigned-char :count #.(- (foreign-type-size '(:struct sockaddr))
+ (foreign-type-size 'sa-family-t)
+ (foreign-type-size 'in-port-t)
+ (foreign-type-size 'uint32-t))))
+
+(defun inet-addr-from-string (x &key (start 0) (end (length x)))
+ (ignore-errors
+ (let ((addr 0))
+ (flet ((eat-byte ()
+ (let ((b 0))
+ (loop while (< start end)
+ for c = (char x start)
+ while (char<= #\0 c #\9)
+ do (setf b (+ (* 10 b) (- (char-code c) (char-code #\0))))
+ do (incf start))
+ (setf addr (logior (ash addr 8) b)))))
+ (dotimes (_ 3)
+ (eat-byte)
+ (assert (char= #\. (char x start)))
+ (incf start))
+ (eat-byte)
+ (assert (= end start)))
+ addr)))
+
+(defun inet-addr (x)
+ (etypecase x
+ ((unsigned-byte 32) x)
+ (string (or (inet-addr-from-string x)))))
+
+
+(defun bind-inet (sockfd addr port)
+ (with-foreign-object (addr-in '(:struct sockaddr))
+ (with-foreign-slots ((sin-family sin-port sin-addr)
+ addr-in (:struct sockaddr-in))
+ (let ((inet-addr (inet-addr addr)))
+ (setf sin-family +af-inet+
+ sin-port (htons port)
+ sin-addr inet-addr)))
+ (let ((r (c-bind sockfd addr-in (foreign-type-size
+ '(:struct sockaddr-in)))))
+ (when (< r 0)
+ (error-errno "bind"))
+ r)))
+
+(defcfun ("listen" c-listen) :int
+ (sockfd :int)
+ (backlog :int))
+
+(defun listen (sockfd backlog)
+ (let ((r (c-listen sockfd backlog)))
+ (when (< r 0)
+ (error-errno "listen"))
+ r))
+
+(defcfun ("accept" c-accept) :int
+ (sockfd :int)
+ (addr :pointer)
+ (addrlen (:pointer :int)))
+
+(defun accept (sockfd)
+ (with-foreign-object (addr '(:struct sockaddr-in))
+ (with-foreign-object (addrlen :int)
+ (setf (mem-ref addrlen :int) (foreign-type-size '(:struct sockaddr-in)))
+ (let ((s (c-accept sockfd addr addrlen)))
+ (cond ((<= 0 s)
+ (values s addr))
+ ((or (= errno +eagain+)
+ (= errno +ewouldblock+))
+ nil)
+ (t
+ (error-errno "accept")))))))
+
+(defmacro with-accept ((fd-var &optional (addr-var (gensym))) listening-fd
+ &body body)
+ (declare (type symbol fd-var addr-var))
+ `(multiple-value-bind (,fd-var ,addr-var) (accept ,listening-fd)
+ (when ,fd-var
+ (unwind-protect (progn ,@body)
+ (unistd:close ,fd-var)))))
+
+(defcfun ("recv" c-recv) ssize-t
+ (sockfd :int)
+ (buf :pointer)
+ (len size-t)
+ (flags :int))
+
+(defun recv (sockfd buffer flags &key (start 0) (end (length buffer)))
+ (declare (type (array (unsigned-byte 8)) buffer))
+ (let ((len (- end start)))
+ (with-foreign-pointer (buf len)
+ (let ((r (c-recv sockfd buf len flags)))
+ (dotimes (i len)
+ (setf (aref buffer start) (mem-aref buf :unsigned-char i))
+ (incf start))
+ (when (< r 0)
+ (error-errno "recv"))
+ r))))
+
+(defun recv-sequence (sockfd buffer flags &key (start 0) (end (length buffer)))
+ (loop while (< start end)
+ for r = (recv sockfd buffer flags :start start :end end)
+ do (when (= r 0) (error "end of file"))
+ do (incf start r)))
+
+(defcfun ("send" c-send) ssize-t
+ (sockfd :int)
+ (buf :pointer)
+ (len size-t)
+ (flags :int))
+
+(defun send (sockfd buffer flags &key (start 0) (end (length buffer)))
+ (declare (type (array (unsigned-byte 8)) buffer))
+ (let ((len (- end start)))
+ (with-foreign-pointer (buf len)
+ (dotimes (i len)
+ (setf (mem-aref buf :unsigned-char i) (aref buffer start))
+ (incf start))
+ (let ((r (c-send sockfd buf len flags)))
+ (when (< r 0)
+ (error-errno "send"))
+ r))))
+
+(defun send-sequence (sockfd buffer flags &key (start 0) (end (length buffer)))
+ (loop while (< start end)
+ for r = (send sockfd buffer flags :start start :end end)
+ do (when (= r 0) (error "end of file"))
+ do (incf start r)))
+
+(defcfun ("shutdown" c-shutdown) :int
+ (sockfd :int)
+ (how :int))
+
+(defun shutdown (sockfd &optional read write)
+ (when (or read write)
+ (c-shutdown sockfd (cond ((and read write) +shut-rdwr+)
+ (read +shut-rd+)
+ (write +shut-wr+)))))
diff --git a/cffi-sockets.asd b/cffi-sockets.asd
deleted file mode 100644
index 770b7d5..0000000
--- a/cffi-sockets.asd
+++ /dev/null
@@ -1,15 +0,0 @@
-
-(in-package :common-lisp-user)
-
-(defpackage :cffi-sockets.system
- (:use :common-lisp :asdf))
-
-(in-package :cffi-sockets.system)
-
-(defsystem "cffi-sockets"
- :defsystem-depends-on ("cffi-grovel")
- :depends-on ("cffi" "cffi-errno" "cffi-unistd")
- :components
- ((:file "package")
- (:cffi-grovel-file "grovel-sockets" :depends-on ("package"))
- (:file "cffi-sockets" :depends-on ("grovel-sockets"))))
diff --git a/cffi-sockets.lisp b/cffi-sockets.lisp
deleted file mode 100644
index 31dbd21..0000000
--- a/cffi-sockets.lisp
+++ /dev/null
@@ -1,172 +0,0 @@
-
-(in-package :cffi-sockets)
-
-;; Sockets
-
-(deftype file-descriptor ()
- `(unsigned-byte (1- (* 8 (foreign-type-size :int)))))
-
-(defcfun ("socket" c-socket) :int
- (domain :int)
- (type :int)
- (protocol :int))
-
-(defun socket (domain type protocol)
- (let ((s (c-socket domain type protocol)))
- (when (< s 0)
- (error-errno "socket"))
- s))
-
-(defmacro with-socket ((var domain type protocol) &body body)
- `(let ((,var (socket ,domain ,type ,protocol)))
- (unwind-protect (progn ,@body)
- (unistd:close ,var))))
-
-(defcstruct sockaddr
- (sa-family sa-family-t)
- (sa-data :char :count 14))
-
-(defcfun ("bind" c-bind) :int
- (sockfd :int)
- (addr (:pointer (:struct sockaddr)))
- (addrlen :int))
-
-(defcfun "htons" uint16-t
- (hostshort uint16-t))
-
-;; IP
-
-(defcstruct sockaddr-in
- (sin-family sa-family-t)
- (sin-port in-port-t)
- (sin-addr uint32-t)
- (sin-zero :unsigned-char :count #.(- (foreign-type-size '(:struct sockaddr))
- (foreign-type-size 'sa-family-t)
- (foreign-type-size 'in-port-t)
- (foreign-type-size 'uint32-t))))
-
-(defun inet-addr-from-string (x &key (start 0) (end (length x)))
- (ignore-errors
- (let ((addr 0))
- (flet ((eat-byte ()
- (let ((b 0))
- (loop while (< start end)
- for c = (char x start)
- while (char<= #\0 c #\9)
- do (setf b (+ (* 10 b) (- (char-code c) (char-code #\0))))
- do (incf start))
- (setf addr (logior (ash addr 8) b)))))
- (dotimes (_ 3)
- (eat-byte)
- (assert (char= #\. (char x start)))
- (incf start))
- (eat-byte)
- (assert (= end start)))
- addr)))
-
-(defun inet-addr (x)
- (etypecase x
- ((unsigned-byte 32) x)
- (string (or (inet-addr-from-string x)))))
-
-
-(defun bind-inet (sockfd addr port)
- (with-foreign-object (addr-in '(:struct sockaddr))
- (with-foreign-slots ((sin-family sin-port sin-addr)
- addr-in (:struct sockaddr-in))
- (let ((inet-addr (inet-addr addr)))
- (setf sin-family +af-inet+
- sin-port (htons port)
- sin-addr inet-addr)))
- (let ((r (c-bind sockfd addr-in (foreign-type-size
- '(:struct sockaddr-in)))))
- (when (< r 0)
- (error-errno "bind"))
- r)))
-
-(defcfun ("listen" c-listen) :int
- (sockfd :int)
- (backlog :int))
-
-(defun listen-sock (sockfd backlog)
- (let ((r (c-listen sockfd backlog)))
- (when (< r 0)
- (error-errno "listen"))
- r))
-
-(defcfun ("accept" c-accept) :int
- (sockfd :int)
- (addr :pointer)
- (addrlen (:pointer :int)))
-
-(defun accept (sockfd)
- (with-foreign-object (addr '(:struct sockaddr-in))
- (with-foreign-object (addrlen :int)
- (setf (mem-ref addrlen :int) (foreign-type-size '(:struct sockaddr-in)))
- (let ((s (c-accept sockfd addr addrlen)))
- (when (< s 0)
- (error-errno "accept"))
- (values s addr)))))
-
-(defmacro with-accept ((var listening-fd) &body body)
- `(let ((,var (accept ,listening-fd)))
- (unwind-protect (progn ,@body)
- (unistd:close ,var))))
-
-(defcfun ("recv" c-recv) ssize-t
- (sockfd :int)
- (buf :pointer)
- (len size-t)
- (flags :int))
-
-(defun recv (sockfd buffer flags &key (start 0) (end (length buffer)))
- (declare (type (array (unsigned-byte 8)) buffer))
- (let ((len (- end start)))
- (with-foreign-pointer (buf len)
- (let ((r (c-recv sockfd buf len flags)))
- (dotimes (i len)
- (setf (aref buffer start) (mem-aref buf :unsigned-char i))
- (incf start))
- (when (< r 0)
- (error-errno "recv"))
- r))))
-
-(defun recv-sequence (sockfd buffer flags &key (start 0) (end (length buffer)))
- (loop while (< start end)
- for r = (recv sockfd buffer flags :start start :end end)
- do (when (= r 0) (error "end of file"))
- do (incf start r)))
-
-(defcfun ("send" c-send) ssize-t
- (sockfd :int)
- (buf :pointer)
- (len size-t)
- (flags :int))
-
-(defun send (sockfd buffer flags &key (start 0) (end (length buffer)))
- (declare (type (array (unsigned-byte 8)) buffer))
- (let ((len (- end start)))
- (with-foreign-pointer (buf len)
- (dotimes (i len)
- (setf (mem-aref buf :unsigned-char i) (aref buffer start))
- (incf start))
- (let ((r (c-send sockfd buf len flags)))
- (when (< r 0)
- (error-errno "send"))
- r))))
-
-(defun send-sequence (sockfd buffer flags &key (start 0) (end (length buffer)))
- (loop while (< start end)
- for r = (send sockfd buffer flags :start start :end end)
- do (when (= r 0) (error "end of file"))
- do (incf start r)))
-
-(defcfun ("shutdown" c-shutdown) :int
- (sockfd :int)
- (how :int))
-
-(defun shutdown (sockfd &optional read write)
- (when (or read write)
- (c-shutdown sockfd (cond ((and read write) +shut-rdwr+)
- (read +shut-rd+)
- (write +shut-wr+)))))
diff --git a/grovel-socket.lisp b/grovel-socket.lisp
new file mode 100644
index 0000000..e96f1fb
--- /dev/null
+++ b/grovel-socket.lisp
@@ -0,0 +1,45 @@
+
+(in-package :cffi-socket)
+
+;; Sockets
+
+(include "sys/types.h")
+(include "sys/socket.h")
+
+(constant (+af-unix+ "AF_UNIX"))
+(constant (+af-local+ "AF_LOCAL"))
+(constant (+af-inet+ "AF_INET"))
+(constant (+af-inet6+ "AF_INET6"))
+(constant (+af-ipx+ "AF_IPX"))
+(constant (+af-packet+ "AF_PACKET"))
+
+(constant (+sock-stream+ "SOCK_STREAM"))
+(constant (+sock-dgram+ "SOCK_DGRAM"))
+(constant (+sock-raw+ "SOCK_RAW"))
+
+(constant (+sock-nonblock+ "SOCK_NONBLOCK"))
+(constant (+sock-cloexec+ "SOCK_CLOEXEC"))
+
+(constant (+shut-rd+ "SHUT_RD"))
+(constant (+shut-wr+ "SHUT_WR"))
+(constant (+shut-rdwr+ "SHUT_RDWR"))
+
+(ctype socklen-t "socklen_t")
+(ctype size-t "size_t")
+(ctype ssize-t "ssize_t")
+
+;; INET
+
+(include "arpa/inet.h")
+
+(ctype uint16-t "uint16_t")
+(ctype uint32-t "uint32_t")
+
+;; IP
+
+(include "netinet/in.h")
+
+(constant (+inaddr-any+ "INADDR_ANY"))
+
+(ctype sa-family-t "sa_family_t")
+(ctype in-port-t "in_port_t")
diff --git a/grovel-sockets.lisp b/grovel-sockets.lisp
deleted file mode 100644
index 0bba75b..0000000
--- a/grovel-sockets.lisp
+++ /dev/null
@@ -1,45 +0,0 @@
-
-(in-package :cffi-sockets)
-
-;; Sockets
-
-(include "sys/types.h")
-(include "sys/socket.h")
-
-(constant (+af-unix+ "AF_UNIX"))
-(constant (+af-local+ "AF_LOCAL"))
-(constant (+af-inet+ "AF_INET"))
-(constant (+af-inet6+ "AF_INET6"))
-(constant (+af-ipx+ "AF_IPX"))
-(constant (+af-packet+ "AF_PACKET"))
-
-(constant (+sock-stream+ "SOCK_STREAM"))
-(constant (+sock-dgram+ "SOCK_DGRAM"))
-(constant (+sock-raw+ "SOCK_RAW"))
-
-(constant (+sock-nonblock+ "SOCK_NONBLOCK"))
-(constant (+sock-cloexec+ "SOCK_CLOEXEC"))
-
-(constant (+shut-rd+ "SHUT_RD"))
-(constant (+shut-wr+ "SHUT_WR"))
-(constant (+shut-rdwr+ "SHUT_RDWR"))
-
-(ctype socklen-t "socklen_t")
-(ctype size-t "size_t")
-(ctype ssize-t "ssize_t")
-
-;; INET
-
-(include "arpa/inet.h")
-
-(ctype uint16-t "uint16_t")
-(ctype uint32-t "uint32_t")
-
-;; IP
-
-(include "netinet/in.h")
-
-(constant (+inaddr-any+ "INADDR_ANY"))
-
-(ctype sa-family-t "sa_family_t")
-(ctype in-port-t "in_port_t")
diff --git a/package.lisp b/package.lisp
index 24b0b47..f15797d 100644
--- a/package.lisp
+++ b/package.lisp
@@ -1,11 +1,13 @@
(in-package :common-lisp)
-(defpackage :cffi-sockets
+(defpackage :cffi-socket
(:use
:cffi
:common-lisp
:errno)
+ (:shadow
+ #:listen)
(:export
#:+af-unix+
#:+af-local+
@@ -25,7 +27,7 @@
#:socket
#:with-socket
#:bind-inet
- #:listen-sock
+ #:listen
#:accept
#:with-accept
#:recv