How to implement a system call?

Hi everybody! :wave:

I’m trying to figure out how to make a system call which is not present in Unix module. Suppose I need shm_open to access the shared memory, what is the general flow of implementing such thing? It would be great to make it compatible with other function that work with Unix file descriptors and not something special like shm_descr.

I’m noob in system programming, but it happened I need to start somewhere…

You can call an external function by just using its name in an external declaration:

external my_syscall : int -> string -> int = "caml_my_syscall"

where caml_my_syscall is a symbol that will be resolved at link time.

Conceptually, that is what you will need to do to use your syscall. However, you usually cannot call a C function directly, but you call a wrapper function that converts between OCaml values and C values. When programming these wrappers, you need to follow some guidelines so that the C code interacts well with the garbage collector.

The page I just linked to contains a number of examples of such wrapper functions. You can also take a look at the implementation of Unix: the external declarations are in unix_unix.ml (for Unix-like systems) or unix_win32.ml (for Windows), and the C functions referred to are in small-ish C files, e.g. the implementation of chown.

On Linux, values of type file_descr are just OCaml integers, so you just need to convert to C integers (there’s a macro for that, see the docs) to use them in syscalls.

1 Like

P.S. if you use dune, compiling and linking your C stubs is straightforward: General Concepts — dune documentation

Hello! You might find some inspiration from looking at the implementation of this function from ocamlnet: netsys_posix.ml + netsys_c_shm.c. If you just wanted to use it, it’s at Netsys_posix.shm_open :slight_smile:

1 Like