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