[plt-scheme] Read and write ports from pre-opened file descriptors?

From: David Fayram (dfayram at gmail.com)
Date: Wed Feb 27 14:41:18 EST 2008

Not only is it concise and simple, but it works. Thank you!

- dlf


On Feb 27, 2008, at 11:33 AM, Matthew Flatt wrote:

> Simpler:
>
>  (module fd mzscheme
>    (require (lib "foreign.ss")) (unsafe!)
>    (provide fd->input-port
>             fd->output-port)
>
>    (define (fd->input-port fd name)
>      (scheme_make_fd_input_port fd name 0 0))
>
>    (define (fd->output-port fd name)
>      (scheme_make_fd_output_port fd name 0 0 0))
>
>    (define scheme_make_fd_input_port
>      (get-ffi-obj "scheme_make_fd_input_port" #f
>                   (_fun _int _scheme _int _int -> _scheme)))
>
>    (define scheme_make_fd_output_port
>      (get-ffi-obj "scheme_make_fd_output_port" #f
>                   (_fun _int _scheme _int _int _int -> _scheme))))
>
>
> At Wed, 27 Feb 2008 14:19:36 -0500, Eli Barzilay wrote:
>> On Feb 27, David Fayram wrote:
>>> Hello, everyone. I'm relatively new to scheme and I've been trying
>>> to writing a binding between Erlang and Scheme for a clustering
>>> application I've built in Erlang. Part of this entails reading and
>>> writing to file descriptors 3 and 4 in a binary protocol for
>>> communication with Erlang via its Ports abstraction.
>>>
>>> It seems like this is possible to do at the C level, but I'm not
>>> sure how to do it with MzScheme's ffi library. It would be best if
>>> there were no external binary objects. Could someone suggest a way
>>> that this might be accomplished?
>>
>> A rough start at doing this:
>>
>>  (module fd-read mzscheme
>>    (require (lib "foreign.ss")) (unsafe!)
>>    (provide fd-read)
>>    (define buf-len 512)
>>    (define fd-read
>>      (get-ffi-obj "read" #f
>>        (_fun ;; the fd argument is the only actual input for this
>>              [fd : _int]
>>              ;; the `buf' input is automatically set to a newly
>>              ;; created byte-string
>>              [buf : _bytes = (make-bytes buf-len)]
>>              ;; len is also automatic -- the size of the buffer
>>              [len : _int = buf-len]
>>              ;; we get back a value that we bind to `n'
>>              -> [n : _int]
>>              ;; but this is what we actually return
>>              -> (if (= n buf-len) buf (subbytes buf 0 n))))))
>>
>> I'm saying `rough' because there might be some off-by-1 errors with
>> the limits, and you might want to avoid allocating a new byte-string
>> on every call and/or avoid copying the actual result from the buffer.
>> (But you'll need to implement some locking if you want to do it
>> properly.)
>>
>> I tried it with bash, and the only way I could get it to get input on
>> 4 (from "x") and keep 0 as stdin is
>>
>>  mzscheme 5<&0 0<x 4<&0- 0<&5
>>
>> It seems to work with that.
>>
>> (This obviously is not intended for Windows...)
>>
>> --  
>>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli  
>> Barzilay:
>>                  http://www.barzilay.org/                 Maze is  
>> Life!
>> _________________________________________________
>>  For list-related administrative tasks:
>>  http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.