guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sample code for networking and safe evaluation


From: Martin Grabmueller
Subject: Sample code for networking and safe evaluation
Date: Tue, 22 May 2001 20:40:03 +0200

Hello list,

just played a bit with networking and safe modules, and now I thought
I'd better share the resulting modules with you.  Attached are two
Guile modules:

(net inet-server) Module for running simple, single-threaded internet
                  servers.

(net eval-server) Module for running a safe REPL server.

More information is in the comments.

Have fun,
  'martin


===File ~/guile/net/inet-server.scm=========================
;;;; inet-server.scm --- Internet server loop.

;;; Copyright (C) 2001 Martin Grabmueller <address@hidden>
;;;
;;; This program comes with ABSOLUTELY NO WARRANTY.  This program is
;;; released under GNU GPL.

;;; Commentary:
;;;
;;; Using this module, you can easily create simple, single-threaded
;;; internet servers.
;;;
;;; Example usage:
;;;
;;;   (use-modules (net inet-server))
;;;   (spin 2001 (lambda (s p) (display "Hello world!" s) (newline s)))
;;;
;;; and then
;;;
;;;   telnet localhost 2001
;;;
;;; in another xterm.

;;;  Code:

(define-module (net inet-server))

(export spin)

;; spin inet-port handler
;;
;; Create a socket listening on port INET-PORT.  Whenever a connection
;; arrives, it is accepted and HANDLER is called with two arguments:
;;
;; - A port, suitable for reading from and writing to the socket, and
;; - a sockaddr structure with the remote IP address.
;;
(define (spin inet-port handler)
  (let ((port (socket AF_INET SOCK_STREAM 0)))
    (bind port AF_INET INADDR_ANY inet-port)
    (listen port 10)                    ; Queue up to 10 requests.
    (let loop ()
      (let ((p (accept port)))
        (catch #t
          (lambda () (handler (car p) (cdr p)))
          (lambda x #t))
        (close-port (car p))
        (loop)))))
============================================================

===File ~/guile/net/eval-server.scm=========================
;;;; eval-server.scm --- REPL server.

;;; Copyright (C) 2001 Martin Grabmueller <address@hidden>
;;;
;;; This program comes with ABSOLUTELY NO WARRANTY.  This program is
;;; released under GNU GPL.

;;; Commentary:
;;;
;;; This is an example module for creating a safe REPL server with Guile.
;;;
;;; Example usage:
;;;
;;;   (use-modules (net eval-server))
;;;   (safe-eval-server 2001)
;;;
;;; and then
;;;
;;;   telnet localhost 2001
;;;
;;; in another xterm.  Enter expressions and see how they get
;;; evaluated.

;;; Code:

(define-module (net eval-server)
  :use-module (ice-9 safe)
  :use-module (net inet-server))

(export safe-eval-server)

;; safe-eval-server inet-port
;;
;; Bind a server on port INET-PORT, which will accept connections and
;; whenever one arrives, a REPL is started on the connection.
;;
(define safe-eval-server
  (let ((handler
         (lambda (socket sockaddr)
           ;; Log the incoming connection to standard output.
           (display "Connection from ")
           (display (inet-ntoa (sockaddr:addr sockaddr)))
           (display " ")
           (display (sockaddr:port sockaddr))
           (newline)

           ;; Create a safe module, read an expression and evaluate it.
           ;; Ignore all exceptions.  The input, output and error ports
           ;; are redirected to the socket.
           ;;
           (let ((module (make-safe-module)))
             (let lp ((expr (read socket)))
               (catch #t
                 (lambda ()
                   (let ((res
                          (with-output-to-port socket
                            (lambda () 
                              (with-input-from-port socket
                                (lambda () 
                                  (with-error-to-port
                                   socket
                                   (lambda () (eval expr module)))))))))
                     (write res socket)
                     (newline socket)
                     (force-output socket)
                     (lp (read socket))))

                 ;; Handle exceptions.
                 ;;
                 (lambda args
                   (display "** Exception: " socket)
                   (write args socket)
                   (newline socket)
                   (force-output socket)
                   (lp (read socket)))))))))

    ;; Call the server loop from the (net inet-server) module
    ;;
    (lambda (inet-port)
      (spin inet-port handler))))
============================================================



reply via email to

[Prev in Thread] Current Thread [Next in Thread]