Wrapping of Linux unshare syscall - OCaml 4.07.1

Hi all,

I’m trying to wrap the unshare Linux syscall
In order to do this I’m creating a simple wrapper in C and then using this one from OCaml.

But I’m unable to build the code, I mainly got errors from the C portion.

unshare.ml

 external unshare : unit -> int = "caml_unshare"
 let unshare _ = unshare ()

unshare_stubs.c

#define _GNU_SOURCE

#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// I guess I dot not need all of these
#include "caml/alloc.h"
#include "caml/bigarray.h"
#include "caml/custom.h"
#include "caml/fail.h"
#include "caml/memory.h"
#include "caml/signals.h"
#include "caml/unixsupport.h"

CAMLprim value caml_unshare() {

  int flags;
  int res;

  flags = CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWNET | CLONE_NEWPID;
  res = unshare(flags);

  CAMLreturn(Val_int(res));
}

dune

(library
 (name unshare)
 (synopsis "Wrap around unshare")
 (public_name unshare)
 (modules unshare)
 (c_names unshare_stubs))

output of dune build

dune build
  ocamlc src/unshare_stubs.o (exit 2)
(cd _build/default/src && /home/ato/.opam/old_yaks/bin/ocamlc.opt -g -ccopt -O2 -ccopt -fno-strict-aliasing -ccopt -fwrapv -ccopt -fPIC -ccopt -g -o unshare_stubs.o unshare_stubs.c)
In file included from unshare_stubs.c:19:0:
unshare_stubs.c: In function ‘caml_unshare’:
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:443:37: error: ‘caml__frame’ undeclared (first use in this function); did you mean ‘caml_raise’?
 #define CAMLdrop caml_local_roots = caml__frame
                                 ^
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:452:3: note: in expansion of macro ‘CAMLdrop’
   CAMLdrop; \
   ^~~~~~~~
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:456:28: note: in expansion of macro ‘CAMLreturnT’
 #define CAMLreturn(result) CAMLreturnT(value, result)
                        ^~~~~~~~~~~
unshare_stubs.c:31:3: note: in expansion of macro ‘CAMLreturn’
   CAMLreturn(Val_int(res));
   ^~~~~~~~~~
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:443:37: note: each undeclared identifier is reported only once for each function it appears in
 #define CAMLdrop caml_local_roots = caml__frame
                                 ^
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:452:3: note: in expansion of macro ‘CAMLdrop’
   CAMLdrop; \
   ^~~~~~~~
/home/ato/.opam/old_yaks/lib/ocaml/caml/memory.h:456:28: note: in expansion of macro ‘CAMLreturnT’
 #define CAMLreturn(result) CAMLreturnT(value, result)
                        ^~~~~~~~~~~
unshare_stubs.c:31:3: note: in expansion of macro ‘CAMLreturn’
   CAMLreturn(Val_int(res));
   ^~~~~~~~~~

any idea/suggestion?

dune version 1.11.0

Thanks
Gabriele

The only ocaml headers that you need are memory.h and mlvalues.h (you are missing this one). You are also missing a call to CAMLparam1 on the (missing) caml_unshare argument.

Note that you might want to have a look at the ctypes library in order to avoid dealing directly with C stubs.

2 Likes

You are also missing a call to CAMLparam1 on the (missing) caml_unshare argument

Ah right!
After fixing the imports and the parameter it is working, at least it builds
Thanks a lot!

Note that you might want to have a look at the ctypes library in order to avoid dealing directly with C stubs.

I was actually looking in doing this using ctypes, but I guess I have to find first which library (.so) implements that function and then link it is that right?
I have experience with ctypes only with custom libraries not with system ones