[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: telnet to MzScheme
On Mar 5, Scorzelli Giorgio wrote:
> Hy all,
>
> I have defined the following script to make MzScheme usable by a simple
> telnet connection:
>
> (define (server port)
> (let ([l (tcp-listen port)])
> (let-values ([(r w) (tcp-accept l)])
> (current-output-port w)
> (current-input-port r)
> (current-error-port w))))
>
> but I have a problem: how can I reset MzScheme input port to reset
> (as I normally do with CTRL+C) its contents.
The problem is that the telnet protocol is not too trivial... I once
wanted a remote-scheme (actually, Swindle) thing similar to what
you're trying to do, but with user logins, background jobs (and C-z to
kick the current evaluation to the bg) etc etc. After some digging I
managed to get basic functionality, here is the relevant piece of
code:
;; some constants for telnet protocol
(define telnet-escape-ch (integer->char 255))
(define eof-ch (integer->char 4))
;; this function manage telnet input processing
(define (filter-proc in out)
;; get a character
(define ch (read-char in))
(cond
;; end-of-file (eof-object? shouldn't be #t)
((or (eof-object? ch) (eq? ch eof-ch))
;; suffocate eval's input
(close-output-port out))
((eq? ch telnet-escape-ch)
;; handle telnet escapes
(case (char->integer (read-char in))
((244) ; C-c
(if (thread-running? eval-thread)
;; break the thread
(break-thread eval-thread)
;; if eval-thread is dead - we're waiting for background
;; expressions, kill all
(for-each break-thread background-exprs)))
((236) ; C-d
;; this is what telnet is supposed to send on an end-of-file
(close-output-port out))
((237) ; C-z
;; mark this interrupt as suspension
(set! suspending? #t)
(break-thread eval-thread))
((253)
;; Telnet protocol: DO X --> WON'T X, except for DO ECHO
(set! ch (read-char in))
(unless (= 1 (char->integer ch))
(write-char telnet-escape-ch telnet-out)
(write-char (integer->char 252) telnet-out)
(write-char ch telnet-out)))
((251 252 254)
;; ignore WILL/WONT/DONT
(read-char in))
((255)
;; escape escape is escape
(write-char ch telnet-out))
(else #f)))
(else
;; out shouldn't be dead but be safe
(no-errors (write-char ch out))))
;; loop forever
(filter-proc in out))
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!