Sorry. That was a bit more than Douglas submitted, I'll revert the non-related part when I get back from work.
bye,
Erik.
On 10/18/06, ehuelsmann@common-lisp.net ehuelsmann@common-lisp.net wrote:
Author: ehuelsmann Date: Wed Oct 18 02:56:33 2006 New Revision: 119
Added: usocket/trunk/backend/scl.lisp usocket/trunk/notes/accept-apis.txt Modified: usocket/trunk/condition.lisp usocket/trunk/doc/design.txt usocket/trunk/usocket.asd usocket/trunk/usocket.lisp Log: Add Scieneer support.
Donated by Douglas Crosher <dtc at scieneer dot com>.
Added: usocket/trunk/backend/scl.lisp
--- (empty file) +++ usocket/trunk/backend/scl.lisp Wed Oct 18 02:56:33 2006 @@ -0,0 +1,101 @@ +;;;; $Id: scl.lisp$ +;;;; $URL: svn://common-lisp.net/project/usocket/svn/usocket/trunk/backend/scl.lisp $
+;;;; See LICENSE for licensing information.
+(in-package :usocket)
+(defparameter +scl-error-map+
- (append +unix-errno-condition-map+
+unix-errno-error-map+))
+(defun scl-map-socket-error (err &key condition socket)
- (let ((usock-err (cdr (assoc err +scl-error-map+ :test #'member))))
- (cond (usock-err
(if (subtypep usock-err 'error)
(error usock-err :socket socket)
(signal usock-err :socket socket)))
(t
(error 'unknown-error
:socket socket
:real-error condition)))))
+(defun handle-condition (condition &optional (socket nil))
- "Dispatch correct usocket condition."
- (etypecase condition
- (ext::socket-error
(format t "erron: ~D~%" (ext::socket-errno condition))
(scl-map-socket-error (ext::socket-errno condition)
:socket socket
:condition condition))
- (error
(error 'unknown-error
:real-condition condition
:socket socket))))
+(defun socket-connect (host port)
- (let* ((socket
(with-mapped-conditions (nil)
(ext:connect-to-inet-socket (host-to-hbo host) port :kind :stream)))
(stream (sys:make-fd-stream socket :input t :output t
:element-type 'character
:buffering :full)))
- ;;###FIXME the above line probably needs an :external-format
- (make-socket :socket socket :stream stream)))
+(defmethod socket-close ((usocket usocket))
- "Close socket."
- (with-mapped-conditions (usocket)
- (ext:close-socket (socket usocket))))
+(defmethod get-local-name ((usocket usocket))
- (multiple-value-bind (address port)
(with-mapped-conditions (usocket)
- (ext:get-socket-host-and-port (socket usocket)))
- (values (hbo-to-vector-quad address) port)))
+(defmethod get-peer-name ((usocket usocket))
- (multiple-value-bind (address port)
(with-mapped-conditions (usocket)
- (ext:get-peer-host-and-port (socket usocket)))
- (values (hbo-to-vector-quad address) port)))
+(defmethod get-local-address ((usocket usocket))
- (nth-value 0 (get-local-name usocket)))
+(defmethod get-peer-address ((usocket usocket))
- (nth-value 0 (get-peer-name usocket)))
+(defmethod get-local-port ((usocket usocket))
- (nth-value 1 (get-local-name usocket)))
+(defmethod get-peer-port ((usocket usocket))
- (nth-value 1 (get-peer-name usocket)))
+(defun get-host-by-address (address)
- (multiple-value-bind (host errno)
(ext:lookup-host-entry (host-byte-order address))
- (cond (host
(ext:host-entry-name host))
(t
(let ((condition (cdr (assoc errno +unix-ns-error-map+))))
(cond (condition
(error condition :host-or-ip address))
(t
(error 'ns-unknown-error :host-or-ip address
:real-error errno))))))))
+(defun get-hosts-by-name (name)
- (multiple-value-bind (host errno)
(ext:lookup-host-entry name)
- (cond (host
(mapcar #'hbo-to-vector-quad
(ext:host-entry-addr-list host)))
(t
(let ((condition (cdr (assoc errno +unix-ns-error-map+))))
(cond (condition
(error condition :host-or-ip name))
(t
(error 'ns-unknown-error :host-or-ip name
:real-error errno))))))))
Modified: usocket/trunk/condition.lisp
--- usocket/trunk/condition.lisp (original) +++ usocket/trunk/condition.lisp Wed Oct 18 02:56:33 2006 @@ -102,8 +102,8 @@ ;; isn't really an error: there's just no data to return. ;; with lisp, we just return NIL (indicating no data) instead of ;; raising an exception...
- (ns-host-not-found
- ns-no-recovery)
- (ns-host-not-found-error
- ns-no-recovery-error) (ns-error))
(define-condition ns-unknown-error (ns-error)
Modified: usocket/trunk/doc/design.txt
--- usocket/trunk/doc/design.txt (original) +++ usocket/trunk/doc/design.txt Wed Oct 18 02:56:33 2006 @@ -13,7 +13,7 @@
- Motivation
- Design goal
- Functional requirements
- Comments on the functional requirements
@@ -83,6 +83,33 @@
- OpenMCL
+The lifetime of a socket can be described with these steps:
- Socket creation (socket() function)
- Socket initializaiton (setsockopt(), bind() and listen()/connect() funcs)
- Socket use (accept() / recv[from], send[to])
- Socket termination (shutdown())
- Socket destruction (close())
+While for most applications steps 1-3 can be condensed into 1 (which most +implementations do), if the library wants to be extensible into other +domains than IP, a means should be provided to do socket initialization +without knowing what parameters to accept beforehand: other protocols +require parameters for setsockopt we will not know about in advance.
+There are several possibilities to address this issue:
- a. Force the 3 steps apart [hard to get done with the current status
- for some implementations, as they are currently integrated in the
- public interface].
- b. Find a mechanism to pass options which we want setsockopt to
- be called with. Problem: what to do with implementations which
- don't support setting of all options *before* the bind() call?
- Does it matter that some options may be set after the bind()
- call? What if they're not set before connect() [buffer size changes
- have to be set before connect()]?
- c. ... ?
Comments on the design above
Added: usocket/trunk/notes/accept-apis.txt
--- (empty file) +++ usocket/trunk/notes/accept-apis.txt Wed Oct 18 02:56:33 2006 @@ -0,0 +1,173 @@
-*- text -*-
+Part of 'Step 3': Server/passive tcp socket interfaces supplied by +the different implementations in order to provide the same externally.
+ABCL +====
- ext:make-server-socket port
- ext:socket-accept socket
- ext:socket-close socket
+Allegro +=======
- socket:make-socket :type :stream :connect :passive
:local-port <port> :reuse-address t :backlog <nr>
:local-host <host-ip>
- socket:accept-connection sock &key wait
- close
+clisp +=====
- socket:socket-server &optional port &key interface backlog
- socket:socket-server-close sock
- socket:socket-server-host sock
- socket:socket-server-port sock
- socket:socket-accept sock &key element-type external-format buffered timeout
- socket:socket-options sock &rest options
+... and ofcourse, there's the raw-sockets
+CMUCL +=====
- ext:create-inet-listener port &optional kind
&key reuseaddress backlog interface
- ext:accept-tcp-connection socket
+LispWorks +=========
- comm::get-fd-from-socket (socket-os-fd lispworks-socket)
- comm::create-tcp-socket-for-service port
(may use comm::*use_so_reuseaddr* for that socket option)
misses the ability to specify an interface to bind to.
- comm::socket-close
+OpenMCL +=======
- openmcl-socket:accept-connection
- openmcl-socket:make-socket :local-host <if> :local-port port
:reuse-address t :type :stream :connect :passive
:backlog <nr>
- close
+SBCL +====
- make-instance 'inet-socket
- sb-bsd-sockets:sockopt-*
- sb-bsd-sockets:socket-bind
- sb-bsd-sockets:socket-listen
- sb-bsd-sockets:socket-accept
+;; +;; +;; The above APIs are good enough to implement a simple +;; accept interface, but doesn't give access to specifying +;; socket options before the socket is bound to the interface +;; ==> This may only actually be required for SO_REUSEADDRESS?!??? +;; +;; The other option would be to use lots of FFI - where needed - +;; and use the (mostly internal) glue routines from the implementations
+ABCL +====
- With ABCL - lacking a good sockets API - it's still possible to implement
- whatever we need to get good access...
+Allegro +=======
- Hmm. The accept function in this implementation does not allow limiting
- connections to a given host/ip, but it does allow to create sockets
- with mostly the right options.
- Is that enough reason to do this entirely in ffi?!
- Also, doing this in FFI would require to reverse engineer the creation
- of socket streams. Maybe Franz tech support could help there though.
- Need to investigate the IPC_* symbols an the sockets package:
- there are lots of functions which look like they should be useable.
+clisp +=====
- This implementation allows access to the full sockets as described
- in http://clisp.cons.org/impnotes/rawsock.html.
+CMUCL +=====
- Provides (in unix package):
- unix-accept
- unix-bind
- unix-listen
- unix-socket
- Provides (in extentions):
- inet-sockaddr
- get-socket-option
- set-socket-option
- create-inet-listener port &key host reuse-address backlog
+LispWorks +=========
- The implementation provides a lot of undocumented functions the library
- could tap into:
- comm::socket
- comm::bind
- comm::accept
- comm::getsockopt
- comm::setsockopt
- comm::initialize-sockaddr_in (helper)
- comm::streams-from-fd (helper)
+OpenMCL +=======
- make-socket provides all options which we'll need to set,
- it doesn't however provide access to [gs]etsockopt...
+SBCL +====
- provides (in sb-bsd-sockets):
- socket-bind
- socket-accept
- sokcet-listen
- provides (in sb-bsd-sockets-internal [sockint]):
- getsockopt
- setsockopt
- SO-* constants
- TCP-* constant(s)
- AF-* constants (and, since AF-* == IF-*, we don't need others)
Modified: usocket/trunk/usocket.asd
--- usocket/trunk/usocket.asd (original) +++ usocket/trunk/usocket.asd Wed Oct 18 02:56:33 2006 @@ -28,6 +28,8 @@ :depends-on ("condition")) #+cmu (:file "cmucl" :pathname "backend/cmucl" :depends-on ("condition"))
#+scl (:file "scl" :pathname "backend/scl"
:depends-on ("condition")) #+sbcl (:file "sbcl" :pathname "backend/sbcl" :depends-on ("condition")) #+lispworks (:file "lispworks" :pathname "backend/lispworks"
Modified: usocket/trunk/usocket.lisp
--- usocket/trunk/usocket.lisp (original) +++ usocket/trunk/usocket.lisp Wed Oct 18 02:56:33 2006 @@ -164,8 +164,8 @@ (string (let ((ip (ignore-errors (dotted-quad-to-vector-quad host)))) (if (and ip (= 4 (length ip)))
ip
(host-to-hbo (get-host-by-name host)))))
(host-byte-order ip)
(host-to-hbo (get-host-by-name host))))) ((vector t 4) (host-byte-order host)) (integer host))))
@@ -186,9 +186,19 @@ ;;
(setf (documentation 'socket-connect 'function)
"Connect to `host' on `port'. `host' is assumed to be a string of
"Connect to `host' on `port'. `host' is assumed to be a string or
an IP address represented in vector notation, such as #(192 168 1 1). `port' is assumed to be an integer.
Returns a usocket object.")
+;; Documentation for the function +;; +;; (defun SOCKET-LISTEN (host port &key local-ip local-port +;; reuseaddress backlog) ..)
+;; Documentation for the function +;; +;; (defun SOCKET-ACCEPT (socket &key element-type external-format +;; buffered timeout) ..) _______________________________________________ usocket-cvs mailing list usocket-cvs@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-cvs