[racket] Sandbox, in a module, with a *shared* environment but *separate* I/O

From: Tony Garnock-Jones (tonyg at ccs.neu.edu)
Date: Thu Oct 27 19:32:25 EDT 2011

I've managed to kludge together a solution that seems to do what I want.
It seems that it's a shared *namespace* instance I want, with a fresh
evaluator for each connection, and the only (?) control over namespaces
for sandboxes is via sandbox-namespace-specs. It isn't the most elegant,
but here's the code:

#lang racket/base

(require racket/tcp)
(require racket/sandbox)

(define e (make-base-namespace))

(define (shell in out)
  (printf "Accepted\n")
  (fprintf out "Hello.\n")
  (parameterize ((current-input-port in)
		 (current-output-port out)
		 (current-error-port out)
		 (sandbox-input in)
		 (sandbox-output out)
		 (sandbox-error-output out)
		 (current-namespace e)
		 (sandbox-namespace-specs (list (lambda () e))))
    (parameterize ((current-eval (make-evaluator '(begin))))
    (fprintf out "\nGoodbye!\n")
    (close-input-port in)
    (close-output-port out)))

(define s (tcp-listen 2322 4 #t))
(printf "Accepting...\n")
(let loop ()
  (define-values (i o) (tcp-accept s))
  (thread (lambda ()
	    (shell i o)))

Any suggestions people have for improving that are very welcome.


On 2011-10-27 3:45 PM, Tony Garnock-Jones wrote:
> Hi all,
> The example TCP-listening sandboxed REPLs given nearish the top of
> http://docs.racket-lang.org/reference/Sandboxed_Evaluation.html differ
> slightly: the one that only works from the toplevel shares a namespace
> and evaluator between all the connections, but the one that works from a
> module uses a fresh namespace and evaluator for each connection.
> How can I set things up so that
>  - a single "global environment" is shared between all connections, but
>  - each connection gets its own input and output ports, connected
>    to the socket?
> I'd like to be able to connect in one terminal, say "(define x 123)",
> then connect in another terminal and have "x" result in "123". I'd also
> like "(display 'hello)" to print to the issuing terminal rather than
> going only to one or the other.
> Does this sound like a familiar problem? Have others solved this before?
> I feel like I'm missing something about the distinction between
> namespaces and evaluators...
> Regards,
>   Tony
> _________________________________________________
>   For list-related administrative tasks:
>   http://lists.racket-lang.org/listinfo/users

Posted on the users mailing list.