Hi,
I wrote some lines to port s-xml-rpc to cmucl. Here is the code
from the file sysdeps.lisp :
What do you think?
>>
;;;; -*- mode: lisp -*-
;;;;
;;;; $Id: sysdeps.lisp,v 1.1.1.1 2004/06/09 09:02:39 scaekenberghe Exp $
;;;;
;;;; These are the system dependent part of S-XML-RPC.
;;;; Ports to OpenMCL, LispWorks and SBCL are provided.
;;;; Porting to another CL requires implementating these definitions.
;;;;
;;;; Copyright (C) 2002, 2004 Sven Van Caekenberghe, Beta Nine BVBA.
;;;; SBCL port Copyright (C) 2004, Brian Mastenbrook & Rudi Schlatte.
;;;;
;;;; You are granted the rights to distribute and use this software
;;;; as governed by the terms of the Lisp Lesser General Public License
;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
(eval-when (compile load eval)
#+cmu (require :simple-streams))
(in-package :s-xml-rpc)
(defmacro with-open-socket-stream ((var host port) &body body)
"Execute body with a bidirectional socket stream opened to host:port"
#+openmcl
`(ccl:with-open-socket (,var :remote-host ,host :remote-port ,port)
,@body)
#+lispworks
`(with-open-stream (,var (comm:open-tcp-stream ,host ,port))
,@body)
#+cmu
`(let ((,var (make-instance 'stream:socket-simple-stream :direction :io
:remote-host ,host :remote-port ,port)))
(unwind-protect
(progn ,@body)
(ext:close-socket ,var)))
#+sbcl
(let ((socket-object (gensym)))
`(let ((,socket-object (make-instance 'sb-bsd-sockets:inet-socket
:type :stream
:protocol :tcp)))
(sb-bsd-sockets:socket-connect ,socket-object
(car (sb-bsd-sockets:host-ent-addresses
(sb-bsd-sockets:get-host-by-name ,host))) ,port)
(let ((,var (sb-bsd-sockets:socket-make-stream ,socket-object
:element-type 'character
:input t
:output t
:buffering :none)))
(unwind-protect
(progn ,@body)
(close ,var))))))
(defun run-process (name function &rest arguments)
"Create and run a new process with name, executing function on arguments"
#+lispworks (apply #'mp:process-run-function name '(:priority 3) function arguments)
#+openmcl (apply #'ccl:process-run-function name function arguments)
#+sbcl (apply function arguments)
#+cmu (apply function arguments))
(defvar *server-processes* nil)
(defun start-standard-server (&key port name connection-handler)
"Start a server process with name, listening on port, delegating to connection-handler with stream as argument"
#+lispworks (comm:start-up-server
:function #'(lambda (socket-handle)
(let ((client-stream (make-instance 'comm:socket-stream
:socket socket-handle
:direction :io
:element-type 'base-char)))
(funcall connection-handler client-stream)))
:service port
:announce t
:error t
:wait t
:process-name name)
#+openmcl (ccl:process-run-function
name
#'(lambda ()
(let ((server-socket (ccl:make-socket :connect :passive
:local-port port
:reuse-address t)))
(unwind-protect
(loop
(let ((client-stream (ccl:accept-connection server-socket)))
(funcall connection-handler client-stream)))
(close server-socket)))))
#+cmu (let* ((socket (ext:create-inet-listener (or port 0)))
(handler-fn (lambda (fd)
(declare (ignore fd))
(let ((stream
(sys:make-fd-stream
(ext:accept-tcp-connection socket)
:buffering :none
:input t
:output t
:element-type 'base-char)))
(funcall connection-handler stream)))))
(push (list name socket (sys:add-fd-handler socket :input handler-fn))
*server-processes*))
#+sbcl (let* ((socket
(make-instance 'sb-bsd-sockets:inet-socket :type :stream
:protocol :tcp))
(handler-fn (lambda (fd)
(declare (ignore fd))
(let ((stream
(sb-bsd-sockets:socket-make-stream
(sb-bsd-sockets:socket-accept socket)
:element-type 'character
:input t
:output t
:buffering :none)))
(funcall connection-handler stream)))))
(setf (sb-bsd-sockets:sockopt-reuse-address socket) t)
(sb-bsd-sockets:socket-bind socket #(0 0 0 0) port)
(sb-bsd-sockets:socket-listen socket 15)
(push (list name socket
(sb-sys:add-fd-handler
(sb-bsd-sockets:socket-file-descriptor socket)
:input handler-fn)) *server-processes*))
name)
(defun stop-server (name)
"Kill a server process by name (as started by start-standard-server)"
#+lispworks
(let ((server-process (mp:find-process-from-name name)))
(when server-process
(mp:process-kill server-process)))
#+openmcl
(let ((server-process (find name (ccl:all-processes)
:key #'ccl:process-name :test #'string-equal)))
(when server-process
(ccl:process-kill server-process)))
#+sbcl
(progn
(destructuring-bind (name socket handler)
(assoc name *server-processes* :test #'string=)
(sb-sys:remove-fd-handler handler)
(sb-bsd-sockets:socket-close socket))
(setf *server-processes* (delete name *server-processes*
:key #'car :test #'string=)))
#+cmu
(progn
(destructuring-bind (name socket handler)
(assoc name *server-processes* :test #'string=)
(sys:remove-fd-handler handler)
(ext::close-socket socket))
(setf *server-processes* (delete name *server-processes*
:key #'car :test #'string=)))
name)
;;;; eof
>>
--
Fred Nicolier