Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!psuvax1!uwm.edu!spool.mu.edu!think.com!barmar From: barmar@think.com (Barry Margolin) Newsgroups: comp.lang.lisp Subject: Re: Lucid specific stream question Message-ID: <1991Feb1.200830.12352@Think.COM> Date: 1 Feb 91 20:08:30 GMT References: <13256@medusa.cs.purdue.edu> <1991Feb1.062927.2260@Think.COM> <13262@medusa.cs.purdue.edu> Sender: news@Think.COM Distribution: usa Organization: Thinking Machines Corporation, Cambridge MA, USA Lines: 67 In article <13262@medusa.cs.purdue.edu> bouma@cs.purdue.EDU (William J. Bouma) writes: > When I posed the question I thought it would probably be something more > involved than just the setf. Are you saying there is no way to do what > I want? Maybe this would work: > > (setq *standard-input* > (make-lisp-stream :input-handle 0 > :element-type '(unsigned-byte 8))) That should work, and should do what you want. However, I suggest that you do something like: (setq *binary-input* ...) rather than setting *standard-input*. Internal functions in the implementation may be dependent on being able to do character input from *standard-input*. Your XDR software can use *binary-input* and *binary-output* as its default streams. Even better would be to use explicit parameters rather than global variables, if feasible. > What I do is have a server on a unix > machine that dup2s the socket over 0 and 1 and then forks a lisp process. > Thus the lisp process is communicating to the socket through *standard-io*. > I use the XDR data protocol. Seems a waste to do the char conversions all > the time. You are confusing Unix stdin and stdout with Lisp's *STANDARD-INPUT* and *STANDARD-OUTPUT*. What you want are Lisp byte streams connected to Unix stdin and stdout; you don't need to change *STANDARD-INPUT* and *STANDARD-OUTPUT* to do this. You've admitted that portability to other Common Lisp implementations isn't an overriding concern (and if it were, it would be easy to push the above into a file containing implementation-dependent pieces with lots of #+); the most portable scheme is to call CHAR-CODE and CODE-CHAR alot (this isn't even completely portable, because CODE-CHAR is not required to work for all codes). However, one possible relationship between *BINARY-xxx* and *STANDARD-xxx* that you might want to guarantee is that they communicate with the same Unix fd's. I.e. if your XDR software is used after someone has done (setq *standard-input* (make-lisp-stream :input-handle 5 :element-type 'string-char)) then *BINARY-INPUT* should also read from file descriptor 5. In that case, you can do: (defun binary-stream-like (stream direction) (make-lisp-stream (case direction (:input :input-handle) (:output :output-handle)) (extract-stream-handle stream direction) :element-type '(unsigned-byte))) (setq *binary-input* (binary-stream-like *standard-input* :input)) (setq *binary-output* (binary-stream-like *standard-output* :output)) By the way, I just learned the hard way that you shouldn't call CLOSE on these binary streams. Apparently, closing a stream created with MAKE-LISP-STREAM closes the associated Unix fd, even if Lisp has other streams with the same handle. Closing stdin and then returning to the read-eval-print loop (or doing anything that uses *STANDARD-INPUT*) is an easy way to get into a recursive error loop. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar