I ran into this issue with rsound. I'm not sure how standard output can
be directly captured from a lower-level language in a Racket context
when that language can freely ignore the Racket printer and write
directly to STDOUT within the same operating system process.

I'd hate to just add a "me too", but the only way quick way I could
think to handle that was to add another subprocess. If I were wanting to
solve the problem in one process, I'd probably extend Racket at the C
level and integrate my output with ports.

https://docs.racket-lang.org/inside/Ports_and_the_Filesystem.html?q=c%20api

On 5/12/21 3:48 AM, Paulo Matos wrote:
> Hi,
>
> I have a shared library for which I am creating some bindings:
> https://github.com/pmatos/racket-binaryen
>
> There's a function BinaryenModulePrint that prints a WebAssembly module
> to stdout.
>
> When I wrap it in racket, if I do something like:
> (define mod ...)
> (with-output-to-string (lambda () (BinaryenModulePrint mod)))
>
> The return value will be "" and it will still print the module to
> stdout. I understand! However, I don't know how to solve it in Racket.
>
> In C, things seem easier because I have access to dup2 and pipe in case
> I need to redirect things, however in Racket all my attempts have
> failed.
>
> I have created the simple example:
> ```hello.c
> #include <stdio.h>
>
> void hello(void) {
>    printf("hello world!\n");
> }
> ```
>
> Compile with `gcc -shared -o hello.so hello.c`.
>
> Then:
> ```hello.rkt
> #lang racket/base
>
> (require racket/port
>           ffi/unsafe
>           ffi/unsafe/define)
>
> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so"))
> (define-ffi-definer define-hello libhello)
> (define-hello hello (_fun -> _void))
> (with-output-to-string hello)
> ```
>
> Here's the issue! In C, I can do something like:
> ```hello-fix.c
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/stat.h>
> #include <fcntl.h>
>
> extern void hello(void);
>
> int main(void) {
>    int filefd = open("test.txt", O_WRONLY|O_CREAT, 0666);
>    dup2(filefd, fileno(stdout));
>    hello();
>
>    return 0;
> }
> ```
> Compile with `gcc -o hello hello.c hello-fix.c`
>
> This will, send the output of hello() to a file. Now, in racket
> preferably I want to connect what is sent to raw stdout, fd 1, to
> current-output-port.
>
> My thought was that I could create a dup2 ffi binding, and use
> unsafe-port->file-descriptor to install the racket pipe file descriptor
> in stdout using the dup2 ffi binding but it doesn't work.
>
> And it doesn't work because the unsafe-port->file-descriptor returns #f,
> even though port-waiting-peer? return #f as well (which sort of hints
> that maybe the documentation of unsafe-port->file-descriptor is
> incomplete.
>
> The start of my attempt would look like this:
>
> ```hello.rkt
> #lang racket/base
>
> (require racket/port
>           ffi/unsafe
>           ffi/unsafe/define
>           ffi/unsafe/port)
>
> (define libhello (ffi-lib "/home/pmatos/dev/tmp/ffi-hello-world/hello.so"))
>
> (define-ffi-definer define-libc (ffi-lib #f))
> (define-ffi-definer define-hello libhello)
>
> (define-libc dup2 (_fun _int _int -> _int))
> (define-hello hello (_fun -> _void))
>
> (define-values (in out) (make-pipe))
>
> ;; FAILS because (unsafe-port-> ...) return #f
> (dup2 (unsafe-port->file-descriptor out) 1)
>
> ;;...
> ;; connect the other end of the port to current-output-port
> ;; and use a thread to copy-port
> ```
>
> Surely there must be a better way than this and I would be surprised if
> there isn't already something out there in a library but I haven't found
> anything yet. Any help here would be great.
>
> Thanks,
>
> --
> Paulo Matos
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/87r1icxuhi.fsf%40linki.tools.

--
~slg


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/1abd8d17-a53c-b7fa-8983-57deec760e96%40sagegerard.com.

Reply via email to