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
On 27 Oct 2005, at 16:20, Fred Nicolier wrote:
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?
[...]
Hi Fred,
Thanks for the contribution. I am currently (this week) reorganizing all my open source common lisp projects, making them more modular and moving most of them to darcs. My older sysdeps code has become a new standalone package,S-SYSDEPS, the unfinished version can be seen at
http://homepage.mac.com/svc/s-sysdeps/
I have not yet integrated your changes there, but I will shortly. Note also that this sysdeps version is slightly different than the one you started from (and contains some more API, like for lock management).
I'll keep you posted,
Sven
s-xml-rpc-devel@common-lisp.net