The Unix Module
Author: Christian.Queinnec@lip6.fr

## The `Unix` Module

This module contains the interfaces to the most important Unix library functions. Much of this module has been ported to Windows and can be used there. Whenever necessary we will indicate the restrictions in the use of the presented functions. A table resuming the restrictions is given by figure 18.1.
The `Unix` library belongs to the Objective CAML non-standard libraries which have to be bound by the `-custom` compiler command (see chapter 7, page ??). Depending on the desired form of the program, one of the following commands is used under Unix to produce bytecode, native code or an interaction loop:

    $ ocamlc -custom unix.cma  fichiers.ml -cclib -lunix
    $ ocamlopt unix.cma fichiers.ml -cclib -lunix
    $ ocamlmktop -custom -o unixtop unix.cma -cclib -lunix

The purpose of constructing an interaction loop (of which the name will be `unixtop`) is to support an incremental development style. Each function can be compiled quickly from its type declaration. It is also possible to execute functional tests.
Depending on the version of Unix in use, the system library may not be located at the default place. If necessary the access path of the libraries may be indicated with the option `-ccopt` (see chapter 7).
Under Windows the commands to compile become:

    $ ocamlc -custom unix.cma  fichiers.ml %CAMLLIB%\libunix.lib wsock32.lib
    $ ocamlopt unix.cma fichiers.ml %CAMLLIB%\libunix.lib wsock32.lib
    $ ocamlmktop -custom -o unixtop.exe unix.cma %CAMLLIB%\libunix.lib wsock32.lib

The name of the obtained interaction loop is `unixtop.exe`.

### Error Handling

Errors produced by system calls throw `Unix_error` exceptions, which can be handled by the Objective CAML program. Such errors contain three arguments: a value of type `Unix.error` which can be transformed into a character string by the function `error_message`, a string containing the name of the function producing the error and optionally, a string containing the argument of the function when the argument is of type string.
It is possible to define a generic calling function with error treatment:

    # let wrap_unix funct arg =
       try (funct arg) with
        Unix.Unix_error (e,fm,argm) ->
          Printf.printf "%s %s %s" (Unix.error_message e) fm argm ;;
    val wrap_unix : ('a -> unit) -> 'a -> unit = <fun>

The function `wrap_unix` takes a function and its argument, and applies one to the other. If a Unix error occurs, an explaining message is printed. An equivalent function is defined in the `Unix` module:

    # Unix.handle_unix_error ;;
    - : ('a -> 'b) -> 'a -> 'b = <fun>

### Portability of System Calls

Figure 18.1 indicates which of the communication and process handling functions presented in this chapter are accessible under Windows. The main shortcoming is the lack of the two functions `fork` and `kill` to create new processes and to send signals.

> Fonction | Unix | Windows | Comment
> `openfile` | × | × |
> `close` | × | × |
> `dup` | × | × |
> `dup2` | × | × |
> `read` | × | × |
> `write` | × | × |
> `lseek` | × | × |
> `execv` | × | × |
> `execve` | × | × |
> `execvp` | × | × |
> `execvpe` | × | × |
> `fork` | × |  | use `create_process`
> `getpid` | × | × |
> `sleep` | × | × |
> `wait` | × |  |
> `waitpid` | × | × | only for a given
> |  |  | number of processes
> `create_process` | × | × |
> `create_process_env` | × | × |
> `kill` | × |  |
> `pipe` | × | × |
> `mkfifo` | × |  |
> `open_process` | × |  | use the interpretation of
> |  |  | `/bin/sh` commands
> `close_process` | × |  |

> Figure 18.1: Portability of the module `Unix` functions used in this chapter.

Furthermore, the function `wait` waiting for the end of a child process is not implemented, because `fork` is not.