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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/87r1icxuhi.fsf%40linki.tools.

Reply via email to