val absolute_path : string -> string

absolute_path path first makes an absolute path, `s` from `path`, prepending the current working directory if `path` was relative. Then `s` is rewritten using `rewrite_absolute_path`. Finally the result is normalized by eliminating instances of `.` or `..`.

## Printing locations

val show_filename : string -> string

In -absname mode, return the absolute path for this filename. Otherwise, returns the filename unchanged.

val print_filename : Format formatter -> string -> unit

val print_loc : Format formatter -> t -> unit

val printLocs : Format formatter -> t list -> unit

val separate_new_message : Format formatter -> unit

module Doc :

sig

val separate_new_message : unit Format_doc.printer

val filename : string Format_doc.printer

val quoted_filename : string Format_doc.printer

val loc : Location.t Format_doc.printer

val locs : Location.t list Format_doc.printer

end

## TLEVEL-SPECIFIC LOCATION HIGHLIGHTING

val highlight_terminfo : Lexing.lexbuf -> Format formatter -> t list -> unit

## REPORTING ERRORS AND WARNINGS

### THE TYPE OF REPORTS AND REPORT PRINTERS

type msg = Format_doc.t loc

val msg : ?loc:t ->
('a, Format_doc.Formatter, unit, msg) format4 -> 'a

type report_type =

| Report_error

| Report_warning of string

| Report_warning_as_error of string

| Report_alert of string

| Report_alert_as_error of string
`val regexp_string : string -> regexp`

`Str.regexp_string` `s` returns a regular expression that matches exactly `s` and nothing else.

`val regexp_string_caseFold : string -> regexp`

`Str.regexp_string_caseFold` is similar to `Str.regexp_string` [31.1], but the regexp matches in a case-insensitive way.

## String matching and searching

`val string_match : regexp -> string -> int -> bool`

`string_match` `r s start` tests whether a substring of `s` that starts at position `start` matches the regular expression `r`. The first character of a string has position 0, as usual.

`val search_forward : regexp -> string -> int -> int`

`search_forward r s start` searches the string `s` for a substring matching the regular expression `r`. The search starts at position `start` and proceeds towards the end of the string. Return the position of the first character of the matched substring.

**Raises** `Not_found` if no substring matches.

`val search : regexp -> string -> int -> int`

`search backward r s last` searches the string `s` for a substring matching the regular expression `r`. The search first considers substrings that start at position `last` and proceeds towards the beginning of string. Return the position of the first character of the matched substring.

**Raises** `Not_found` if no substring matches.

`val string_partial_match : regexp -> string -> int -> bool`

Similar to `Str_string_match` [31.1], but also returns true if the argument `string` is a prefix of a string that matches. This includes the case of a true complete match.

`val matched_string : string -> string`

`matched_string` `s` returns the substring of `s` that was matched by the last call to one of the following matching or searching functions:

* `Str.String_match` [31.1]

* `Str.search_forward` [31.1]

* `Str.search` [31.1]

* `Str.String_partial_match` [31.1]

* `Str.global_substitute` [31.1]

* `Str.substitute_first` [31.1]

provided that none of the following functions was called in between:
```hkl
type report =
{
    kind : reportASY;
    main : msg ;
    sub : msg list ;
    footnote : Format_doc.t option ;
}

type report_printers =
{
    pp : report_printers -> Format formatter -> report -> unit ;
    pp_reportASY : report_printers ->
        report -> Format formatter -> reportASY -> unit ;
    pp_mainLoc : report_printers ->
        report -> Format formatter -> t -> unit ;
    pp_main_txt : report_printers ->
        report -> Format formatter -> Format_doc.t -> unit ;
    pp_sub : report_printers ->
        report -> Format formatter -> msg list -> unit ;
    pp_submsg : report_printers ->
        report -> Format formatter -> msg -> unit ;
    pp_submsgLoc : report_printers ->
        report -> Format formatter -> t -> unit ;
    pp_submsg_txt : report_printers ->
        report -> Format formatter -> Format_doc.t -> unit ;
}
```

A printer for reports, defined using open-recursion. The goal is to make it easy to define new printers by re-using code from existing ones.

## Report printers used in the compiler

```hkl
val batch_mode_printers : report_printers
val terminfo_t LEVELS : Lexing.lexbuf -> report_printers
val best_tLEVELS : unit -> report_printers

Detects the terminal capabilities and selects an adequate printer
```

## Printing a report

```hkl
val print_report : Format formatter -> report -> unit

Display an error or warning report.
```

```hkl
val report_printers : (unit -> report_printers) ref

Hook for redefining the printer of reports.
```

The hook is a `unit -> report_printers` and not simply a `report_printers`: this is useful so that it can detect the type of the output (a file, a terminal, ...) and select a printer accordingly.
val default_report_printers : unit -> report_printers

Original report printer for use in hooks.

## Reporting warnings

### Converting a Warnings.t into a report

val report_warning : t -> Warnings.t -> report option

report_warning loc w produces a report for the given warning w, or None if the warning is not to be printed.

val warning_reporter : (t -> Warnings.t -> report option) ref

Hook for intercepting warnings.

val default_warning_reporter : t -> Warnings.t -> report option

Original warning reporter for use in hooks.

## Printing warnings

val formatter_for_warnings : Format formatter ref

val print_warning : t -> Format formatter -> Warnings.t -> unit

Prints a warning. This is simply the composition of report_warning and print_report.

val prerr_warning : t -> Warnings.t -> unit

Same as print_warning, but uses !formatter_for_warnings as output formatter.

## Reporting alerts

### Converting an Alert.t into a report

val report_alert : t -> Warnings.alert -> report option

report_alert loc w produces a report for the given alert w, or None if the alert is not to be printed.

val alert_reporter : (t -> Warnings.alert -> report option) ref

Hook for intercepting alerts.

val default_alert_reporter : t -> Warnings.alert -> report option

Original alert reporter for use in hooks.
* `Invalid_argument` if there are fewer than *n* groups in the regular expression.

`val group_end : int -> int`

`group_end` *n* returns the position of the character following the last character of substring that was matched by the *n*th group of the regular expression that was matched by the last call to a matching or searching function (see `Str.matched_string`[31.1] for details).

**Raises**

* `Not_found` if the *n*th group of the regular expression was not matched.

* `Invalid_argument` if there are fewer than *n* groups in the regular expression.

## Replacement

`val global_replace : regexp -> string -> string -> string`

`global_replace regexp templ s` returns a string identical to *s*, except that all substrings of *s* that match `regexp` have been replaced by `templ`. The replacement template `templ` can contain `\1`, `\2`, etc; these sequences will be replaced by the text matched by the corresponding group in the regular expression. `\0` stands for the text matched by the whole regular expression.

`val replace_first : regexp -> string -> string -> string`

Same as `Str.global_replace`[31.1], except that only the first substring matching the regular expression is replaced.

`val global_substitute : regexp -> (string -> string) -> string -> string`

`global_substitute regexp subst s` returns a string identical to *s*, except that all substrings of *s* that match `regexp` have been replaced by the result of function `subst`. The function `subst` is called once for each matching substring, and receives *s* (the whole text) as argument.

`val substitute_first : regexp -> (string -> string) -> string -> string`

Same as `Str.global_substitute`[31.1], except that only the first substring matching the regular expression is replaced.

`val replace_matchd : string -> string -> string`

`replace_matchd repl s` returns the replacement text `repl` in which `\1`, `\2`, etc. have been replaced by the text matched by the corresponding groups in the regular expression that was matched by the last call to a matching or searching function (see `Str.matched_string`[31.1] for details). *s* must be the same string that was passed to the matching or searching function.
## Printing alerts

val print_alert : t -> Format formatter -> Warnings.alert -> unit
Prints an alert. This is simply the composition of report_alert and print_report.

val prerr_alert : t -> Warnings.alert -> unit
Same as print Alert, but uses !formatter_for_warnings as output formatter.

val deprecated : ?def:t -> ?use:t -> t -> string -> unit
Prints a deprecation alert.

val alert : ?def:t ->
?use:t -> kind: string -> t -> string -> unit
Prints an arbitrary alert.

val auto_include_alert : string -> unit
Prints an alert that -I +lib has been automatically added to the load path

val deprecated_script Alert : string -> unit
deprecated_script Alert command prints an alert that command foo has been deprecated
in favour of command ./foo

## Reporting errors

type error = report
An error is a report which report\_kind must be Report\_error.

type delayed\_msg = unit -> Format\_doc.t option

val error :
?loc:t ->
?sub:msg list ->
?footnote:delayed\_msg -> string -> error

val errorf :
?loc:t ->
?sub:msg list ->
?footnote:delayed\_msg ->
('a, Format\_doc formatter, unit, error) format4 -> 'a

val aligned\_error\_hint :
?loc:t ->
?sub:msg list ->
?footnote:delayed\_msg ->
('a, Format\_doc formatter, unit, Format\_doc.t option -> error)
format4 -> 'a
## Splitting

**val split : regexp -> string -> string list**

`split` `r` `s` splits `s` into substrings, taking as delimiters the substrings that match `r`, and returns the list of substrings. For instance, `split (regexp "[ \t]+") s` splits `s` into blank-separated words. An occurrence of the delimiter at the beginning or at the end of the string is ignored.

**val bounded_split : regexp -> string -> int -> string list**

Same as `Str.split[31.1]`, but splits into at most `n` substrings, where `n` is the extra integer parameter.

**val split_delim : regexp -> string -> string list**

Same as `Str.split[31.1]` but occurrences of the delimiter at the beginning and at the end of the string are recognized and returned as empty strings in the result. For instance, `split_delim` (`regexp " " " abc "` returns `[]"; "abc"; ""`], while `split` with the same arguments returns `"abc"`.

**val bounded_split_delim : regexp -> string -> int -> string list**

Same as `Str.bounded_split[31.1]`, but occurrences of the delimiter at the beginning and at the end of the string are recognized and returned as empty strings in the result.

**type split_result =**

| Text of string

| Delim of string

**val full_split : regexp -> string -> split_result list**

Same as `Str.split_delim[31.1]`, but returns the delimiters as well as the substrings contained between delimiters. The former are tagged `Delim` in the result list; the latter are tagged `Text`. For instance, `full_split` (`regexp "[{}]" "{ab}"` returns `Delim "{"; Text "ab"; Delim "}"`].

**val bounded_full_split : regexp -> string -> int -> split_result list**

Same as `Str.bounded_split_delim[31.1]`, but returns the delimiters as well as the substrings contained between delimiters. The former are tagged `Delim` in the result list; the latter are tagged `Text`.

## Extracting substrings

**val string_before : string -> int -> string**

`string_before` `s` `n` returns the substring of all characters of `s` that precede position `n` (excluding the character at position `n`).

**val string_after : string -> int -> string**
`aligned_error_hint` ?loc ?sub ?footnote fmt ... `aligned_hint` produces an error report where the potential `aligned_hint` message has been aligned with the main error message before being added to the list of submessages.

```hcl
val error_of_printers : 
    ?loc:t ->
    ?sub:msg list ->
    ?footnote:delayed msg ->
    (Format_doc.Formatter -> 'a -> unit) -> 'a -> error
```

```hcl
val error_of_printers_file : 
    (Format_doc.Formatter -> 'a -> unit) -> 'a -> error
```

## Automatically reporting errors for raised exceptions

```hcl
val register_error_of_exn : (exn -> error option) -> unit
```
Each compiler module which defines a custom type of exception which can surface as a user-visible error should register a "printer" for this exception using `register_error_of_exn`. The result of the printer is an error value containing a location, a message, and optionally sub-messages (each of them being located as well).

```hcl
val error_of_exn : exn -> [ `Already_displayed | `Ok of error ] option
exception Error of error
```

Raising `Error` e signals an error `e`; the exception will be caught and the error will be printed.

### exception Already_displayed_error

Raising `Already_displayed_error` signals an error which has already been printed. The exception will be caught, but nothing will be printed

```hcl
val raise_error : 
    ?loc:t ->
    ?sub:msg list ->
    ?footnote:delayed msg ->
    ('a, Format_doc.Formatter, unit, 'b) format4 -> 'a
```

```hcl
val report_exception : Format formatter -> exn -> unit
```
Reraise the exception if it is unknown.

## 30.4 Module Longident : Long identifiers, used in parsetree.

**Warning:** this module is unstable and part of compiler-libs[30].

To print a longident, see `Pprintast.longident`[30.7], using `Format.asprintf`[29.23] to convert to a string.

`type t =`
`string_after` s n returns the substring of all characters of s that follow position n (including the character at position n).

`val first_chars : string -> int -> string`

`first_chars` s n returns the first n characters of s. This is the same function as `Str_string_before[31.1]`.

`val last_chars : string -> int -> string`

`last_chars` s n returns the last n characters of s.
```
| Lident of string
| Ldot of t Location.loc * string Location.loc
| Lapply of t Location.loc * t Location.loc

val same : t -> t -> bool

same t t' compares the longids t and t' without taking locations into account.
```

```
val flatten : t -> string list
val unflatten : string list -> t option
```

For a non-empty list `l`, `unflatten l` is Some lid where `lid` is the long identifier created by concatenating the elements of `l` with `Ldot`. `unflatten []` is None.

```
val last : t -> string
val parse : string -> t
```

*Deprecated.* this function may misparse its input, use "Parse.longident" or "Longident.unflatten"This function is broken on identifiers that are not just "Word.Word.word"; for example, it returns incorrect results on infix operators and extended module paths.

If you want to generate long identifiers that are a list of dot-separated identifiers, the function `Longident.unflatten[30.4]` is safer and faster. `Longident.unflatten[30.4]` is available since OCaml 4.06.0.

If you want to parse any identifier correctly, use the long-identifiers functions from the `Parse[30.5]` module, in particular `Parse.longident[30.5]`. They are available since OCaml 4.11, and also provide proper input-location support.

## 30.5 Module Parse : Entry points in the parser

**Warning:** this module is unstable and part of compiler-libs[30].

```
val implementation : Lexing.lexbuf -> Parsetree structure
val interface : Lexing.lexbuf -> Parsetree signature
val toplevel_phrase : Lexing.lexbuf -> Parsetree toplevel_phrase
val use_file : Lexing.lexbuf -> Parsetree toplevel_phrase list
val core_type : Lexing.lexbuf -> Parsetree core_type
val expression : Lexing.lexbuf -> Parsetree expression
val pattern : Lexing.lexbuf -> Parsetree pattern
val module_type : Lexing.lexbuf -> Parsetree module_type
val module_expr : Lexing.lexbuf -> Parsetree module_expr

The functions below can be used to parse Longident safely.

val longident : Lexing.lexbuf -> Longident.t
```
The function `longident` is guaranteed to parse all subclasses of `Longident.t`[30.4] used in OCaml: values, constructors, simple or extended module paths, and types or module types.

However, this function accepts inputs which are not accepted by the compiler, because they combine functor applications and infix operators. In valid OCaml syntax, only value-level identifiers may end with infix operators `Foo.( + )`. Moreover, in value-level identifiers the module path `Foo` must be simple (`M.N` rather than `F(X)`: functor applications may only appear in type-level identifiers. As a consequence, a path such as `F(X).( + )` is not a valid OCaml identifier; but it is accepted by this function.

The next functions are specialized to a subclass of `Longident.t`[30.4]

`val val_ident : Lexing.lexbuf -> Longident.t`

This function parses a syntactically valid path for a value. For instance, `x`, `M.x`, and `( + )` are valid. Contrarily, `M.A`, `F(X).x`, and `true` are rejected.

Longident for OCaml's value cannot contain functor application. The last component of the `Longident.t`[30.4] is not capitalized, but can be an operator `A.Path.To.(%.%.(..)<-)`

`val constr_ident : Lexing.lexbuf -> Longident.t`

This function parses a syntactically valid path for a variant constructor. For instance, `A`, `M.A` and `M.(:)` are valid, but both `M.a` and `F(X).A` are rejected.

Longident for OCaml's variant constructors cannot contain functor application. The last component of the `Longident.t`[30.4] is capitalized, or it may be one the special constructors: `true`, `false`, `()`, `[]`, `::`. Among those special constructors, only `::` can be prefixed by a module path (`A.B.C.(:)`).

`val simple_module_path : Lexing.lexbuf -> Longident.t`

This function parses a syntactically valid path for a module. For instance, `A`, and `M.A` are valid, but both `M.a` and `F(X).A` are rejected.

Longident for OCaml's module cannot contain functor application. The last component of the `Longident.t`[30.4] is capitalized.

`val extended_module_path : Lexing.lexbuf -> Longident.t`

This function parses syntactically valid path for an extended module. For instance, `A.B` and `F(A).B` are valid. Contrarily, `(.%)` or `[]` are both rejected.

The last component of the `Longident.t`[30.4] is capitalized.

`val type_ident : Lexing.lexbuf -> Longident.t`

This function parses syntactically valid path for a type or a module type. For instance, `A`, `t`, `M.t` and `F(X).t` are valid. Contrarily, `(.%)` or `[]` are both rejected.

In path for type and module types, only operators and special constructors are rejected.
Chapter 32

The runtime_events library

The `runtime_events` library provides an API for consuming runtime tracing and metrics information from the runtime. See chapter 25 for more information.

Programs that use `runtime_events` must be linked as follows:

```
ocamlc -I +runtime_events other options unix.cma runtime_events.cma other files
ocamlopt -I +runtime_events other options unix.cmxa runtime_events.cmxa other files
```

Compilation units that use the `runtime_events` library must also be compiled with the `-I +runtime_events` option (see chapter 13).

## 32.1 Module Runtime_events: Runtime events - ring buffer-based runtime tracing

This module enables users to enable and subscribe to tracing events from the Garbage Collector and other parts of the OCaml runtime. This can be useful for diagnostic or performance monitoring purposes. This module can be used to subscribe to events for the current process or external processes asynchronously.

When enabled (either via setting the `OCAML_RUNTIME EVENTS START` environment variable or calling `Runtime_events.start`) a file with the pid of the process and extension `.events` will be created. By default this is in the current directory but can be over-ridden by the `OCAML_RUNTIME EVENTS DIR` environment variable. Each domain maintains its own ring buffer in a section of the larger file into which it emits events.

There is additionally a set of C APIs in `runtime_events.h` that can enable zero-impact monitoring of the current process or bindings for other languages.

The runtime events system's behaviour can be controlled by the following environment variables:

* `OCAML_RUNTIME EVENTS START` if set will cause the runtime events system to be started as part of the OCaml runtime initialization.

* `OCAML_RUNTIME EVENTS DIR` sets the directory where the runtime events ring buffers will be located. If not present the program's working directory will be used.
30.6 Module Parsetree : Abstract syntax tree produced by parsing

Warning: this module is unstable and part of compiler-libs[30].

type constant =
{
    pconst_desc : constant_desc ;
    pconst_loc : Location.t ;
}

type constant_desc =
| Pconst_integer of string * char option
    Integer constants such as 3 31 3L 3n.

Suffixes [g-z] [G-Z] are accepted by the parser. Suffixes except 'l', 'L' and 'n' are rejected by the typechecker

| Pconst_char of char
    Character such as 'c'.

| Pconst_string of string * Location.t * string option
    Constant string such as "constant" or {delim|other constant|delim}.

The location span the content of the string, without the delimiters.

| Pconst_float of string * char option
Float constant such as 3.4, 2e5 or 1.4e-4.

Suffixes g-zG-Z are accepted by the parser. Suffixes are rejected by the typechecker.

type location_stack = Location.t list

Extension points

type attribute =
{
    attr_name : string Asttypes.loc ;
    attr_payload : payload ;
    attr_loc : Location.t ;
}

Attributes such as [@id ARG] and [@@id ARG].

Metadata containers passed around within the AST. The compiler ignores unknown
attributes.

type extension = string Asttypes.loc * payload
Extension points such as [%id ARG] and [%%id ARG].

Sub-language placeholder – rejected by the typechecker.

type attributes = attribute list

type payload =

| PStr of structure

| PSig of signature
* OCAML_RUNTIME EVENTS_PRESERVE if set will prevent the OCaml runtime from removing its ring buffers when it terminates. This can help if monitoring very short running programs.

type runtime_counter =

| EV_C_FORCE_MINOR_ALLOC_SMALL

| EV_C_FORCE_MINOR_MAKE_VECT

| EV_C_FORCE_MINOR_SET_MINOR_heap_SIZE

| EV_C_FORCE_MINOR_MEMPROF

| EV_C_MINOR_PROMOTED

| EV_C_MINOR_ALLOCATED

| EV_C_REQUEST_MAJOR_ALLOC_SHR

| EV_C_REQUEST_MAJOR_ADJUST_GC_SPEED

| EV_C_REQUEST_MINOR_REALLOC_REF_TABLE

| EV_C_REQUEST_MINOR_REALLOC_EPHE_REF_TABLE

| EV_C_REQUEST_MINOR_REALLOC_CUSTOM_TABLE

| EV_C_MAJOR_heap_POOL_words

Total words in a Domain's major heap pools. This is the sum of unallocated and live words in each pool.

Since: 5.1

| EV_C_MAJOR_heap_POOL_LIVE_words

Current live words in a Domain's major heap pools.

Since: 5.1

| EV_C_MAJOR_heap_LARGE_words

Total words of a Domain's major heap large allocations. A large allocation is an allocation larger than the largest sized pool.

Since: 5.1

| EV_C_MAJOR_heap_POOL_FRAG_words

Words in a Domain's major heap pools lost to fragmentation. This is due to there not being a pool with the exact size of an allocation and a larger sized pool needing to be used.

Since: 5.1

| EV_C_MAJOR_heap_POOL_LIVE_BLOCKs

Live blocks of a Domain's major heap pools.

Since: 5.1

| EV_C_MAJOR_heap_LARGE_BLOCKs

Live blocks of a Domain's major heap large allocations.

Since: 5.1
* : SIG in an attribute or an extension point

* | PTyp of core_type

* : T in an attribute or an extension point

* | PPat of pattern * expression option

* ? P or ? P when E, in an attribute or an extension point

## Core language

### Type expressions

```c
type core_type =
{
    ptyp_desc : core_type_desc ;
    ptyp_loc : Location.t ;
    ptyp_loc_stack : location_stack ;
    ptyp_attributes : attributes ;

    ... [@id1] [@id2]
}

type core_type_desc =
{
    Ptyp_any

    -

    | Ptyp_var of string

    A type variable such as 'a

    | PtypArrow of Asttypes.arg_label * core_type * core_type

    Ptyparrow.lbl, T1, T2) represents:

    • T1 -> T2 when lbl is Nolabel[??],
    • ~1:T1 -> T2 when lbl is Labelled[??],
    • ?1:T1 -> T2 when lbl is Optional[??].

    | Ptyp_tuple of (string option * core_type) list

    Ptyp_tuple(t1) represents a product type:

    • T1 * ... * Tn when t1 is (None, T1); ...; (None, Tn)
    • L1:T1 * ... * Ln:Tn when t1 is (Some L1, T1); ...; (Some Ln, Tn)
    • A mix, e.g., L1:T1 * T2 when t1 is (Some L1, T1); (None, T2)

    Invariant: n >= 2.
```

* | Ptyp_constr of Longident.t Asttypes.loc * core_type list
  Ptyp_constr(lident, l) represents:
  * tconstr when l=[],
The type for counter events emitted by the runtime

```
type runtime_phase =
| EV_EXPLICIT_GC_SET
| EV_EXPLICIT_GC_STAT
| EV_EXPLICIT_GC_MINOR
| EV_EXPLICIT_GC_MAJOR
| EV_EXPLICIT_GC_FULL_MAJOR
| EV_EXPLICIT_GC_COMPACT
| EV_MAJOR
| EV_MAJOR_SWEEP
| EV_MAJOR_mark_roots
| EV_MAJOR_mark
| EV_MINOR
| EV_MINOR_LOCAL_roots
| EV_MINOR_FINALIZED
| EV_EXPLICIT_GC_MAJOR_SLICE
| EV_FINALISE_UPDATE_FIRST
| EV_FINALISE_UPDATE_LAST
| EV_INTERRUPT remoTe
| EV_MAJOR_EPHE_mark
| EV_MAJOR_EPHE_SWEEP
| EV_MAJOR_finished_marking
| EV_MAJOR_GCots_CYCLE乞 domains
| EV_MAJOR_GCPHASE_CHANGE
| EV_MAJOR_GC_STW
| EV_MAJOR_mark_opportunistic
| EV_MAJOR_SLICE
| EV_MAJOR_finishedots_CYCLE
| EV_MINOR_CLEAR
| EV_MINOR_finalizers_0ldify
| EV_MINOR_GLOBAL_roots
| EV_MINOR Leaves_BARRIER
| EV_STW_api_bARRIER
| EV_STWectoRDER
| EV_MAJOR_finished_swEEPing
| EV_MINOR_finalizers_admin
| EV_MINOR_REMEMBERED_SET
| EV_MINOR_REMEMBERED_SET_PROMOTE
| EV_MINOR_LOCAL_roots_PROMOTE
| EV乞 domain condition_Wait
| EV乞 domain_resize_heap_reserveATion
```

The type for span events emitted by the runtime
* `T tconstr` when `l=[T]`,

* `(T1, ..., Tn) tconstr` when `l=[T1; ... ; Tn]`.

| `Ptyp_object` of `object_field` list * `Asttypes.closed_flag`
  `Ptyp_object([ l1:T1; ...; ln:Tn ], flag)` represents:

* `< l1:T1; ...; ln:Tn >` when flag is Closed[??],

* `< l1:T1; ...; ln:Tn; .. >` when flag is Open[??].

| `Ptyp_class` of `Longident.t` `Asttypes.loc` * `core_type` list
  `Ptyp_class(tconstr, l)` represents:

* `#tconstr` when `l=[]`,

* `T #tconstr` when `l=[T]`,

* `(T1, ..., Tn) #tconstr` when `l=[T1; ... ; Tn]`.

| `Ptyp_alias` of `core_type` * `string` `Asttypes.loc`
  `T` as `'a`.

| `Ptypvariant` of `row_field` list * `Asttypes.closed_flag` * `Asttypes.label` list option
  `PtypVariant([`A;`B`], flag, labels) represents:

* `[ `A` | `B` ] when flag is Closed[??], and labels is None,

* `[> `A` | `B` ] when flag is Open[??], and labels is None,

* `[< `A` | `B` ] when flag is Closed[??], and labels is Some [],

* `[< `A` | `B` > `X` `Y` ] when flag is Closed[??], and labels is Some `[

| `Ptyp_pol` of `string` `Asttypes.loc` list * `core_type`
  `'a1 ... 'an. T`

Can only appear in the following context:

* As the `Parsetree.core_type[30.6]` of a `Ppat_constraint[??]`
  node corresponding to a constraint on a let-binding:

let x : 'a1 ... 'an. T = e ...

* Under `Cfk_virtual[??]` for methods (not values).

* As the `Parsetree.core_type[30.6]` of a `Pctf_method[??]` node.

* As the `Parsetree.core_type[30.6]` of a `Pexp_pol[??]` node.

* As the `pld_type[??]` field of a `Parsetree.label labels` [30.6].

* As a `Parsetree.core_type[30.6]` of a `Ptyp_object[??]` node.
```hcl
type lifecycle =
  | EV habITRg_sTART
  | EV habITRg_stOP
  | EV habITRg_pAUSe
  | EV habITRg_rESUme
  | EV_FoRK_PArENT
  | EV_FoRK_ChiLd
  | EV_DOMAIN_SPAWN
  | EV_DOMAIN_TeRMinATE
```

Lifecycle events for the ring itself

```hcl
val lifecycle_name : lifecycle -> string
  Return a string representation of a given lifecycle event type
```

```hcl
val runtime_phase_name : runtime_phase -> string
  Return a string representation of a given runtime phase event type
```

```hcl
val runtime_counter_name : runtime_counter -> string
  Return a string representation of a given runtime counter type
```

```hcl
type cursor
  Type of the cursor used when consuming
```

```hcl
module Timestamp :
  sig
    type t
    Type for the int64 timestamp to allow for future changes
  val to_int64 : t -> int64
  end
```

```hcl
module Type :
  sig
    type 'a t
    The type for a user event content type
  val unit : unit t
```

An event that has no data associated with it

```hcl
type span =
  | Begin
  | End
  val span : span t
```
* As the `pval_type[??]` field of a `Parsetree.value_description[30.6]`.

| Ptyp_package of package_type
  (module S).

| Ptyp_open of Longident.t Asttypes.loc * core_type
  M.(T)

| Ptyp_extension of extension
  [%id].

type package_type =
{
  ppt_path : Longident.t Asttypes.loc ;
  ppt_cstrs : (Longident.t Asttypes.loc * core_type) list ;
  ppt_loc : Location.t ;
  ppt_attrs : attributes ;
}

As `Parsetree/package_type[30.6]` typed values:

* `{ppt_path: S; ppt_cstrs: []}` represents `(module S)`,

* `{ppt_path: S; ppt_cstrs: [(t1, T1); ...; (tn, Tn)]}` represents `(module S`
  with type `t1 = T1` and `...` and `tn = Tn`).

type row_field =
{
  prf_desc : row_field_desc ;
  prf_loc : Location.t ;
  prf_attributes : attributes ;
}

type row_field_desc =
| Rtag(`A`, b, l) represents:

* `A` when `b` is true and `l` is [],

* `A` of `T` when `b` is false and `l` is `[T],`

* `A` of `T1` & ... & `Tn` when `b` is false and `l` is `[T1;...Tn],`

* `A` of `& T1` & ... & `Tn` when `b` is true and `l` is `[T1;...Tn].`

* The `bool` field is true if the tag contains a constant (empty) constructor.

* `&` occurs when several types are used for the same constructor (see 4.2 in the manual).

| Rinherit of core_type
  [ | t ]
An event that has a beginning and an end

```ksharp
val int : int t
```

An event containing an integer value

```ksharp
val register :
    encode: (bytes -> 'a -> int) ->
    decode: (bytes -> int -> 'a) -> 'a t
```

Registers a custom type by providing an encoder and a decoder. The encoder writes the value in the provided buffer and returns the number of bytes written. The decoder gets a slice of the buffer of specified length, and returns the decoded value.

The maximum value length is 1024 bytes.

```ksharp
end
```

```ksharp
module User :
```

```ksharp
sig
```

User events is a way for libraries to provide runtime events that can be consumed by other tools. These events can carry known data types or custom values. The current maximum number of user events is 8192.

```ksharp
type tag = ..
```

The type for a user event tag. Tags are used to discriminate between user events of the same type

```ksharp
type 'value t
```

The type for a user event. User events describe their tag, carried data type and an unique string-based name

```ksharp
val register : string ->
    tag ->
    'value Runtime_events.Type.t -> 'value t
```

register name tag ty registers a new event with an unique name, carrying a tag and values of type ty

```ksharp
val write : 'value t -> 'value -> unit
```

write t v records a new event t with value v

```ksharp
val name : 'a t -> string
```

name t is the uniquely identifying name of event t

```ksharp
val tag : 'a t -> tag
```
```python
type object_field =
{ pof_desc : object_field_desc ;
  pof_loc : Location.t ;
  pof_attributes : attributes ;
}

type object_field_desc =
| Otag of Asttypes.label Asttypes.loc * core_type
| Oinherit of core_type
```

## Patterns

```python
type pattern =
{ ppat_desc : pattern_desc ;
  ppat_loc : Location.t ;
  ppat_loc_stack : location_stack ;
  ppat_attributes : attributes ;
  ... [@id1] [@id2]
}

type pattern_desc =
| Ppat_any
  The pattern _.
| Ppat_var of string Asttypes.loc
  A variable pattern such as x
| Ppat_alias of pattern * string Asttypes.loc
  An alias pattern such as P as 'a
| PpatConstant of constant
  Patterns such as 1, 'a', "true", 1.0, 1l, 1L, 1n
| Ppat_interval of constant * constant
  Patterns such as 'a'..'z'.

Other forms of interval are recognized by the parser but rejected by the type-checker.

| Ppat_tuple of (string option * pattern) list * Asttypes=closed_flag
  Ppat_tuple(pl, Closed) represents
    (P1, ..., Pn) when pl is (None, P1); ...; (None, Pn)
    (~L1:P1, ..., ~Ln:Pn) when pl is (Some L1, P1); ...; (Some Ln, Pn)
    A mix, e.g. (~L1:P1, P2) when pl is (Some L1, P1); (None, P2)

Ppat_tuple(pl, Open) is similar, but indicates the pattern additionally ends in a ...

Invariant:
    If Closed, n >= 2.
```
`tag t` is the associated tag of event `t`, when it is known. An event can be unknown if it was not registered in the consumer program.

end

module Callbacks :

sig

type t

Type of callbacks

val create :

?runtime_begin: (int ->
    Runtime_events.Timestamp.t ->
    Runtime_eventsruntime_phase -> unit) ->

?runtime_end: (int ->
    Runtime_events.Timestamp.t ->
    Runtime_events runtime_phase -> unit) ->

?runtime_counter: (int ->
    Runtime_events.Timestamp.t ->
    Runtime_events runtime_counter -> int -> unit) ->

?alloc: (int -> Runtime_events.Timestamp.t -> int array -> unit) ->

?lifecycle: (int ->
    Runtime_events.Timestamp.t ->
    Runtime_events.lifecycle -> int option -> unit) ->

?lost_events: (int -> int -> unit) -> unit -> t

Create a **Callback** that optionally subscribes to one or more runtime events. The first int supplied to callbacks is the ring buffer index. Each domain owns a single ring buffer for the duration of the domain's existence. After a domain terminates, a newly spawned domain may take ownership of the ring buffer. A `runtime_begin` callback is called when the runtime enters a new phase (e.g a `runtime_begin` with `EV_MINOR` is called at the start of a minor GC). A `runtime_end` callback is called when the runtime leaves a certain phase. The `runtime_counter` callback is called when a counter is emitted by the runtime. `lifecycle` callbacks are called when the ring undergoes a change in lifecycle and a consumer may need to respond. `alloc` callbacks are currently only called on the instrumented runtime. `lost_events` callbacks are called if the consumer code detects some unconsumed events have been overwritten.

val add_user_event :
'a Runtime_events.Type.t ->
(int -> Runtime_events.Timestamp.t -> 'a Runtime_events.User.t -> 'a -> unit) ->
t -> t

`add_user_event ty callback t` extends `t` to additionally subscribe to user events of type `ty`. When such an event happens, `callback` is called with the corresponding event and payload.
* If `Open`, `n >= 1`.

| `Ppat_construct` of `Longident.t` `Asttypes.loc`

* (string `Asttypes.loc` list * pattern) option

`Ppat_construct(C, args)` represents:

* `C` when `args` is `None`,

* `C P` when `args` is `Some ([], P)`

* `C` (`P1`, ..., `Pn`) when `args` is `Some ([], Ppat_tuple [P1; ...; Pn])`

* `C` (type `a b`) `P` when `args` is `Some ([a; b], P)`

| `Ppat_variant` of `Asttypes.label` * pattern option

`Ppat_variant(`A`, pat)` represents:

* `A` when `pat` is `None`,

* `A P` when `pat` is `Some P`

| `Ppat_record` of (`Longident.t` `Asttypes.loc` * pattern) list * `Asttypes closed flag`

`Ppat_record([((l1, P1); ...; (ln, Pn)], flag)` represents:

* `{ l1=P1; ...; ln=Pn }` when `flag` is `Closed[??]`

* `{ l1=P1; ...; ln=Pn; _ }` when `flag` is `Open[??]`

Invariant: `n > 0`

| `Ppat_array` of pattern list

Pattern `[| P1; ...; Pn |]`

| `Ppat_or` of pattern * pattern

Pattern `P1 | P2`

| `Ppat_constraint` of pattern * `core_type`

Pattern (`P`: `T`)

| `Ppat_type` of `Longident.t` `Asttypes.loc`

Pattern `#tconst`

| `Ppat_lazy` of pattern

Pattern `lazy P`

| `Ppat_unpack` of string option `Asttypes.loc`

`Ppat_unpack(s)` represents:

* (`module P`) when `s` is `Some "P"`

* (`module _`) when `s` is `None`

Note: (`module P`: `S`) is represented as `Ppat_constraint(Ppat_unpack(Some "P"), Ptyp_package S)`
end

val start : unit -> unit

start () will start the collection of events in the runtime if not already started.

Events can be consumed by creating a cursor with `create_cursor` and providing a set of callbacks to be called for each type of event.

val pause : unit -> unit

pause () will pause the collection of events in the runtime. Traces are collected if the program has called `Runtime_events.start()` or the `OCAML_RUNTIME_events_START` environment variable has been set.

val resume : unit -> unit

resume () will resume the collection of events in the runtime. Traces are collected if the program has called `Runtime_events.start()` or the `OCAML_RUNTIME_events_START` environment variable has been set.

val create_cursor : (string * int) option -> cursor

`create_cursor path_pid` creates a cursor to read from an `runtime_events`. Cursors can be created for `runtime_events` in and out of process. A `runtime_events` ring-buffer may have multiple cursors reading from it at any point in time and a program may have multiple cursors open concurrently (for example if multiple consumers want different sets of events). If `path_pid` is `None` then a cursor is created for the current process. Otherwise the pair contains a string `path` to the directory that contains the `pid.events` file and `int pid` for the `runtime_events` of an external process to monitor.

val free_cursor : cursor -> unit

Free a previously created `runtime_events` cursor

val read_poll : cursor -> Callbacks.t -> int option -> int

`read_poll cursor callbacks max_option` calls the corresponding functions on `s` for up to `max_option` events read off `cursor`'s `runtime_events` and returns the number of events read.
| Ppat_exception of pattern

Pattern exception P

| Ppat_effect of pattern * pattern

| Ppat_extensions of extension

Pattern [%id]

| Ppat_open of Longident.t Asttypes.loc * pattern

Pattern M.(P)

Value expressions

type expression =

{ pexp_desc : expression_desc ;
    pexp_loc : Location.t ;
    pexp_loc_stack : location_stack ;
    pexp_attributes : attributes ;
    ... [@id1] [@id2]

}

type expression_desc =

| Pexp_ident of Longident.t Asttypes.loc

Identifiers such as x and M.x

| PexpConstant of constant

Expressions constant such as 1, 'a', "true", 1.0, 11, 1L, 1n

| Pexp_let of Asttypes.rec_flag * value physlist list * expression

Pexp_let flag, [(P1,E1) ; ... ; (Pn,En)], E) represents:

• let P1 = E1 and ... and Pn = EN in E when flag is Nonrecursive[??],

• let rec P1 = E1 and ... and Pn = EN in E when flag is Recursive[??].

| Pexp_function of function_param list * type_constraint option

* function_body

Pexp_function ([P1; ...; Pn], C, body) represents any construct involving fun
or function, including:

• fun P1 ... Pn -> E when body = Pfunction_body E

• fun P1 ... Pn -> function p1 -> e1 | ... | pm -> em when body =
  Pfunction cases [ p1 -> e1; ...; pm -> em ]

C represents a type constraint or coercion placed immediately before the arrow, e.g. fun
P1 ... Pn : ty -> ... when C = Some (Pconstraint ty).

A function must have parameters: in Pexp_function (params, ..., body), if params
does not contain a Pparam_val ..., body must be Pfunction cases _.
| Pexp_apply of expression * (Asttypes.arg_label * expression) list
  Pexp_apply(E0, [(l1, E1); ...; (ln, En)]) represents E0 ~l1:E1 ...
  ~ln:En

  li can be Nolabel[??] (non labeled argument), Labelled[??] (labelled arguments) or
  Optional[??] (optional argument).

  Invariant: n > 0

| Pexp_match of expression * case list
  match E0 with P1 -> E1 | ... | Pn -> En

| Pexp_ttry of expression * case list
  try E0 with P1 -> E1 | ... | Pn -> En

| Pexp_tuple of (string option * expression) list
  Pexp_tuple(el) represents
    * (E1, ..., En) when el is (None, E1); ...; (None, En)
    * (~L1:E1, ..., ~Ln:En) when el is (Some L1, E1); ...; (Some Ln, En)
    * A mix, e.g., (~L1:E1, E2) when el is (Some L1, E1); (None, E2)
  Invariant: n >= 2

| Pexp_construct of Longident.t Asttypes.loc * expression option
  Pexp_construct(C, exp) represents:

* C when exp is None,

* C E when exp is Some E,

* C (E1, ..., En) when exp is Some (Pexp_tuple[E1;...;En])

| Pexp variant of Asttypes.label * expression option
  Pexp variant(`A, exp) represents

* `A when exp is None

* `A E when exp is Some E

| Pexp_record of (Longident.t Asttypes.loc * expression) list
  * expression option
  Pexp_record([((l1,P1); ...; (ln,Pn])], exp0) represents

* `{ l1=P1; ...; ln=Pn }` when exp0 is None

* `{ E0 with l1=P1; ...; ln=Pn }` when exp0 is Some E0

Invariant: n > 0

| Pexp_field of expression * Longident.t Asttypes.loc
  E.1
Chapter 33

The threads library

The threads library allows concurrent programming in OCaml. It provides multiple threads of
control (also called lightweight processes) that execute concurrently in the same memory space.
Threads communicate by in-place modification of shared data structures, or by sending and receiving
data on communication channels.

The threads library is implemented on top of the threading facilities provided by the operating
system: POSIX 1003.1c threads for Linux, MacOS, and other Unix-like systems; Win32 threads for
Windows. Only one thread at a time is allowed to run OCaml code on a particular domain 9.5.1.
Hence, opportunities for parallelism are limited to the parts of the program that run system or
C library code. However, threads provide concurrency and can be used to structure programs as
several communicating processes. Threads also efficiently support concurrent, overlapping I/O
operations.

Programs that use threads must be linked as follows:

ocamlc -I +unix -I +threads other options unix.cma threads.cma other files

ocamlopt -I +unix -I +threads other options unix.cmxa threads.cmxa other files

Compilation units that use the threads library must also be compiled with the -I +threads
option (see chapter 13).

33.1 Module Thread : Lightweight threads for Posix 1003.1c and Win32.

type t

The type of thread handles.

Thread creation and termination

val create : ('a -> 'b) -> 'a -> t

Thread.create funct arg creates a new thread of control, in which the function application
funct arg is executed concurrently with the other threads of the domain. The application of
| Pexp_setfield of expression * Longident.t Asttypes.loc * expression
  E1.1 <- E2

| Pexp_array of expression list
  [ E1; ...; En ]

| Pexp_ifthenelse of expression * expression * expression option
  if E1 then E2 else E3

| Pexp_sequence of expression * expression
  E1; E2

| Pexpwhile of expression * expression
  while E1 do E2 done

| Pexp_for of pattern * expression * expression

* Asttypes direction_flag * expression
  Pexp_for(i, E1, E2, direction, E3) represents:

• for i = E1 to E2 do E3 done when direction is Upto[??]

• for i = E1 downto E2 do E3 done when direction is Downto[??]

| Pexp_constraint of expression * core_type
  (E : T)

| Pexp_coerce of expression * core_type option * core_type
  Pexp_coerce(E, from, T) represents

• (E :> T) when from is None,

• (E : TO :> T) when from is Some TO.

| Pexp_send of expression * Asttypes.label Asttypes.loc
  E # m

| Pexp_new of Longident.t Asttypes.loc
  new M.c

| Pexp_setinstvar of Asttypes.label Asttypes.loc * expression
  x <- 2

| Pexp_override of (Asttypes.label Asttypes.loc * expression) list
  {< x1 = E1; ...; xn = En >}

| Pexp_letmodule of string option Asttypes.loc * module_expr * expression
  let module M = ME in E

| Pexp_letexception of extension_constructor * expression
  let exception C in E
`Thread.create` returns the handle of the newly created thread. The new thread terminates when the application `funct arg` returns, either normally or by raising the `Thread文化的Exit[33.1]` exception or by raising any other uncaught exception. In the last case, the uncaught exception is printed on standard error, but not propagated back to the parent thread. Similarly, the result of the application `funct arg` is discarded and not directly accessible to the parent thread.

See also `Domain spawn` [28.14] if you want parallel execution instead.

`val self: unit -> t`

Return the handle for the thread currently executing.

`val id: t -> int`

Return the identifier of the given thread. A thread identifier is an integer that identifies uniquely the thread. It can be used to build data structures indexed by threads.

`exception Exit`

Exception raised by user code to initiate termination of the current thread. In a thread created by `Thread.create[33.1]` `funct arg`, if the `Thread文化的Exit[33.1]` exception reaches the top of the application `funct arg`, it has the effect of terminating the current thread silently. In other contexts, there is no implicit handling of the `Thread文化的Exit[33.1]` exception.

`val exit: unit -> unit`

*Deprecated.* Use 'raise Thread文化的Exit' instead. Raise the `Thread文化的Exit[33.1]` exception. In a thread created by `Thread.create[33.1]`, this will cause the thread to terminate prematurely, unless the thread function handles the exception itself. `Fun.protect[28.22]` finalizers and catch-all exception handlers will be executed.

To make it clear that an exception is raised and will trigger finalizers and catch-all exception handlers, it is recommended to write `raise Thread文化的Exit` instead of `Thread.exit()`.

**Before 5.0** A different implementation was used, not based on raising an exception, and not running finalizers and catch-all handlers. The previous implementation had a different behavior when called outside of a thread created by `Thread.create`.

## Suspending threads

`val delay: float -> unit`

`delay d` suspends the execution of the calling thread for `d` seconds. The other program threads continue to run during this time.

`val join: t -> unit`

`join th` suspends the execution of the calling thread until the thread `th` has terminated.

`val yield: unit -> unit`

Re-schedule the calling thread without suspending it. This function can be used to give scheduling hints, telling the scheduler that now is a good time to switch to other threads.
| Pexp assert of expression
  assert E.

Note: `assert false` is treated in a special way by the type-checker.

| Pexp lazy of expression
  lazy E

| Pexp poly of expression * core_type option
  Used for method bodies.

Can only be used as the expression under `Cfk_concrete[??]` for methods (not values).

| Pexp object of class_structure
  object ... end

| Pexp newtype of string Asttypes.loc * expression
  fun (type t) -> E

| Pexp pack of module_expr * package_type option
  (module ME) or (module ME : S).

| Pexp open of open declaration * expression
  - M.(E)

• let open M in E

• let open! M in E

| Pexp letop of letop
  - let* P = E0 in E1

• let* P0 = E00 and* P1 = E01 in E1

| Pexp extension of extension
  [%id]

| Pexp unreachable

type case =
{ pc_lhs : pattern ;
pc-guard : expression option ;
pc_rhs : expression ;

Values of type `Parsetree.case[30.6]` represents `(P -> E)` or `(P when E0 -> E)`

type letop =
{ let_ : binding_op ;
ands : binding_op list ;
body : expression ;
## Waiting for file descriptors or processes

The functions below are leftovers from an earlier, VM-based threading system. The Unix[30.1] module provides equivalent functionality, in a more general and more standard-conformant manner. It is recommended to use Unix[30.1] functions directly.

* `val wait_timed_read`: Unix.file_descr -> float -> bool

*Deprecated*. Use Unix.select instead. See Thread.wait_timed_write[33.1].

* `val wait_timed_write`: Unix.file_descr -> float -> bool

*Deprecated*. Use Unix.select instead. Suspend the execution of the calling thread until at least one character or EOF is available for reading (`wait_timed_read`) or one character can be written without blocking (`wait_timed_write`) on the given Unix file descriptor. Wait for at most the amount of time given as second argument (in seconds). Return `true` if the file descriptor is ready for input/output and `false` if the timeout expired. The same functionality can be achieved with Unix.select[30.1].

* `val select`:

Unix.file_descr list ->

Unix.file_descr list ->

Unix.file_descr list ->

float -> Unix.file_descr list * Unix.file_descr list * Unix.file_descr list

*Deprecated*. Use Unix.select instead. Same function as Unix.select[30.1]. Suspend the execution of the calling thread until input/output becomes possible on the given Unix file descriptors. The arguments and results have the same meaning as for Unix.select[30.1].

* `val wait_pid`: int -> int * Unix.process_status

*Deprecated*. Use Unix.waitpid instead. Same function as Unix.waitpid[30.1]. `wait_pid p` suspends the execution of the calling thread until the process specified by the process identifier `p` terminates. Returns the pid of the child caught and its termination status, as per Unix.wait[30.1].

## Management of signals

Signal handling follows the POSIX thread model: signals generated by a thread are delivered to that thread; signals generated externally are delivered to one of the threads that does not block it. Each thread possesses a set of blocked signals, which can be modified using Thread sigmask[33.1]. This set is inherited at thread creation time. Per-thread signal masks are supported only by the system thread library under Unix, but not under Win32, nor by the VM thread library.

* `val sigmask`: Unix sigprocmask_command -> int list -> int list

`sigmask cmd sigs` changes the set of blocked signals for the calling thread. If `cmd` is `SIG_SETMASK`, blocked signals are set to those in the list `sigs`. If `cmd` is `SIG_BLOCK`, the signals in `sigs` are added to the set of blocked signals. If `cmd` is `SIG_UNBLOCK`, the signals in `sigs` are removed from the set of blocked signals. `sigmask` returns the set of previously blocked signals for the thread.
```c
}
type binding_op =
{
    pbop_op : string Asttypes.loc ;
    pbop_pat : pattern ;
    pbop_exp : expression ;
    pbop_loc : Location.t ;
}

type function_param_desc =
| Pparam_val of Asttypes.arg_label * expression option * pattern
    Pparam_val (lbl, exp0, P) represents the parameter:
    • P when lbl is Nolabel[??] and exp0 is None
    • ~1:P when lbl is Labelled 1[??] and exp0 is None
    • ?1:P when lbl is Optional 1[??] and exp0 is None
    • ?1:(P = E0) when lbl is Optional 1[??] and exp0 is Some E0
```

Note: If E0 is provided, only Optional[??] is allowed.

| Pparam_newtype of string Asttypes.loc

Pparam_newtype x represents the parameter (type x). x carries the location of the identifier, whereas the pparam_loc on the enclosing function_param node is the location of the (type x) as a whole.

Multiple parameters (type a b c) are represented as multiple Pparam_newtype nodes, let's say:

```c
[ { pparam-kind = Pparam-newtype a; pparam-loc = loc1 };
   { pparam-kind = Pparam-newtype b; pparam-loc = loc2 };
   { pparam-kind = Pparam-newtype c; pparam-loc = loc3 };
]
```

Here, the first loc loc1 is the location of (type a b c), and the subsequent locs loc2 and loc3 are the same as loc1, except marked as ghost locations. The locations on a, b, c, correspond to the variables a, b, and c in the source code.

```c
type function_param =
{
    pparam_loc : Location.t ;
    pparam_desc : function_param_desc ;
}
```

```c
type function_body =
| Pfunction_body of expression
| Pfunction cases of case list * Location.t * attributes
```

In Pfunction cases (_, loc, attrs), the location extends from the start of the function keyword to the end of the last case. The compiler will only use typechecking-related attributes from attrs, e.g. enabling or disabling a warning.

See the comment on Pexp_function[??].
```kotlin
val wait_signal : int list -> int
```

`wait_signal` `sigs` suspends the execution of the calling thread until the process receives one of the signals specified in the list `sigs`. It then returns the number of the signal received. Signal handlers attached to the signals in `sigs` will not be invoked. The signals `sigs` are expected to be blocked before calling `wait_signal`.

## Uncaught exceptions

```kotlin
val default_uncaught_exception_handler : exn -> unit
```

`Thread.default_uncaught_exception_handler` will print the thread's id, exception and backtrace (if available).

```kotlin
val set_uncaught_exception_handler : (exn -> unit) -> unit
```

`Thread.set_uncaught_exception_handler` `fn` registers `fn` as the handler for uncaught exceptions.

If the newly set uncaught exception handler raise an exception, `Thread.default_uncaught_exception_handler[33.1]` will be called.

## 33.2 Module Event: First-class synchronous communication.

This module implements synchronous inter-thread communications over channels. As in John Reppy's Concurrent ML system, the communication events are first-class values: they can be built and combined independently before being offered for communication.

### type 'a channel

The type of communication channels carrying values of type `'a`.

```kotlin
val new_channel : unit -> 'a channel
```

Return a new channel.

### type +'a event

The type of communication events returning a result of type `'a`.

```kotlin
val send : 'a channel -> 'a -> unit event
```

`send ch v` returns the event consisting in sending the value `v` over the channel `ch`. The result value of this event is `()`.

```kotlin
val receive : 'a channel -> 'a event
```

`receive ch` returns the event consisting in receiving a value from the channel `ch`. The result value of this event is the value received.

```kotlin
val always : 'a -> 'a event
```
```c
type type_constraint =
  | Pconstraint of core_type
  | Pcoerce of core_type option * core_type

  See the comment on Pexp_function[??].
```

## Value descriptions

```c
type value_description =
{
    pval_name : string Asttypes.loc ;
    pval_type : core_type ;
    pvalPrim : string list ;
    pval_attributes : attributes ;
    ...
    [@@id1] [@@id2]
}

pval_loc : Location.t ;
}
```

Values of type Parsetree.value_description[30.6] represents:

* `val x: T`, when `pvalPrim[??]` is []

* `external x: T = "s1" ... "sn"` when `pvalPrim[??]` is `"s1";..."sn"`

## Type declarations

```c
type typeDeclaration =
{
    ptype_name : string Asttypes.loc ;
    ptype_params : (core_type * (Asttypes.variance * Asttypes injectivity)) list ;
    ('a1,..., 'an) t
    ptype_cstrs : (core_type * core_type * Location.t) list ;
    ... constraint T1=T1' ... constraint Tn=Tn'
    ptype_type : type_type ;
    ptype_private : Asttypes.private_flag ;
    for = private ...
    ptype manifest : core_type option ;
    represents = T
    ptype_attributes : attributes ;
    ...
    [@@id1] [@@id2]
}

ptypeLoc : Location.t ;
}
```

Here are type declarations and their representation, for various `ptope_type`[??] and `ptope_-manifest`[??] values:
`always v` returns an event that is always ready for synchronization. The result value of this event is `v`.

`val choose : 'a event list -> 'a event`

`choose evl` returns the event that is the alternative of all the events in the list `evl`.

`val wrap : 'a event -> ('a -> 'b) -> 'b event`

`wrap ev fn` returns the event that performs the same communications as `ev`, then applies the post-processing function `fn` on the return value.

`val wrap_abort : 'a event -> (unit -> unit) -> 'a event`

`wrap_abort ev fn` returns the event that performs the same communications as `ev`, but if it is not selected the function `fn` is called after the synchronization.

`val guard : (unit -> 'a event) -> 'a event`

`guard fn` returns the event that, when synchronized, computes `fn()` and behaves as the resulting event. This enables computing events with side-effects at the time of the synchronization operation.

`val sync : 'a event -> 'a`

'Synchronize' on an event: offer all the communication possibilities specified in the event to the outside world, and block until one of the communications succeed. The result value of that communication is returned.

`val select : 'a event list -> 'a`

'Synchronize' on an alternative of events. `select evl` is shorthand for `sync(choose evl)`.

`val poll : 'a event -> 'a option`

Non-blocking version of `Event.sync[33.2]`: offer all the communication possibilities specified in the event to the outside world, and if one can take place immediately, perform it and return `Some r` where `r` is the result value of that communication. Otherwise, return `None` without blocking.
* type `t` when `typeKind` is `Ptype[T]`, and `manifest` is `None`,

* type `t` = `TO` when `typeKind` is `Ptype{T}Abstract[T]`, and `manifest` is `Some TO`,

* type `t` = `C` of `T` | ... when `typeKind` is `Ptype{T}Variant[T]`, and `manifest` is `None`,

* type `t` = `TO` = `C` of `T` | ... when `typeKind` is `Ptype{T}Variant[T]`, and `manifest` is `Some TO`,

* type `t` = `{1: T; ...}` when `typeKind` is `Ptype{T}Record[T]`, and `manifest` is `None`,

* type `t` = `TO` = `{1: T; ...}` when `typeKind` is `Ptype{T}Record[T]`, and `manifest` is `Some TO`,

* type `t` = `..` when `typeKind` is `Ptype{T}Open[T]`, and `manifest` is `None`.

```h
type typeKind =
  | Ptype{T}Abstract
  | Ptype{T}Variant of constructor{T}declaration list
  | Ptype{T}Record of label{T}declaration list
```

Invariant: non-empty list

| Ptype{T}Open

type label{T}declaration =

{ pld_name : string Asttypes.loc ;
  pld mutable : Asttypes.mutable_flag ;
  pld_type : core_type ;
  pld loc : Location.t ;
  pld_attributes : attributes ;
  l : T [@id1] [@id2] }

}

- `{ ... ; l: T; ... }` when `pld mutable [??]` is `Immutable[??]`,

* `{ ... ; mutable l: T; ... }` when `pld mutable [??]` is `Mutable[??]`.

Note: `T` can be a `Ptyp{T}Poly[??]`.

type constructor{T}declaration =

{ pcd_name : string Asttypes.loc ;
  pcd_vars : string Asttypes.loc list ;
  pcd_args : constructor{T}arguments ;
  pcd_res : core_type option ;
  pcd loc : Location.t ;
  pcd_attributes : attributes ;
  C of ... [@id1] [@id2] }

}

type constructor{T}arguments =

| Pcstr{T}tuple of core{T}type list

| Pcstr{T}record of label{T}declaration list
Values of type `Parsetree.ConstructorDeclaration[30.6]` represents the constructor arguments of:

* C of `T1 * ... * Tn` when `res = None`, and `args = Pcstr_tuple [T1; ... ; Tn]`,

* C: `T0` when `res = Some T0`, and `args = Pcstr_tuple []`,

* C: `T1 * ... * Tn -> T0` when `res = Some T0`, and `args = Pcstr_tuple [T1; ... ; Tn]`,

* C of `{...}` when `res = None`, and `args = Pcstr_record [...]`,

* C: `{...} -> T0` when `res = Some T0`, and `args = Pcstr_record [...]`.

```python
type type_extension =
{
    ptyext_path : Longident.t Asttypes.loc ;
    ptyext_params : (core_type * (Asttypes.variance * Asttypes injectivity)) list ;
    ptyext_constructors : extension constructor list ;
    ptyext_private : Asttypes.private_flag ;
    ptyext_loc : Location.t ;
    ptyext_attributes : attributes ;
    ...
    @@id1 @@id2
}
```

```python
}
```

Definition of new extensions constructors for the extensive sum type `t (type t += ...)`).

```python
type extension_constructors =
{
    pext_name : string Asttypes.loc ;
    pext kind : extension_constructors kind ;
    pext_loc : Location.t ;
    pext_attributes : attributes ;
    C of ... [@@id1] [@@id2]
}
```

```python
}
```

```python
type type_exception =
{
    ptyexn_constructors : extension_constructors ;
    ptyexn_loc : Location.t ;
    ptyexn_attributes : attributes ;
    ...
    @@id1 @@id2
}
```

```python
}
```

Definition of a new exception (exception E).

```python
type extension_constructors kind =
| Pext decl of string Asttypes.loc list * constructor_argument
* core_type option

Pext decl (existentials, c_args, t_opt) describes a new extension constructor.
It can be:
```
Chapter 34

The dynlink library: dynamic loading
and linking of object files

The dynlink library supports type-safe dynamic loading and linking of bytecode object files (`.cmo` and `.cma` files) in a running bytecode program, or of native plugins (usually `.cmxs` files) in a running native program. Type safety is ensured by limiting the set of modules from the running program that the loaded object file can access, and checking that the running program and the loaded object file have been compiled against the same interfaces for these modules. In native code, there are also some compatibility checks on the implementations (to avoid errors with cross-module optimizations); it might be useful to hide `.cmx` files when building native plugins so that they remain independent of the implementation of modules in the main program.

Programs that use the `dynlink` library simply need to include the dynlink library directory with `-I +dynlink` and link `dynlink.cma` or `dynlink.cmxa` with their object files and other libraries.

**Note:** in order to insure that the dynamically-loaded modules have access to all the libraries that are visible to the main program (and not just to the parts of those libraries that are actually used in the main program), programs using the `dynlink` library should be linked with `-linkall`.

34.1 Module Dynlink : Dynamic loading of .cmo, .cma and .cmxs files.

val is_native : bool

`true` if the program is native, `false` if the program is bytecode.

Dynamic loading of compiled files

val loadfile : string -> unit

In bytecode: load the given bytecode object file (`.cmo` file) or bytecode library file (`.cma` file), and link it with the running program. In native code: load the given OCaml plugin file (usually `.cmxs`), and link it with the running program.
* C of T1 * ... * Tn when:

- existentials is [],

- c_args is [T1; ...; Tn],

- t_opt is None

* C: TO when

- existentials is [],

- c_args is [],

- t_opt is Some TO.

* C: T1 * ... * Tn -> TO when

- existentials is [],

- c_args is [T1; ...; Tn],

- t_opt is Some TO.

* C: 'a... . T1 * ... * Tn -> TO when

- existentials is ['a;...],

- c_args is [T1; ... ; Tn],

- t_opt is Some TO.

| Pext_rebind of Longident.t Asttypes.loc
Pext_rebind(D) re-export the constructor D with the new name C

Class language

Type expressions for the class language

type class_type =
{ pcty_desc : class_type_desc ;
pcty_loc : Location.t ;
pcty_attributes : attributes ;
... [@id1] [@id2]
}

type class_type_desc =
| Pcty_constr of Longident.t Asttypes.loc * core_type list
- c

* ['a1, ..., 'an] c

| Pcty_signature of class_signature
object ... end

| PctyArrow of Asttypes.arg_label * core_type * class_type
PctyArrow(lb1, T, CT) represents:
All toplevel expressions in the loaded compilation units are evaluated. No facilities are provided to access value names defined by the unit. Therefore, the unit must itself register its entry points with the main program (or a previously-loaded library) e.g. by modifying tables of functions.

An exception will be raised if the given library defines toplevel modules whose names clash with modules existing either in the main program or a shared library previously loaded with `loadfile`. Modules from shared libraries previously loaded with `loadfile_private` are not included in this restriction.

The compilation units loaded by this function are added to the "allowed units" list (see `Dynlink.set_allowed_units[34.1]`).

**val loadfile_private : string -> unit**

Same as `loadfile`, except that the compilation units just loaded are hidden (cannot be referenced) from other modules dynamically loaded afterwards.

An exception will be raised if the given library defines toplevel modules whose names clash with modules existing in either the main program or a shared library previously loaded with `loadfile`. Modules from shared libraries previously loaded with `loadfile_private` are not included in this restriction.

An exception will also be raised if the given library defines toplevel modules whose name matches that of an interface depended on by a module existing in either the main program or a shared library previously loaded with `loadfile`. This applies even if such dependency is only a "module alias" dependency (i.e. just on the name rather than the contents of the interface).

The compilation units loaded by this function are not added to the "allowed units" list (see `Dynlink.set_allowed_units[34.1]`) since they cannot be referenced from other compilation units.

**val adapt_filename : string -> string**

In bytecode, the identity function. In native code, replace the last extension with `.cmxs`.

## Access control

**val set_allowed_units : string list -> unit**

Set the list of compilation units that may be referenced from units that are dynamically loaded in the future to be exactly the given value.

Initially all compilation units composing the program currently running are available for reference from dynamically-linked units. `set_allowed_units` can be used to restrict access to a subset of these units, e.g. to the units that compose the API for dynamically-linked code, and prevent access to all other units, e.g. private, internal modules of the running program.

Note that `Dynlink.loadfile[34.1]` changes the allowed-units list.

**val allow_only : string list -> unit**
* T -> CT when `lbl` is `Nolabel[??]`,

* `~1:T -> CT` when `lbl` is `Labelled 1[??]`,

* `?1:T -> CT` when `lbl` is `Optional 1[??]`.

| Pcty_extension of extension
  %id

| Pcty_open of open_description * class_type
  let open M in CT

type class_signeture =
{ pcsig self : core_type ;
  pcsig_fields : class_type_field list ;
}

Values of type `class_signeture` represents:

* `object('selfpat') ... end`

* `object ... end` when `pcsig self[??]` is `Ptyp_any[??]`

type class_type_field =
{ pctf_desc : class_type_field_desc ;
  pctf_loc : Location.t ;
  pctf_attributes : attributes ;
  ... [@@id1] [@@id2]

}

| Pctf_inherit of class_type
  inherit CT
| Pctf_val of (Asttypes.label Asttypes.loc * Asttypes.multiple_flag *
  Asttypes.virtual_flag * core_type)
  val x: T

| Pctf_method of (Asttypes.label Asttypes.loc * Asttypes.private_flag *
  Asttypes.virtual_flag * core_type)
  method x: T

Note: T can be a `Ptyp_polyl[??]`.

| Pctf_constraint of (core_type * core_type)
  constraint T1 = T2

| Pctf_attribute of attribute
  [@@@id]

| Pctf_extension of extension
`allow_only units` sets the list of allowed units to be the intersection of the existing allowed units and the given list of units. As such it can never increase the set of allowed units.

`val prohibit : string list -> unit`

`prohibit units` prohibits dynamically-linked units from referencing the units named in list units by removing such units from the allowed units list. This can be used to prevent access to selected units, e.g. private, internal modules of the running program.

`val main_program_units : unit -> string list`

Return the list of compilation units that form the main program (i.e. are not dynamically linked).

`val public_dynamically_loaded_units : unit -> string list`

Return the list of compilation units that have been dynamically loaded via `loadfile` (and not via `loadfile_private`). Note that compilation units loaded dynamically cannot be unloaded.

`val all_units : unit -> string list`

Return the list of compilation units that form the main program together with those that have been dynamically loaded via `loadfile` (and not via `loadfile_private`).

`val allow_unsafe_modules : bool -> unit`

Govern whether unsafe object files are allowed to be dynamically linked. A compilation unit is 'unsafe' if it contains declarations of external functions, which can break type safety. By default, dynamic linking of unsafe object files is not allowed. In native code, this function does nothing; object files with external functions are always allowed to be dynamically linked.

## Error reporting

`type linking_error = private`

| Undefined_global of string

| Unavailable primitive of string

| Uninitialized_global of string

`type error = private`

| Not_a_bytescode_file of string

| Inconsistent_import of string

| Unavailable_unit of string

| Unsafe_file

| Linking_error of string * linking_error

| Corrupted_interface of string

| Cannot_open_dynamic_library of exn

| Library's_module_initializers_failed of exn

| Inconsistent_implementation of string

| Module_already_loaded of string

| Private_library_cannot_implement_interface of string

exception Error of error
```c
    [%%id]

type 'a class =
{
   pci_virt : Asttypes.virtual_flag ;
   pci_params : (core_type * (Asttypes.variance * Asttypes injectivity)) list ;
   pci_name : string Asttypes.loc ;
   pci_expr : 'a ;
   pci_loc : Location.t ;
   pci_attributes : attributes ;
    ... [@@id1] [@@id2]
}
```

Values of type `class_expr` `class_info`s represents:

* class c = ...

* class ['a1, ..., 'an] c = ...

* class virtual c = ...

They are also used for "class type" declaration.

`type class_description = class_type class_info`s

`type class_type_description = class_type class_info`s

Value expressions for the class language

```c
type class_expr =
{
   pcl_desc : class_expr_desc ;
   pcl_loc : Location.t ;
   pcl_attributes : attributes ;
    ... [@id1] [@id2]
}
```

```c
type class_expr_desc =
| Pcl_constr of Longident.t Asttypes.loc * core_type list
c and ['a1, ..., 'an] c
| Pcl_structure of class_structure
object ... end
| PclFun of Asttypes.arg_label * expression option * pattern
* class_expr
PclFun.lbl, exp0, P, CE) represents:
```

* fun P -> CE when label is `Nolabel[??]` and exp0 is None,

* fun ~1:P -> CE when label is `Labelled l[??]` and exp0 is None,

* fun ?1:P -> CE when label is `Optional l[??]` and exp0 is None,
Errors in dynamic linking are reported by raising the `Error` exception with a description of the error. A common case is the dynamic library not being found on the system: this is reported via `Cannot_open_dynamic_library` (the enclosed exception may be platform-specific).

`val error_message : error -> string`

Convert an error description to a printable message.
* `fun ?l:(P = E0) -> CE` when `lbl` is Optional `l[??]` and `exp0` is Some `E0`.

| `Pcl_apply` of `class_expr` * (`Asttypes.arg_label` * `expression`) list
  `Pcl_apply`(`CE`, [(`l1`, `E1`) ; ... ; (`ln`, `En`))] represents `CE ~l1:E1 ... ~ln:En`.
  `li` can be empty (non labeled argument) or start with ? (optional argument).
  Invariant: `n > 0`

| `Pcl_let` of `Asttypes.rec_flag` * `value_bind` list * `class_expr`
  `Pcl_let`(`rec`, [(`P1`, `E1`); ... ; (`Pn`, `En`)], `CE`) represents:

* `let P1 = E1` and ... and `Pn = EN` in `CE` when `rec` is Nonrecursive[??],

* `let rec P1 = E1` and ... and `Pn = EN` in `CE` when `rec` is Recursive[??].

| `Pcl_constraint` of `class_expr` * `class_type`
  (`CE`: `CT`)

| `Pcl_extension` of `extension`
  `[%id]`

| `Pcl_open` of `open_description` * `class_expr`
  `let open M` in `CE`

```h
type class_structure =
{
    pcstr self : pattern ;
    pcstr_fields : class_field list ;
}
```

Values of type `Parsetree.class_structure[30.6]` represents:

* `object(selfpat)` ... end

* `object ...` end when `pcstr self[??]` is `Ppat_any[??]`

```h
type class_field =
{
    pcf_desc : class_field_desc ;
    pcf_loc : Location.t ;
    pcf_attributes : attributes ;
    ... [@@id1] [@@id2]
}
```

```c
}
```

type `class_field_desc` =
| `Pcf_inherit` of `Asttypes gasp` * `class_expr` * `string` `Asttypes.loc` option
  `Pcf_inherit`(`flag`, `CE`, `s`) represents:

* `inherit CE` when `flag` is `Fresh[??]` and `s` is `None`,

* `inherit CE` as `x` when `flag` is `Fresh[??]` and `s` is `Some x`,

* `inherit! CE` when `flag` is `Override[??]` and `s` is `None`,
# Chapter 35

## Recently removed or moved libraries
(Graphics, Bigarray, Num, LablTk)

This chapter describes three libraries which were formerly part of the OCaml distribution (Graphics, Num, and LablTk), and a library which has now become part of OCaml's standard library, and is documented there (Bigarray).

### 35.1 The Graphics Library

Since OCaml 4.09, the `graphics` library is distributed as an external package. Its new home is: https://github.com/ocaml/graphics

If you are using the `opam` package manager, you should install the corresponding `graphics` package:

```
opam install graphics
```

Before OCaml 4.09, this package simply ensures that the `graphics` library was installed by the compiler, and starting from OCaml 4.09 this package effectively provides the `graphics` library.

### 35.2 The Bigarray Library

As of OCaml 4.07, the `bigarray` library has been integrated into OCaml's standard library.

The `bigarray` functionality may now be found in the standard library `Bigarray` module, except for the `map_file` function which is now part of the Unix library. The documentation has been integrated into the documentation for the standard library.

The legacy `bigarray` library bundled with the compiler is a compatibility library with exactly the same interface as before, i.e. with `map_file` included.

We strongly recommend that you port your code to use the standard library version instead, as the changes required are minimal.

If you choose to use the compatibility library, you must link your programs as follows:

```
ocamlc other options bigarray.cma other files
ocamlopt other options bigarray.cmxa other files
```
* `inherit!` `CE` as `x` when `flag` is `Override[??]` and `s` is `Some x`

| `Pcf_val` of (`Asttypes.label` `Asttypes.loc` * `Asttypes.mutable_flag` * `class_fieldKind`)

`Pcf_val(x, flag, kind)` represents:

* `val x = E` when `flag` is `Immutable[??]` and `kind` is `Cfk_concrete(Fresh, E)[??]`

* `val virtual x: T` when `flag` is `Immutable[??]` and `kind` is `Cfk_virtual(T)[??]`

* `val mutable x = E` when `flag` is `Mutable[??]` and `kind` is `Cfk_concrete(Fresh, E)[??]`

* `val mutable virtual x: T` when `flag` is `Mutable[??]` and `kind` is `Cfk_virtual(T)[??]`

| `Pcf_method` of (`Asttypes.label` `Asttypes.loc` * `Asttypes.private_flag` * `class_fieldKind`)

- `method x = E` (`E` can be a `Pexp_polymode`)

* `method virtual x: T` (`T` can be a `Ptyp_polymode`)

| `Pcf_constraint` of (`core_type` * `core_type`)

constraint `T1 = T2`

| `Pcf_initialize` of expression

initializer `E`

| `Pcf_attribute` of attribute

[@@@id]

| `Pcf_extension` of extension

[%%id]

type `class_fieldKind` =

| `Cfk_virtual` of `core_type`

| `Cfk_concrete` of `Asttypesption` * `expression`

type `classyar` ` declaration` = `class_expr` `class_info`

## Module language

### Type expressions for the module language

type `module_type` =

{ `pmty_desc` : `module_type_desc` ;

`pmty.loc` : Location.t;

`pmty_attributes` : `attributes` ;

... [@id1] [@id2]
For interactive use of the `bigarray` compatibility library, do:

```
ocamlmktop -o mytop bigarray.cma
./mytop
```

or (if dynamic linking of C libraries is supported on your platform), start `ocaml` and type `#load "bigarray.cma";;`.

## 35.3 The Num Library

The `num` library implements integer arithmetic and rational arithmetic in arbitrary precision. It was split off the core OCaml distribution starting with the 4.06.0 release, and can now be found at https://github.com/ocaml/num.

New applications that need arbitrary-precision arithmetic should use the `Zarith` library (https://github.com/ocaml/Zarith) instead of the `Num` library, and older applications that already use `Num` are encouraged to switch to `Zarith`. `Zarith` delivers much better performance than `Num` and has a nicer API.

## 35.4 The Labltk Library and OCamlBrowser

Since OCaml version 4.02, the OCamlBrowser tool and the Labltk library are distributed separately from the OCaml compiler. The project is now hosted at https://github.com/garrigue/labltk.
```c
}
type module_type_desc =
  | Pmty_ident of Longident.t Asttypes.loc
     Pmty_ident(S) represents S
  | PmtySignature of signature
     sig ... end
  | PmtyFunctor of functor_parameter * module_type
     functor(X : MT1) -> MT2
  | Pmty_with of module_type * with_constraint list
     MT with ...
  | PmtyTypeof of module_expr
     module type of ME
  | PmtyExtension of extension
     [%id]
  | Pmty_alias of Longident.t Asttypes.loc
     (module M)
type functor_parameter =
  | Unit
  ()
  | Named of string option Asttypes.loc * module_type
     Named(name, MT) represents:
     • (X : MT) when name is Some X,
     • (_ : MT) when name is None

type signature = signature_item list
type signature_item =
  { psig_desc : signature_item_desc ;
    psig_loc : Location.t ;
  }
type signature_item_desc =
  | Psig_value of value_description
     - val x: T
     • external x: T = "s1" ... "sn"
  | Psig_type of Asttypes.rec_flag * type_declaration list
     type t1 = ... and ... and tn = ...
  | Psig_typesubst of type_declaration list
```
# Part V

## Indexes
```pascal
type t1 := ... and ... and tn := ...

| Psig typext of type extension
type t1 += ...

| Psig_exception of type_exception
exception C of T

| Psig_module of module declaration
module X = M and module X : MT

| Psig_modsubst of module_substitution
module X := M

| Psig_recmodule of module declaration list
module rec X1 : MT1 and ... and Xn : MTn

| Psig_modtype of module_type declaration
module type S = MT and module type S

| Psig_modtypesubst of module_type declaration
module type S := ...

| Psig_open of open_description
open X

| Psig_include of include_description
include MT

| Psig_class of class_description list
class c1 : ... and ... and cn : ...

| Psig_class_type of class_type declaration list
class type ct1 = ... and ... and ctn = ...

| Psig_attribute of attribute
[@@id]

| Psig_extension of extension * attributes
[%id]

type module declaration =
{ pmd_name : string option Asttypes.loc ;
pmd_type : module_type ;
pmd_attributes : attributes ;
... [@@id1] [@@id2]
pmd_loc : Location.t ;
}
```

Values of type module声明represents `S : MT`
<figure><img src="image_6.png" /></figure>
```c
type module_substitution =
{
    pms_name : string Asttypes.loc ;
    pms ManiFest : Longident.t Asttypes.loc ;
    pms_attributes : attributes ;
    ... [@@id1] [@@id2]
    pms_loc : Location.t ;
}

Values of type module_substitution represents S := M
```

```c
type module_type declaration =
{
    pmtd_name : string Asttypes.loc ;
    pmtd_type : module_type option ;
    pmtd_attributes : attributes ;
    ... [@@id1] [@@id2]
    pmtd_loc : Location.t ;
}

Values of type module_type declaration represents:
```

* S = MT,

* S for abstract module type declaration, when pmtd_type[??] is None.

```c
type 'a open =
{
    popen_expr : 'a ;
    popen_override : Asttypes Worten_flag ;
    popen_loc : Location.t ;
    popen_attributes : attributes ;
}
```

Values of type 'a open_info represents:

* open! X when popen_override[??] is Override[??] (silences the "used identifier shadowing" warning)

* open X when popen_override[??] is Fresh[??]

```c
type open_description = Longident.t Asttypes.loc open_info
```

Values of type open_description represents:

* open M.N

* open M(N).O

```c
type open_statement = module_expr open_info
```

Values of type open_statement represents:

* open M.N
Index to the library

( * ), 499
( ** ), 501
( *. ), 501
(&&), 497, 570
(@), 508
(@@), 499
(!), 516
(!=), 497
(:=), 516
(=), 496
(==), 497
(^), 505
(~^), 518
(>), 496
(>=), 496
(<), 496
(<=), 496
(<>), 496
(-), 499
(-.), 501
(|>), 499
(||), 497, 570
(+), 499
(+.), 501
(/), 499
(/.), 501
(~-), 499
(~-.), 501
(~+), 499
(~+.), 501
(asr), 501
(land), 500
(lor), 500
(lsl), 500
(lsr), 500
(lxor), 500
(mod), 500
__FILE__, 497
__FUNCTION__, 498
__LINE__, 498
__LINE_OF__, 498
__LOC__, 497

__LOC_OF__, 498
__MODULE__, 498
__POS__, 498
__POS_OF__, 498
_exit, 926
abs, 500, 629, 703, 706, 711, 776
abs_float, 503
absolute_path, 885
accept, 951
access, 936
accessariation, 936
acos, 502, 632
acosh, 503, 633
acquire, 836, 837
adapt_filename, 988
add, 605, 619, 621-623, 628, 688, 693, 694, 703, 706, 710, 737, 749, 754, 756, 761, 769, 775, 797, 830, 873
add_buffer, 574
add_bytes, 573
add_channel, 574
add_char, 572
add_int16_be, 575
add_int16_le, 575
add_int16_ne, 575
add_int32_be, 576
add_int32_le, 576
add_int32_ne, 575
add_int64_be, 576
add_int64_le, 576
add_int64_ne, 576
add_int8, 575
add_ppx_context_sig, 881
add_ppx_context_str, 881
add_seq, 574, 619, 620, 691, 693, 695, 743, 752, 755, 757, 767, 773, 798, 835, 839
add_string, 573
add_subbytes, 573
add_substitute, 573
add_substring, 573
add_symbolic_output_item, 669
* open M(N).O

* open struct ... end

```h
type 'a include =
{ pincl_mod : 'a ;
  pincl_loc : Location.t ;
  pincl_attributes : attributes ;
}
```

```h
type include_description = module_type include_info;
  Values of type include_description represents include MT
```

```h
type include_statement = module_expr include_info;
  Values of type include_statement represents include ME
```

```h
type with_constraint =
| Pwith_type of Longident.t Asttypes.loc * type_statement
    with type X.t = ...
```

Note: the last component of the longident must match the name of the
`type_statement`.

| Pwith_module of Longident.t Asttypes.loc * Longident.t Asttypes.loc
  with module X.Y = Z

| Pwith_modtype of Longident.t Asttypes.loc * module_type
  with module type X.Y = Z

| Pwith_modtypesubst of Longident.t Asttypes.loc * module_type
  with module type X.Y := sig end

| Pwith_typesubst of Longident.t Asttypes.loc * type_statement
  with type X.t := ..., same format as [Pwith_type]

| Pwith_modsubst of Longident.t Asttypes.loc * Longident.t Asttypes.loc
  with module X.Y := Z

## Value expressions for the module language

```h
type module_expr =
{ pmod_desc : module_expr_desc ;
  pmod_loc : Location.t ;
  pmod_attributes : attributes ;
  ... [@id1] [@id2]
}
```

```h
type module_expr_desc =
| Pmod_ident of Longident.t Asttypes.loc
```
add_to_list, 737, 762
add_uint16_be, 575
add_uint16_le, 575
add_uint16_ne, 575
add_uint8, 575
add_user_event, 978
add_utf_16be Uchar, 573
add_utf_16le Uchar, 573
add_utf_8 Uchar, 573
addr_info, 957
alarm, 684, 946
alert, 888
alert_reporter, 888
align, 529
all_units, 989
allocated_bytes, 682
allocation, 685
allocation_source, 684
allow_only, 988
allow_unsafe_modules, 989
Already_displayed_error, 889
always, 984
anon Fun, 527
append, 531, 538, 637, 643, 721, 729, 826
apply, 880
Arg, 519, 525
arg, 606
arg_label, 882
argv, 858
Array, 519, 530, 636, 840
array, 492
Array0, 557
array0_of_genarray, 567
Array1, 558
array1_of_genarray, 567
Array2, 561
array2_of_genarray, 567
Array3, 564
array3_of_genarray, 567
ArrayLabels, 519, 537, 642
asin, 502, 633
asinh, 503, 633
asprintf, 672
Assert_failure, 494
Assert_failure, 191, 493

assoc, 725, 734
assoc_opt, 725, 734
assq, 725, 734
assq_opt, 726, 734
Ast_mapper, 877
Asttypes, 881
at_exit, 518, 610
atan, 502, 633
atan2, 503, 633
atanh, 503, 633
Atomic, 519, 545
attribute, 892
attribute_of_warning, 880
attributes, 892
auto_include_alert, 888

backend_type, 860
backtrace_slots, 790
backtrace_slots_of_raw_entry, 790
backtrace_status, 787
Bad, 529
basename, 625
batch_mode_printers, 886
before_first_spawn, 610
beginning_of_input, 810
best_topleft_printers, 887
big_endian, 861
Bigarray, 519, 547
Binary, 837
bind, 780, 805, 951
binding, 917
binding_op, 901
bindings, 738, 763
bits, 801, 803
bits_of_float, 708, 713
bits32, 802, 803
bits64, 802, 803
blit, 532, 539, 556, 558, 560, 563, 566, 572, 578, 591, 637, 644, 841, 850, 872
blit_string, 578, 592
bom, 869
Bool, 519, 569
bool, 492, 802, 803
bool_of_string, 506
X

| Pmod_structure of structure
  struct ... end

| Pmod functor of functor_parameter * module_expr
  functor(X : MT1) -> ME

| Pmod_apply of module_expr * module_expr
  ME1(ME2)

| Pmod_apply_unit of module_expr
  ME1()

| Pmod_constraint of module_expr * module_type
  (ME : MT)

| Pmod_unpack of expression
  (val E)

| Pmod_extension of extension
  [%id]

type structure = structure_item list

type structure_item =

{ pstr_desc : structure_item_desc ;
  pstr_loc : Location.t ;
}

type structure_item_desc =

| Pstr_eval of expression * attributes
  E

| Pstr_value of Asttypes.rec_flag * value_bindist list

Pstr_value(rec, [(P1, E1 ; ... ; (Pn, En)))] represents:

• let P1 = E1 and ... and Pn = EN when rec is Nonrecursive[??],

• let rec P1 = E1 and ... and Pn = EN when rec is Recursive[??].

| Pstr primitive of value_description

- val x: T

• external x: T = "s1" ... "sn"

| Pstr_type of Asttypes.rec_flag * typeDeclaration list

type t1 = ... and ... and tn = ...

| Pstr_typeext of type_extension

type t1 += ...
bool_of_string_opt, 506
bounded_full_split, 970
bounded_split, 970
bounded_split_delim, 970
bprintf, 795
Break, 864
broadcast, 609
bscanf, 811
bscanf_format, 816
bscanf_opt, 811
Bucket, 621-623
Buffer, 519, 571
Bytes, 519, 576, 840
bytes, 491, 612
BytesLabels, 519, 590
c_layout, 552
Callback, 519, 603
Callbacks, 978
capitalize_ascii, 581, 595, 844, 853
cardinal, 738, 763, 769, 831
case, 901
cat, 578, 592, 842, 850
catch, 787
catch_break, 864
cbrt, 632
ceil, 503, 634
change_layout, 554, 557, 559, 562, 565
channel, 612, 984
Char, 519, 604
char, 491, 551
char_of_int, 506
chdir, 859, 938
check, 872
check_geometry, 657
check_suffix, 624
chmod, 936
choose, 739, 763, 770, 832, 985
choose_opt, 739, 763, 770, 832
chop_extension, 625
chop_suffix, 624
chop_suffix_opt, 624
chown, 936
chr, 604
chroot, 938

classDeclaration, 909
class_description, 906
class_expr, 907, 917
class_expr_desc, 908
class_field, 908, 916
class_field_desc, 909
class_fieldASYM, 909
class field, 909
class_info, 906
class signature, 905
class_structure, 908
class_type, 905, 917
class_type_declaration, 906
class_type_desc, 905
class_type_field, 906, 916
class_type_field_desc, 906
classify_float, 505, 631
clean, 619, 620
clear, 572, 619, 621-623, 687, 692, 694, 748, 754, 756, 798, 839, 873
clear_close_on_exec, 937
clear_nonblock, 937
clear_parser, 786
clear_symbolic_output_buffer, 668
close, 700, 783, 929
close_box, 651
close_in, 515, 809
close_in_noerr, 515
close_noerr, 700, 783
close_out, 513
close_out_noerr, 513
close_process, 941
close_process_full, 941
close_process_in, 941
close_process_out, 941
close_stag, 661
close_tbox, 659
closed_flag, 882
closedir, 938
code, 604
combine, 535, 542, 726, 735
command, 859
compact, 682
compare, 496, 570, 581, 595, 604, 612, 617, 635, 704, 708, 713, 721, 729, 736, 742, 761, 766, 768, 772, 778, 781, 806, 821,
```pascal
| Pstr_exception of type_exception
    - exception C of T
        * exception C = M.X

| Pstr_module of module_bind
    module X = ME

| Pstr_recmodule of module_bind_list
    module rec X1 = ME1 and ... and Xn = MEn

| Pstr_modtype of module_type declaration
    module type S = MT

| Pstr_open of open declaration
    open X

| Pstr_class of class declaration list
    class c1 = ... and ... and cn = ...

| Pstr_class_type of class_type declaration list
    class type ct1 = ... and ... and ctn = ...

| Pstr_include of include declaration
    include ME

| Pstr_attribute of attribute
    [@@@id]

| Pstr_extension of extension * attributes
    [%@id]

type value_constraint =
| Pvc_constraint of { locally_abSTRACT_univars : string Asttypes.loc list ;
    typ : core_type ;
}
| Pvc_coercion of { ground : core_type option ;
    coercion : core_type ;
}
```

- `Pvc_constraint { locally_abSTRACT_univars = []; typ }` is a simple type constraint on a value binding: `let x : typ`

* More generally, in `Pvc_constraint { locally_abSTRACT_univars; typ }`
  `locally_abSTRACT_univars` is the list of locally abstract type variables in `let
  x: type a ... typ`

* `Pvc_coercion { ground=None; coercion }` represents `let x :> typ`

* `Pvc_coercion { ground=Some g; coercion }` represents `let x : g :> typ`
830, 834, 842, 851, 870, 871
compare_and_set, 545
compare_length_with, 720, 728
compare Lengths, 719, 728
Complex, 519, 605
complex32, 550
complex32_elt, 549
complex64, 550
complex64_elt, 549
compression_supported, 746
concat, 531, 538, 578, 592, 624, 637, 643, 721,
729, 826, 842, 850
concat_map, 722, 730, 826
Condition, 519, 607
conj, 605
connect, 951
cons, 720, 728, 822
const, 676
constant, 881, 892
constr_ident, 891
constructor_argumentS, 903
constructor_declaration, 903
contains, 581, 594, 842, 851
contains_from, 581, 594, 842, 851
contents, 571
continuation, 614, 615
Continuation alreadY resumed, 613
continue, 614
continue_with, 615
control, 681
convert_raw_backtrace_slots, 792
copy, 532, 539, 577, 591, 619, 637, 643, 688,
693, 694, 749, 754, 756, 779, 798, 803,
839
copy_sign, 634
copysign, 504
core_type, 890, 893, 916
core_type_desc, 894
cos, 502, 632
cosh, 503, 633
count, 874
counters, 681
Counting, 836
cpu_relax, 610
create, 553, 557, 558, 561, 564, 571, 577, 590,

609, 618, 619, 637, 643, 687, 692, 694,
748, 754, 756, 774, 797, 838, 872, 873,
978, 981
create_alarm, 684
create_cursor, 979
create_float, 531, 538
create_process, 939
create_process_env, 939
curr, 883
current, 530
current_dir_name, 624
cursor, 976
cycle, 823
cygwin, 860
data, 873
data_size, 746
dscr, 516, 545
Deep, 614
default_alert_reporter, 888
default_mapper, 879
default_report_printers, 887
default_uncaught_exception_handler,
789, 984
default_warning_reporter, 887
delay, 982
delete_alarm, 684
deprecated, 888
deprecated_script_alert, 888
descr_of_in_channel, 930
descr_of_out_channel, 930
development_version, 864
diff, 769, 831
Digest, 519, 612
dim, 559
dim1, 561, 564
dim2, 561, 564
dim3, 564
dims, 554
dir_handle, 938
dir_sep, 624
direction_flag, 882
directive_argument, 916
directive_argument_desc, 916
dirname, 625
```python
type value_bind =
{
    pvb_pat : pattern ;
    pvb_expr : expression ;
    pvb_constraint : value_constraint option ;
    pvb_attributes : attributes ;
    pvb_loc : Location.t ;
}

let pat : type_constraint = exp

type module_bind =
{
    pmb_name : string option Asttypes.loc ;
    pmb_expr : module_expr ;
    pmb_attributes : attributes ;
    pmb_loc : Location.t ;
}

Values of type module_bind represents module X = ME
```

## TLEVEL

### Tplevel phrases

```python
type toplevel_phrase =
|
Ptop_def of structure
|
Ptop_dir of toplevel_directive

#use, #load ...

type toplevel_directive =
{
    pdir_name : string Asttypes.loc ;
    pdir_arg : directive_argument option ;
    pdir_loc : Location.t ;
}

type directive_argument =
{
    pdira_desc : directive_argument_desc ;
    pdira_loc : Location.t ;
}

type directive_argument_desc =
|
Pdir_string of string
|
Pdir_int of string * char option
|
Pdir_ident of Longident.t
|
Pdir_bool of bool
```

## 30.7 Module Pprintast : Pretty-printers for Parsetree [30.6]

**Warning:** this module is unstable and part of compiler-libs[30].
discontinue, 614
discontinue_with, 615
discontinue_with_backtrace, 614, 615
disjoint, 769, 831
div, 606, 628, 703, 706, 710, 776
Division_by_zero, 495
Division_by_zero, 493
DLS, 611
doc, 527
Domain, 519, 609
domain_of_sockaddr, 951
dprintf, 672
drop, 824, 838
drop_ppx_context_sig, 881
drop_ppx_context_str, 881
dropwhile, 825
dummy_pos, 716
dup, 936
dup2, 936
Dynlink, 987
echo_eof, 884
Effect, 519, 613
effect_handler, 614
Either, 520, 616
elements, 769, 831
elt, 769, 830
Empty, 797, 838
empty, 577, 591, 737, 761, 769, 822, 830, 841, 850
enable_runtime_warnings, 865
End_of_file, 495
end_of_input, 810
End_of_file, 493
ends_with, 582, 595, 842, 851
environment, 924
Ephemeron, 520, 617
eprintf, 672, 795
epsilon, 630
epsilon_float, 505
eq, 866
equal, 570, 581, 595, 604, 612, 617, 635, 692, 694, 704, 709, 713, 721, 729, 742, 753, 755, 766, 772, 778, 781, 806, 821, 834, 842, 851, 870, 871

erf, 633
erfc, 634
err_formatter, 666
Error, 889, 989
error, 805, 888, 889, 924, 989
error_message, 924, 990
error_of_exn, 889
error_of_printers, 889
error_of_printers_file, 889
errorf, 889
escaped, 579, 593, 604, 844, 852
establish_server, 955
Event, 984
event, 984
eventlog_pause, 684
eventlogResume, 684
exchange, 545
executable_name, 858
execv, 925
execve, 926
execvp, 926
execvpe, 926
exists, 534, 541, 579, 593, 639, 645, 723, 732, 742, 766, 773, 820, 834, 844, 852
exists2, 534, 541, 724, 732, 821
Exit, 494, 982
exit, 518, 982
exn, 492
exn�_id, 793
exnSlot_name, 793
exp, 502, 606, 632
exp2, 632
expm1, 502, 632
expression, 890, 897, 916
expression_desc, 901
extend, 578, 591
extended_module_path, 891
extension, 625, 892
extension_constructor, 904
extension_constructor_rnd, 904
extension_of_error, 880
extern_flags, 744
extra_info, 864
extra_prefix, 864
```kotlin
type space_formatter = (unit, Format formatter, unit) format
val longident : Format formatter -> Longident.t -> unit
val constr : Format formatter -> Longident.t -> unit
val expression : Format formatter -> Parsetree.expression -> unit
val string_of_expression : Parsetree.expression -> string
val pattern : Format formatter -> Parsetree.pattern -> unit
val core_type : Format formatter -> Parsetree.core_type -> unit
val signature : Format formatter -> Parsetree signature -> unit
val structure : Format formatter -> Parsetree structure -> unit
val string_of_structure : Parsetree structure -> string
val module_expr : Format formatter -> Parsetree.module_expr -> unit
val toplevel_phrase : Format formatter -> Parsetree.t LEVEL_phrase -> unit
val top_phrase : Format formatter -> Parsetree.t LEVEL_phrase -> unit
val class_field : Format formatter -> Parsetree.class_field -> unit
val class_type_field : Format formatter -> Parsetree.class_type_field -> unit
val class_expr : Format formatter -> Parsetree.class_expr -> unit
val class_type : Format formatter -> Parsetree.class_type -> unit
val module_type : Format formatter -> Parsetree.module_type -> unit
val structure_item : Format formatter -> Parsetree. structure_item -> unit
val signature_item : Format formatter -> Parsetree. signature_item -> unit
val binding : Format formatter -> Parsetree.value_bindin g -> unit
val payload : Format formatter -> Parsetree_payload -> unit
val tyvar_of_name : string -> string
```

Turn a type variable name into a valid identifier, taking care of the special treatment required for the single quote character in second position, or for keywords by escaping them with `\#`. No-op on `"_"`.

```kotlin
val tyvar : Format formatter -> string -> unit
```

Print a type variable name as a valid identifier, taking care of the special treatment required for the single quote character in second position, or for keywords by escaping them with `\#`. No-op on `"_"`.

```kotlin
module Doc :
sig
    val longident : Longident.t Format_doc.printer
    val constr : Longident.t Format_doc.printer
    val tyvar : string Format_doc.printer
    val nominal_exp : Parsetree.expression -> Format_doc.t option
```
Failure, 493, 495
failwith, 494
fast_sort, 536, 543, 640, 647, 727, 735
fchmod, 936
fchown, 936
fetch_and_add, 545
fiber, 615
file, 613
file_descr, 927
file_exists, 858
fileKind, 931
file_name, 809
file_perm, 928
Filename, 520, 624
fill, 532, 539, 557, 558, 560, 563, 566, 578, 591, 637, 644, 872
filter, 724, 733, 741, 765, 771, 823, 833
filter_map, 722, 730, 741, 765, 772, 824, 833
filter_map_inplace, 689, 693, 695, 750, 754, 756
filteri, 725, 733
finalise, 682
finalise_last, 683
finalise_release, 684
Finally_raised, 677
find, 619, 621-623, 688, 693, 694, 724, 732, 739, 749, 754, 756, 764, 770, 820, 832, 873
find_all, 619, 620, 688, 693, 695, 725, 733, 749, 754, 756, 874
find_first, 739, 764, 770, 832
find_first_opt, 740, 764, 771, 832
find_index, 534, 541, 639, 646, 724, 732, 820
find_last, 740, 764, 771, 832
find_last_opt, 740, 764, 771, 833
find_left, 616
find_map, 534, 542, 639, 646, 724, 733, 820
find_mapi, 535, 542, 639, 646, 724, 733, 820
find_opt, 534, 541, 619, 620, 639, 646, 688, 693, 694, 724, 732, 739, 749, 754, 756, 764, 770, 832, 874
find_right, 617
first_chars, 971
flat_map, 826
flatten, 721, 729, 890

flip, 676
Float, 520, 628
float, 492, 504, 802, 803
float_of_bits, 708, 713
float_of_int, 504
float_of_string, 507
float_of_string_opt, 507
float32, 550
float32_elt, 549
float64, 550
float64_elt, 549
floor, 503, 634
flow_action, 962
flush, 511, 784
flush_all, 511, 784
flush_input, 719
flush_queue, 961
flush_str_formatter, 666
flush_symbolic_output_buffer, 668
fma, 628
fold, 617, 689, 693, 695, 740, 750, 754, 756, 765, 771, 780, 798, 805, 833, 839, 874
fold_left, 533, 540, 579, 592, 638, 645, 722, 731, 819, 843, 852
fold_left_map, 533, 540, 722, 730
fold_left2, 723, 731, 821
fold_lefti, 819
fold_lines, 701
fold_right, 533, 540, 579, 592, 638, 645, 722, 731, 843, 852
fold_right2, 723, 731
for_all, 533, 541, 579, 593, 617, 639, 645, 723, 732, 742, 766, 773, 819, 834, 843, 852
for_all2, 534, 541, 723, 732, 821
force, 169, 715
force_newline, 654
force_val, 716
Forced_twice, 825
forever, 823
fork, 926
Format, 520, 649
format, 518, 791
format_from_string, 816
format_of_string, 518
Returns a format document if the expression reads nicely as the subject of a sentence in
a error message.

end

Format_doc[??] functions for error messages
format4, 492, 518
format6, 518
formatter, 650
formatter_for_warnings, 887
formatter_of_buffer, 666
formatter_of_out_channel, 665
formatter_of_out_functions, 667
formatter_of_symbolic_output_buffer, 669
formatter_out_functions, 663
formatter_stag_functions, 664
fortran_layout, 552
fpclass, 505, 631
fprintf, 671, 793
free_cursor, 979
frexp, 504, 635
from_bytes, 746
from_channel, 717, 745, 810
from_file, 809
from_file_bin, 809
from Fun, 716
from_function, 717, 809
from_hex, 613
from_string, 717, 746, 809
from_val, 715
fst, 507
fstat, 932, 933
fsync, 929
ftruncate, 931, 933
full_init, 801
full_int, 801, 803
full_major, 682
full_split, 970
Fun, 520, 676
functor_parameter, 910
Gc, 520, 677
Genarray, 552
genarray_of_array0, 567
genarray_of_array1, 567
genarray_of_array2, 567
genarray_of_array3, 567
geometry, 657
get, 530, 537, 545, 554, 558, 559, 562, 565, 577, 590, 611, 636, 643, 682, 780, 841,

850, 872
get_backtrace, 787
get_callstack, 615, 616, 789
get cookie, 881
get_copy, 872
get_ellipsis_text, 659
get_err_formatter, 666
get_error, 805
get_formatter_out_functions, 664
get_formatter_output_functions, 663
get_formatter_stag_functions, 665
get_geometry, 658
get_id, 610
get_int16_be, 586, 600, 848, 856
get_int16_le, 586, 600, 848, 856
get_int16_ne, 586, 600, 847, 856
get_int32_be, 587, 600, 848, 857
get_int32_le, 587, 600, 848, 857
get_int32_ne, 587, 600, 848, 857
get_int64_be, 587, 601, 848, 857
get_int64_le, 587, 601, 849, 857
get_int64_ne, 587, 600, 848, 857
get_int8, 586, 599, 847, 856
get margin, 656
get_markos, 662
get_max boxes, 658
get_max indent, 657
get_minor_free, 682
get_ok, 805
get pos info, 883
get_printos, 662
get_raw_backtrace, 789
get_raw_backtrace_next�, 792
get_raw_backtrace_slots, 792
get_state, 804
get_std_formatter, 666
get_stdbuf, 666
get_str_formatter, 666
get_symbolic_output_buffer, 668
get_temp_dir_name, 627
get_uint16_be, 586, 600, 847, 856
get_uint16_le, 586, 600, 847, 856
get_uint16_ne, 586, 600, 847, 856
get_uint8, 586, 599, 847, 856
get_utf_16be_uchar, 585, 598, 846, 855
Chapter 31

The unix library: Unix system calls

The unix library makes many Unix system calls and system-related library functions available to OCaml programs. This chapter describes briefly the functions provided. Refer to sections 2 and 3 of the Unix manual for more details on the behavior of these functions.

Not all functions are provided by all Unix variants. If some functions are not available, they will
raise Invalid_arg when called.

Programs that use the unix library must be linked as follows:

ocamlc other options -I +unix unix.cma other files

ocamlopt other options -I +unix unix.cmxa other files

For interactive use of the unix library, do:

ocamlmktop -o mytop -I +unix unix.cma

./mytop

or (if dynamic linking of C libraries is supported on your platform), start ocaml and type

# #directory "+unix";;

# #load "unix.cma";;

Windows:

A fairly complete emulation of the Unix system calls is provided in the Windows version
of OCaml. The end of this chapter gives more information on the functions that are not
supported under Windows.

31.1 Module Unix : Interface to the Unix system.

To use the labeled version of this module, add module Unix = UnixLabels in your implementation.

Note: all the functions of this module (except Unix.error_message[31.1] and Unix.handle_
unix_error[31.1]) are liable to raise the Unix.Unix_error[31.1] exception whenever the underlying
system call signals an error.
get_utf_16le_uchar, 585, 599, 847, 855
get_utf_8_uchar, 584, 598, 846, 855
get_value, 837
getaddrinfo, 957
getaddrinfo_option, 957
getcwd, 859, 938
getegid, 948
getenv, 858, 924
getenv_opt, 859
geteuid, 947
getgid, 947
getgrgid, 949
getgrnam, 949
getgroups, 948
gethostbyaddr, 956
gethostbyname, 956
gethostname, 956
getitimer, 947
getlogin, 949
getnameinfo, 958
getnameinfo_option, 958
getpeername, 952
getpid, 927
getppid, 927
getprotobyname, 956
getprotobynumber, 956
getpwnam, 949
getpwuid, 949
getservbyname, 956
getservbyport, 956
getsockname, 952
getsockopt, 954
getsockopt_error, 955
getsockopt_float, 954
getsockopt_int, 954
getsockopt_optint, 954
gettimeofday, 945
getuid, 947
global_replace, 969
global_substitute, 969
gmtime, 945
group, 825
group_beginning, 968
group_end, 969
group_entry, 948

guard, 985
handle_unix_error, 924
handler, 614, 615
has_symlink, 942
hash, 570, 605, 636, 692, 696, 705, 709, 714, 753, 757, 779, 848, 857, 870
hash_param, 696, 758
HashedType, 692, 753
Hashtbl, 520, 686, 747
hd, 720, 728
header_size, 746
Help, 529
highlight_termininfo, 885
host_entry, 955
hypot, 503, 633
i, 605
ibprintf, 796
Id, 867
id, 610, 676, 779, 982
ifprintf, 673, 795
ignore, 506
ikbprintf, 796
ikfprintf, 673, 796
Immediate, 866
Immediate64, 865
implementation, 890
In_channel, 520, 698
in_channel, 508, 808
in_channel_length, 515
in_channel_of_descr, 929
in_file, 883
includeDeclaration, 912
include_description, 912
includeInfos, 912
incr, 516, 545
index, 579, 593, 845, 854
index_from, 580, 593, 845, 854
index_from_opt, 580, 594, 845, 854
index_opt, 580, 593, 845, 854
inet_addr, 949
inet_addr_any, 949
inet_addr_loopback, 949
inet_addr_of_string, 949
inet6_addr_any, 950
Error report

type error =

| E2BIG

Argument list too long

| EACCES

Permission denied

| EAGAIN

Resource temporarily unavailable; try again

| EBADF

Bad file descriptor

| EBUSY

Resource unavailable

| ECHILD

No child process

| EDEADLK

Resource deadlock would occur

| EDOM

Domain error for math functions, etc.

| EEXIST

File exists

| EFAULT

Bad address

| EFBIG

File too large

| EINTR

Function interrupted by signal

| EINVAL

Invalid argument

| EIO

Hardware I/O error

| EISDIR

Is a directory

| EMFILE

Too many open files by the process
inet6_addr_loopback, 950
infinity, 504, 629
init, 531, 538, 553, 557, 559, 561, 564, 577,
590, 637, 643, 720, 729, 801, 822, 841,
850, 883
initgroups, 948
injectivity, 882
input, 514, 613, 701
input_all, 700
input_binary_int, 514
input_byte, 514, 700
input_char, 513, 700
input_lexbuf, 883
input_line, 513, 700
input_lines, 701
input_name, 883
input_phrase_buffer, 883
input_value, 514
Int, 520, 702
int, 491, 551, 801, 803, 977
int_elt, 549
int_of_char, 506
int_of_float, 504
int_of_string, 507
int_of_string_opt, 506
int_size, 860
int16_signed, 551
int16_signed_elt, 549
int16_unsigned, 551
int16_unsigned_elt, 549
Int32, 520, 705
int32, 492, 551, 802, 803
int32_elt, 549
Int64, 520, 709
int64, 492, 551, 802, 803
int64_elt, 549
int8, 551
int8_elt, 549
int8 unsigned, 551
int8 unsigned_elt, 549
inter, 769, 831
interactive, 859
interface, 890
interleave, 827
interval_timer, 947

interval_timer_status, 947
ints, 829
inv, 606
invalid_arg, 494
Invalid_argument, 495
Invalid_argument, 493
is_buffered, 785
is_char, 869
is_directory, 858
is_empty, 720, 728, 742, 766, 772, 798, 818,
834, 839
is_error, 806
is_finite, 630
is_implicit, 624
is_inet6_addr, 950
is_infinite, 630
is inline, 791
is_integer, 630
is_left, 616
is_main_domain, 610
is_nan, 630
is_native, 987
is_none, 781, 883
is_ok, 806
is RaisE, 791
is_randomized, 690, 751
is COmPLeCtAR, 858
is_relative, 624
is right, 616
is some, 781
is_val, 715
is_valid, 869
is_valid_utf_16be, 585, 599, 846, 855
is_valid_utf_16le, 585, 599, 847, 855
is_valid_utf_8, 585, 598, 846, 855
isatty, 702, 785, 932
iter, 532, 539, 578, 592, 617, 638, 644, 688,
693, 695, 722, 730, 740, 749, 754, 756,
764, 771, 780, 798, 805, 819, 833, 839,
845, 853, 874
iter_error, 805
iter2, 533, 540, 639, 645, 723, 731, 820
iterate, 823
iteri, 532, 539, 578, 592, 638, 644, 722, 730,
819, 845, 853
| EMLINK

Too many links

| ENAMETOOLONG

Filename too long

| ENFILE

Too many open files in the system

| ENODEV

No such device

| ENOENT

No such file or directory

| ENOEXEC

Not an executable file

| ENOLCK

No locks available

| ENOMEM

Not enough memory

| ENOSPC

No space left on device

| ENOSYS

Function not supported

| ENOTDIR

Not a directory

| ENOTEMPTY

Directory not empty

| ENOTTY

Inappropriate I/O control operation

| ENXIO

No such device or address

| EPERM

Operation not permitted

| EPIPE

Broken pipe

| ERANGE

Result too large
join, 610, 780, 805, 982
K1, 620
K2, 621
kasprintf, 673
kbprintf, 796
kdprintf, 673
key, 527, 611, 618, 619, 692, 694, 737, 754, 756, 761
kfprintf, 673, 796
kill, 944
kind, 550, 554, 557, 559, 562, 564
kind_size_in_bytes, 551
Kn, 622
kprintf, 796
kscanf, 815
ksprintf, 673, 796
ksscnf, 815
label, 882
label_declaration, 903
LargeFile, 515, 932
last, 890
last_chars, 971
layout, 552, 554, 557, 559, 562, 565
Lazy, 520, 714
Lazy (module), 169
lazy_t, 492
ldexp, 504, 635
left, 616
length, 530, 537, 572, 576, 590, 619–623, 636, 643, 689, 693, 695, 702, 719, 728, 750, 754, 756, 784, 798, 819, 839, 841, 850, 872
letop, 901
lexbuf, 717
lexeme, 718
lexeme_char, 718
lexeme_end, 718
lexeme_end_p, 719
lexeme_start, 718
lexeme_start_p, 718
Lexing, 520, 716
lifecycle, 976
lifecycle_name, 976
link, 935

linking_error, 989
List, 520, 719, 840
list, 492
listen, 951
ListLabels, 520, 727
lnot, 500
loadfile, 987
loadfile_private, 988
loc, 882, 883
localtime, 946
Location, 882
location, 791
location_stack, 892
lock, 774
lock_command, 943
lockf, 943
log, 502, 606, 632
log10, 502, 632
log1p, 502, 632
log2, 632
logand, 704, 707, 711, 777
lognot, 704, 707, 711, 777
logor, 704, 707, 711, 777
logxor, 704, 707, 711, 777
Longident, 889
longident, 890, 916
lowercase CHAR, 581, 594, 604, 844, 853
lseek, 930, 932
lstat, 932, 933
main_program_units, 989
major, 682
major_slice, 682
Make, 620, 622, 623, 694, 743, 755, 767, 774, 835, 866, 874
make, 531, 538, 545, 577, 590, 620–623, 636, 643, 803, 836, 837, 841, 849, 867
make_formatter, 666
make_matrix, 531, 538
make self init, 803
make symbolic output buffer, 668
make synchronized formatter, 667
MakeSeeded, 620, 622, 623, 695, 757
Map, 520, 736, 760
map, 532, 539, 579, 592, 617, 638, 644, 715,
| EROFS

Read-only file system

| ESPIPE

Invalid seek e.g. on a pipe

| ESRCH

No such process

| EXDEV

Invalid link

| EWOULDBLOCK

Operation would block

| EINPROGRESS

Operation now in progress

| EALREADY

Operation already in progress

| ENOTSOCK

Socket operation on non-socket

| EDESTADDRREQ

Destination address required

| EMSGSIZE

Message too long

| EPROTOTYPE

Protocol wrong type for socket

| ENOPROTOOPT

Protocol not available

| EPROTONOSUPPORT

Protocol not supported

| ESOCKTNOSUPPORT

Socket type not supported

| EOPNOTSUPP

Operation not supported on socket

| EPFNOSUPPORT

Protocol family not supported

| EAFNOSUPPORT

Address family not supported by protocol family
722, 730, 740, 765, 771, 780, 805, 823, 833, 843, 852
map_error, 805
map_file, 934
map_from_array, 641, 647
map_inplace, 532, 540, 638, 644
map_left, 617
map_opt, 880
map_product, 827
map_right, 617
map_to_array, 641, 647
map_val, 715
map2, 533, 540, 639, 645, 723, 731, 826
mapi, 532, 540, 579, 592, 638, 645, 722, 730, 741, 765, 823, 843, 852
mapi_inplace, 533, 540, 638, 645
mapper, 879
 Marshal, 520, 743
match_beginning, 968
match_end, 968
Match_failure, 494
match_with, 614
matched_group, 968
matched_string, 967
Match_failure, 175, 178, 181, 493
max, 497, 635, 704, 709, 713, 779, 869
max_array_length, 861
maxBinding, 739, 763
maxBinding_opt, 739, 763
max_elt, 770, 831
max_elt_opt, 770, 832
max_float, 505, 630
max_floatarray_length, 861
max_int, 500, 703, 707, 711, 776
max_num, 635
max_string_length, 861
mem, 534, 541, 619, 620, 639, 646, 688, 693, 695, 724, 732, 742, 749, 754, 756, 766, 772, 834, 874
mem, 726, 734
mem Assq, 726, 734
mem_ieee, 639, 646
memoize, 825
Memprof, 684
memq, 534, 541, 724, 732

merge, 727, 735, 738, 762, 873
min, 496, 635, 704, 709, 713, 779, 869
min_bindin9, 738, 763
min_bindin9_opt, 739, 763
min_elt, 770, 831
min_elt_opt, 770, 831
min_floa, 505, 630
min_int, 500, 704, 707, 711, 776
min_max, 635
min_max_num, 636
min_num, 635
minor, 682
minor_words, 681
minus_one, 628, 703, 706, 710, 775
mkdir, 859, 938
mkfifo, 938
mkloc, 883
mknoloc, 883
mktime, 946
mod_floa, 504
modf, 504, 635
module_bindin9, 915
module_declaration, 911
module_expr, 890, 913, 916
module_expr_desc, 914
module_substitution, 911
module_type, 890, 909, 917
module_type_declaration, 911
module_type_desc, 910
MoreLabels, 520, 747
msg, 886
msg_flag, 952
mul, 606, 628, 703, 706, 710, 775
mutable_flag, 882
Mutex, 520, 774
name, 791, 977
name_info, 958
name_of_input, 810
nan, 504, 629
nativebits, 802, 803
Nativeint, 520, 775
nativeint, 492, 551, 802, 803
nativeint_elt, 549
neg, 605, 628, 703, 706, 710, 775
| EADDRINUSE

Address already in use

| EADDRNOTAVAIL

Can't assign requested address

| ENETDOWN

Network is down

| ENETUNREACH

Network is unreachable

| ENETRESET

Network dropped connection on reset

| ECONNABORTED

Software caused connection abort

| ECONNRESET

Connection reset by peer

| ENOBUFS

No buffer space available

| EISCONN

Socket is already connected

| ENOTCONN

Socket is not connected

| ESHUTDOWN

Can't send after socket shutdown

| ETOOMANYREFS

Too many references: can't splice

| ETIMEDOUT

Connection timed out

| ECONNREFUSED

Connection refused

| EHOSTDOWN

Host is down

| EHOSTUNREACH

No route to host

| ELOOP

Too many levels of symbolic links
neg_infinity, 504, 629

negate, 676

new_channel, 984

new_key, 611

new_line, 719

next_after, 634

nice, 927

node, 818

Non_immediate, 865

none, 780, 883

norm, 606

norm2, 606

not, 497, 570

Not_found, 495

Not_found, 493

nth, 572, 720, 728

nth_dim, 554

nth_opt, 720, 728

null, 625

null_tracking, 685

num-dims, 554

Obj, 521

object_field, 895

object_field_desc, 895

Ocaml_operators, 875

ocaml_release, 865

ocaml_release_info, 864

ocaml_version, 864

of_array, 560, 563, 566

of_binary_string, 804

of_bytes, 841, 850

of_char, 870

of_dispenser, 829

of_float, 705, 708, 712, 777

of_int, 630, 707, 711, 777, 869

of_int32, 712, 778

of_list, 532, 539, 638, 644, 742, 767, 773, 835

of_nativeint, 712

of_seq, 536, 543, 574, 584, 598, 619, 620, 641,
647, 691, 693, 695, 727, 736, 743, 752,
755, 757, 767, 773, 798, 835, 839, 846,
855

of_string, 577, 591, 630, 708, 712, 778

of_string_opt, 631, 708, 713, 778

of_value, 558

ok, 804

once, 825

one, 605, 628, 703, 705, 710, 775

Oo, 521, 779

opaque-identity, 865

open_bin, 699, 782

open_box, 651

open_connection, 955

open_declaration, 912

open_description, 912

open_flag, 511, 699, 782, 928

open_gen, 699, 782

open_hbox, 651

open_hovbox, 652

open_hvbox, 652

open_in, 513, 809

open_in_bin, 513, 809

open_in_gen, 513

open, 912

open_out, 511

open_out_bin, 511

open_out_gen, 511

open_process, 939

open_process_args, 940

open_process_args_full, 940

open_process_args_in, 940

open_process_args_out, 940

open_process_full, 940

open_process_in, 939

open_process_out, 939

open_stag, 661

open_tbox, 658

open_temp_file, 626

open_text, 699, 782

open_vbox, 652

opendir, 938

openfile, 928

Option, 521, 780

Option, 492

OrderedType, 736, 761, 768, 830

os_type, 860

Out_channel, 521, 781

out_channel, 508

out_channel_length, 512, 515
| **EVERFLOW**

File size or position not representable

| **EUNKNOWNERR** of **int**

Unknown error

The type of error codes. Errors defined in the POSIX standard and additional errors from UNIX98 and BSD. All other errors are mapped to EUNKNOWNERR.

**exception Unix_error of error * string * string**

Raised by the system calls below when an error is encountered. The first component is the error code; the second component is the function name; the third component is the string parameter to the function, if it has one, or the empty string otherwise.

`UnixLabels.Unix_error[??]` and `Unix.Unix_error[31.1]` are the same, and catching one will catch the other.

**val error_message : error -> string**

Return a string describing the given error code.

**val handle_unix_error : ('a -> 'b) -> 'a -> 'b**

`handle_unix_error` `f` `x` applies `f` to `x` and returns the result. If the exception `Unix.Unix_error[31.1]` is raised, it prints a message describing the error and exits with code 2.

## Access to the process environment

**val environment : unit -> string array**

Return the process environment, as an array of strings with the format `"variable=value"`. The returned array is empty if the process has special privileges.

**val unsafe_environment : unit -> string array**

Return the process environment, as an array of strings with the format `"variable=value"`. Unlike `Unix-environment[31.1]`, this function returns a populated array even if the process has special privileges. See the documentation for `Unix.unsafe_getenv[31.1]` for more details.

**Since:** 4.06 (4.12 in UnixLabels)

**val getenv : string -> string**

Return the value associated to a variable in the process environment, unless the process has special privileges.

**Raises** `Not_found` if the variable is unbound or the process has special privileges.

This function is identical to `Sys.getenv[29.60]`.

**val unsafe_getenv : string -> string**
out_channel_of descr, 930
Out_of_memory, 495
Out_of_memory, 493
output, 512, 613, 783
output_binary_int, 512
output_buffer, 572
output_byte, 512, 783
output_bytes, 511, 783
output_char, 511, 783
output_string, 511, 783
output_substring, 512, 784
output_value, 512
over_max boxes, 658
override_flag, 882
package_type, 894
parent_dir_name, 624
Parse, 890
parse, 527, 890
parse_and_extend_argv_dynamic, 529
parse_argv, 528
parse_argv_dynamic, 529
parse_dynamic, 528
Parse_error, 786
parse_extend, 529
Parsetree, 891
Parsing, 521, 785
partition, 725, 733, 741, 766, 772, 828, 834
partition_map, 725, 733, 828
passwd_entry, 948
pattern, 890, 895, 916
pattern_desc, 897
pause, 944, 979
payload, 892, 917
peek, 797
peek_opt, 797
perform, 613
pi, 630
pipe, 938
polar, 606
poll, 985
pop, 797, 838
pop_opt, 838
pos, 701, 784
pos_in, 515

pos_out, 512, 515
position, 716
pow, 606, 631
pp_close_box, 651
pp_close_stag, 661
pp_close_tbox, 659
pp_force_newline, 654
pp_get_ellipsis_text, 659
pp_get_formatter_out_functions, 664
pp_get_formatter_output_functions, 663
pp_get_formatter_stag_functions, 665
pp_get_geometry, 658
pp_get_margin, 656
pp_get_markelpop, 662
pp_get_max boxes, 658
pp_get_max indent, 657
pp_get_printelpop, 662
pp_open_box, 651
pp_open_hbox, 651
pp_open_hvbox, 652
pp_open_hvbox, 652
pp_open_stag, 661
pp_open_tbox, 658
pp_open_vbox, 652
pp_over_max boxes, 658
pp_print_array, 669
pp_print_as, 652
pp_print_bool, 653
pp_print_break, 653
pp_print_bytes, 652
pp_print_char, 653
pp_print_custom_break, 654
pp_print_cut, 653
pp_print_either, 670
pp_print_float, 653
pp_print_flush, 655
pp_print_if_newline, 654
pp_print_int, 652
pp_print_iter, 669
pp_print_list, 669
pp_print_newline, 655
pp_print_option, 670
pp_print_result, 670
pp_print_seq, 669
pp_print_space, 653
Return the value associated to a variable in the process environment.

Unlike Unix.getenv[31.1], this function returns the value even if the process has special privileges. It is considered unsafe because the programmer of a setuid or setgid program must be careful to avoid using maliciously crafted environment variables in the search path for executables, the locations for temporary files or logs, and the like.

Since: 4.06

Raises Not_found if the variable is unbound.

val putenv : string -> string -> unit

putenv name value sets the value associated to a variable in the process environment. name is the name of the environment variable, and value its new associated value.

Process handling

type process_status =

| WEXITED of int

The process terminated normally by exit; the argument is the return code.

| WSIGNALED of Sys.signal

The process was killed by a signal; the argument is the signal number.

| WSTOPPED of Sys.signal

The process was stopped by a signal; the argument is the signal number.

The termination status of a process. See Sys.signal[29.60] for the definitions of the standard signal numbers.

On Windows: only WEXITED is used (as there are no inter-process signals) but with specific return codes to indicate special termination causes. Look for NTSTATUS values in the Windows documentation to decode such error return codes. In particular, STATUS_ACCESS_VIOLATION error code is the 32-bit 0xC0000005: as Int32.of_int 0xC0000005 is -1073741819, WEXITED -1073741819 is the Windows equivalent of WSIGNALED Sys.sigsegv.

type wait_flag =

| WNOHANG

Do not block if no child has died yet, but immediately return with a pid equal to 0.

| WUNTRACED

Report also the children that receive stop signals.

Flags for Unix.waitpid[31.1].

val execv : string -> string array -> 'a

execv prog args execute the program in file prog, with the arguments args, and the current process environment. Note that the first argument, args. (0), is by convention the
pp_print_string, 652
pp_print_tab, 659
pp_print_tbreak, 659
pp_print_text, 670
pp_safe_set_geometry, 657
pp_set_ellipsis_text, 659
pp_set_formatter_out_channel, 662
pp_set_formatter_out_functions, 664
pp_set_formatter_output_functions, 662
pp_set_formatter_stag_functions, 664
pp_set_geometry, 657
pp_setmargin, 655
pp_set_markos, 662
pp_set_max boxes, 658
pp_set_maxIndent, 656
pp_set_printos, 662
pp_set_tab, 659
pp_setos, 662
pp_update_geometry, 657
Pprintast, 916
pred, 499, 629, 703, 706, 711, 776, 869
prerr_alert, 888
prerr_bytes, 509
prerr_char, 509
prerr_endline, 509
prerr_float, 509
prerr_int, 509
prerr_newline, 509
prerr_string, 509
prerr_warning, 887
print, 787
print_alert, 888
print_as, 652
print_backtrace, 787
print_bool, 653
print_break, 653
print_bytes, 508, 652
print_char, 508, 653
print_cut, 653
print_endline, 509
print_filename, 885
print_float, 508, 653
print_flush, 655
print_if_newline, 654
print_int, 508, 652

print_loc, 885
printLocs, 885
print_newline, 509, 655
print_raw_backtrace, 789
print_report, 887
print_space, 653
print_stat, 682
print_string, 508, 652
print_tab, 659
print_tbreak, 659
print_warning, 887
Printexc, 521, 786
printf, 521, 793
printf, 672, 795
private_flag, 882
process_full_pid, 941
process_in_pid, 940
process_out_pid, 941
process_pid, 941
process_status, 925
process_times, 945
product, 827
prohibit, 989
protect, 676, 775
protocol_entry, 956
provably_equal, 867
public_dynamically_loaded_units, 989
push, 797, 838
putenv, 925
query, 620, 621, 623
Queue, 521, 797
quick_stat, 681
quiet_nan, 629
quote, 627, 966
quote_command, 627
raise, 494
raise_errorf, 889
raise_notrace, 494
raise_with_backtrace, 789
Random, 521, 801
randomize, 689, 750
raw_backtrace, 788
raw_backtrace_entries, 789
raw_backtrace_entry, 788
filename of the program being executed, just like `Sys.argv.(0)`. These `execv*` functions never return: on success, the current program is replaced by the new one.

On Windows: the CRT simply spawns a new process and exits the current one. This will have unwanted consequences if e.g. another process is waiting on the current one. Using `Unix.create_process[31.1]` or one of the `open_process_*` functions instead is recommended.

**Raises** `Unix_error` on failure

`val execve: string -> string array -> string array -> 'a`

Same as `Unix.execv[31.1]`, except that the third argument provides the environment to the program executed.

`val execvp: string -> string array -> 'a`

Same as `Unix.execv[31.1]`, except that the program is searched in the path.

`val execvpe: string -> string array -> string array -> 'a`

Same as `Unix.execve[31.1]`, except that the program is searched in the path.

`val fork: unit -> int`

Fork a new process. The returned integer is 0 for the child process, the pid of the child process for the parent process. It fails if the OCaml process is multi-core (any domain has been spawned). In addition, if any thread from the Thread module has been spawned, then the child process might be in a corrupted state.

**Raises**

* `Invalid_argument` on Windows. Use `Unix.create_process[31.1]` or threads instead.

* `Failure` if any domain has been spawned.

`val wait: unit -> int * process_status`

Wait until one of the children processes die, and return its pid and termination status.

**Raises** `Invalid_argument` on Windows. Use `Unix.waitpid[31.1]` instead.

`val waitpid: wait_flag list -> int -> int * process_status`

Same as `Unix.wait[31.1]`, but waits for the child process whose pid is given. A pid of -1 means wait for any child. A pid of 0 means wait for any child in the same process group as the current process. Negative pid arguments represent process groups. The list of options indicates whether `waitpid` should return immediately without waiting, and whether it should report stopped children.

On Windows: can only wait for a given PID, not any child process.

`val system: string -> process_status`
raw_backtrace_length, 792
raw_backtrace�, slot, 792
raw_backtrace_to_string, 789
rcontains_from, 581, 594, 842, 851
read, 929
read_arg, 530
read_arg0, 530
read_float, 510
read_float_opt, 510
read_int, 510
read_int_opt, 510
read_line, 510
read_poll, 979
readdir, 859, 938
readlink, 942
really_input, 514, 701
really_input_string, 514, 700
realpath, 935
rebuild, 690, 751
rec_flag, 882
receive, 984
recommended_domain_count, 610
record_backtrace, 787
recv, 952
recvfrom, 952
ref, 516
regexp, 965
regexp_caseFold, 966
regexp_string, 967
regexp_string_caseFold, 967
register, 603, 880, 977
register_error_of_exn, 889
register_exception, 604
register_function, 880
register_printers, 788
release, 836, 837
rem, 629, 703, 706, 710, 776
remove, 619, 621-623, 688, 693, 694, 737, 749,
      754, 756, 762, 769, 831, 858, 873
remove, 726, 734
removeass, 726, 734
removet, 625
rename, 858, 935
rep, 869
repeat, 822

replace, 619, 620, 688, 693, 695, 749, 754, 756
replace_first, 969
replace_match, 969
replace_seq, 619, 620, 691, 693, 695, 752,
      755, 757
report, 886
report_alert, 888
report_exception, 889
report, 886
report_printers, 886, 887
report_warning, 887
repr, 866
reset, 572, 619, 687, 692, 694, 748, 754, 756,
      884
reshape, 568
reshape_0, 568
reshape_1, 568
reshape_2, 568
reshape_3, 568
Result, 521, 804
result, 516
resume, 979
return, 822
rev, 720, 729
rev_append, 721, 729
rev_map, 722, 730
rev_map2, 723, 731
rewinddir, 938
rewrite�r absolute_path, 884
rewrite_find_all_existing_dirs, 884
rewrite_find_first_existing, 884
rhs end, 786
rhs end pos, 786
rhs_interval, 883
rhs loc, 883
rhs start, 785
rhs_start_pos, 786
right, 616
rindex, 580, 593, 846, 854
rindex_from, 580, 594, 845, 854
rindex_from_opt, 580, 594, 845, 854
rindex_opt, 580, 593, 846, 854
rmdir, 859, 938
round, 634
row_field, 895
Execute the given command, wait until it terminates, and return its termination status. The string is interpreted by the shell `/bin/sh` (or the command interpreter `cmd.exe` on Windows) and therefore can contain redirections, quotes, variables, etc. To properly quote whitespace and shell special characters occurring in file names or command arguments, the use of `Filename.quote_command[29.21]` is recommended. The result `WEXITED 127` indicates that the shell couldn't be executed.

**`val_exit` : `int` -> 'a**

Terminate the calling process immediately, returning the given status code to the operating system: usually 0 to indicate no errors, and a small positive integer to indicate failure. Unlike `exit[28.2]`, `Unix._exit[31.1]` performs no finalization whatsoever: functions registered with `at_exit[28.2]` are not called, input/output channels are not flushed, and the C run-time system is not finalized either.

The typical use of `Unix._exit[31.1]` is after a `Unix.fork[31.1]` operation, when the child process runs into a fatal error and must exit. In this case, it is preferable to not perform any finalization action in the child process, as these actions could interfere with similar actions performed by the parent process. For example, output channels should not be flushed by the child process, as the parent process may flush them again later, resulting in duplicate output.

**Since: 4.12**

**`val getpid` : `unit` -> `int`**

Return the pid of the process.

**`val getppid` : `unit` -> `int`**

Return the pid of the parent process.

**Raises Invalid_argument on Windows (because it is meaningless)**

**`val nice` : `int` -> `int`**

Change the process priority. The integer argument is added to the "nice" value. (Higher values of the "nice" value mean lower priorities.) Return the new nice value.

**Raises Invalid_argument on Windows**

## Basic file input/output

**`type file_descr`**

The abstract type of file descriptors.

**`val stdin` : `file_descr`**

File descriptor for standard input.

**`val stdout` : `file_descr`**

File descriptor for standard output.
row_field_desc, 895
run_main, 880
runtime_counter, 974
runtime_counter_name, 976
Runtime_events, 973
runtime_parameters, 861
runtime_phase, 975
runtime_phase_name, 976
runtime_variant, 861
runtime_warnings_enabled, 865
S, 618, 692, 737, 754, 761, 768, 830, 873
safe_set_geometry, 657
scan, 824
Scan_failure, 810
scanbuf, 808
Scanf, 521, 806
scanf, 815
scanf_opt, 815
scanner, 810
scanner_opt, 810
Scanning, 808
search, 967
search_forward, 967
seeded_hash, 570, 605, 636, 694, 696, 705, 709, 713, 755, 758, 779, 848, 857
seeded_hash_param, 696, 758
SeededHashedType, 694, 755
SeededS, 619, 694, 756
seek, 701, 784
seek_command, 930
seek_in, 515
seek_out, 512, 515
select, 942, 983, 985
self, 610, 982
self_init, 801
Semaphore, 521, 836
send, 952, 984
send_substring, 952
sendto, 952
sendto_substring, 952
separate_new_message, 884
Seq, 521, 816
service_entry, 956
Set, 521, 767, 829

set, 530, 538, 545, 555, 558, 560, 562, 565, 577, 590, 611, 636, 643, 682, 872
set_allowed_units, 988
set_binary_mode, 702, 784
set_binary_mode_in, 515
set_binary_mode_out, 513
set_buffered, 785
set_close_on_exec, 937
set cookie, 881
set_ellipsis_text, 659
set_filename, 718
set_formatter_out_channel, 662
set_formatter_out_functions, 664
set_formatter_output_functions, 662
set_formatter_stag_functions, 664
set_geometry, 657
set_int16_be, 588, 601
set_int16_le, 588, 602
set_int16_ne, 588, 601
set_int32_be, 588, 602
set_int32_le, 588, 602
set_int32_ne, 588, 602
set_int64_be, 588, 602
set_int64_le, 588, 602
set_int64_ne, 588, 602
set_int8, 587, 601
set_margin, 655
set_markelo, 662
set_max�, 658
set_max_mind, 656
set_nonblock, 936
set_position, 718
set_printelo, 662
set_signal, 862
set_state, 804
set_tab, 659
setelo, 662
set_temp_dir_name, 627
set_trace, 786
set_uint16_be, 587, 601
set_uint16_le, 588, 601
set_uint16_ne, 587, 601
set_uint8, 587, 601
set_uncaught_exception_handler, 790, 984
set_utf_16be_uchar, 585, 598
`val stderr : file_descr`

File descriptor for standard error.

`type open_flag =`

| `O_RDONLY`

Open for reading

| `O_WRONLY`

Open for writing

| `O_RDWR`

Open for reading and writing

| `O_NONBLOCK`

Open in non-blocking mode

| `O_APPEND`

Open for append

| `O_CREAT`

Create if nonexistent

| `O_TRUNC`

Truncate to 0 length if existing

| `O_EXCL`

Fail if existing

| `O_NOCTTY`

Don't make this dev a controlling tty

| `O_DSYNC`

Writes complete as 'Synchronised I/O data integrity completion'

| `O_SYNC`

Writes complete as 'Synchronised I/O file integrity completion'

| `O_RSYNC`

Reads complete as writes (depending on `O_SYNC/O_DSYNC`)

| `O_SHARE_DELETE`

Windows only: allow the file to be deleted while still open

| `O_CLOEXEC`

Set the close-on-exec flag on the descriptor returned by `Unix.openfile[31.1]`. See `Unix.set_close_on_exec[31.1]` for more information.

| `O_KEEPEXEC`

Clear the close-on-exec flag. This is currently the default.
set_utf_16le_uchar, 585, 599
set_utf_8_uchar, 585, 598
setattr When, 961
setgid, 948
setgroups, 948
setitimer, 947
setsid, 962
setsockopt, 954
setsockopt_float, 955
setsockopt_int, 954
setsockopt_optint, 954
setuid, 947
Shallow, 615
shift_left, 704, 707, 711, 777
shift_right, 704, 707, 711, 777
shift_rightlogical, 704, 707, 711, 777
show_filename, 885
shutdown, 952
shutdown_command, 951
shutdown_connection, 955
sigabrt, 862
sigalrm, 862
sigbus, 863
sigchld, 863
sigcont, 863
sigfpe, 862
sighup, 862
sigill, 862
sigint, 862
sigkill, 862
sigmask, 983
sign bit, 634
signal, 609, 861
signal� behavior, 861
signaling_nan, 629
signature, 910, 916
signature_item, 910, 917
signature_item_desc, 911
sigpending, 944
sigpipe, 862
sigpoll, 863
sigprocmask, 944
sigprocmask_command, 944
sigprof, 863
sigquit, 862

sigsegv, 862
sigstop, 863
sigsuspend, 944
sigsys, 863
sigterm, 862
sigtrap, 863
sigtstp, 863
sigttin, 863
sigttou, 863
sigurg, 864
sigusr1, 862
sigusr2, 863
sigvtalrm, 863
sigxcpu, 864
sigxfsz, 864
simple_module_path, 891
sin, 502, 632
single_write, 929
single_write_substring, 929
singleton, 737, 762, 769, 830
sinh, 503, 633
size, 776
size_in_bytes, 554, 558, 559, 562, 565
sleep, 946
sleepf, 946
slice, 560
slice left, 556, 563
slice left 1, 566
slice left 2, 566
slice right, 556, 563
slice right 1, 566
slice right 2, 566
Slot, 791
snd, 507
sockaddr, 950
socket, 951
socket bool option, 953
socket_domain, 950
socket float option, 954
socket int option, 954
socket_optint_option, 954
socket type, 950
socketpair, 951
some, 780
sort, 535, 542, 640, 646, 726, 735
The flags to Unix.openfile[31.1].

type file_perm = int

The type of file access rights, e.g. 0o640 is read and write for user, read for group, none for others

val openfile : string -> open_flag list -> file_perm -> file_descr

Open the named file with the given flags. Third argument is the permissions to give to the file if it is created (see Unix.umask[31.1]). Return a file descriptor on the named file.

val close : file_descr -> unit

Close a file descriptor.

val fsync : file_descr -> unit

Flush file buffers to disk.

Since: 4.08 (4.12 in UnixLabels)

val read : file_descr -> bytes -> int -> int -> int

read fd buf pos len reads len bytes from descriptor fd, storing them in byte sequence buf, starting at position pos in buf. Return the number of bytes actually read.

val read_bigarray :

file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)

Bigarray Array1.t -> int -> int -> int

Same as Unix.read[31.1], but read the data into a bigarray.

Since: 5.2

val write : file_descr -> bytes -> int -> int -> int

write fd buf pos len writes len bytes to descriptor fd, taking them from byte sequence buf, starting at position pos in buff. Return the number of bytes actually written. write repeats the writing operation until all bytes have been written or an error occurs.

val write_bigarray :

file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)

Bigarray.array1.t -> int -> int -> int

Same as Unix.write[31.1], but take the data from a bigarray.

Since: 5.2

val single_write : file_descr -> bytes -> int -> int -> int

Same as Unix.write[31.1], but attempts to write only once. Thus, if an error occurs, single_write guarantees that no data has been written.
sort_uniq, 727, 735
sorted_merge, 827
space_formatter, 916
span, 976
spawn, 609
spec, 527
split, 535, 542, 726, 734, 741, 766, 772, 803, 804, 828, 834, 970
split_delim, 970
split_on_char, 584, 597, 843, 851
split_result, 970
sprintf, 672, 795
sqrt, 502, 606, 632
sscanf, 815
sscanf_format, 816
sscanf_opt, 815
stable_sort, 535, 543, 640, 647, 727, 735
Stack, 521, 838
Stack_overflow, 495
Stack_overflow, 493
stag, 660
start, 685, 979
starts_with, 582, 595, 842, 851
stat, 678, 681, 932, 933
State, 802
statistics, 690, 752
stats, 619, 620, 690, 693, 695, 752, 754, 756, 874, 932, 933
stats_alive, 619, 620
std_formatter, 665
stdbuf, 666
stderr, 508, 782, 927
stdin, 508, 699, 808, 927
StdLabels, 521, 840
Stdlib, 494
stdout, 508, 782, 927
stop, 686
Str, 965
str_formatter, 666
String, 521, 840
string, 492, 612
string_after, 970
string_before, 970
string_match, 967
string_of_bool, 506

string_of_expression, 916
string_of_float, 507
string_of_format, 518
string_of_inet_addr, 949
string_of_int, 506
string_of_structure, 916
string_partial_match, 967
StringLabels, 521, 849
structure, 914, 916
structure_item, 914, 917
structure_item_desc, 915
sub, 531, 539, 560, 571, 577, 591, 606, 628, 637, 643, 703, 706, 710, 775, 843, 851
sub_left, 555, 562, 565
sub_right, 555, 562, 565
sub_string, 577, 591
subbytes, 612
subset, 773, 834
substitute_first, 969
substring, 612
succ, 499, 629, 703, 706, 711, 776, 869
symbol_end, 785
symbol_end_pos, 786
symbol_gloc, 883
symbol_rloc, 883
symbol_start, 785
symbol_start_pos, 786
symbolic_output_buffer, 668
symbolic_output_item, 668
symlink, 941
sync, 985
synchronized_formatter_of_out_channel, 665
Sys, 521, 858
Sys_blocks_io, 495
Sys_error, 495
Sys_blocks_io, 494
Sys_error, 493
system, 926

t, 530, 537, 545, 552, 557, 558, 561, 564, 570, 571, 581, 595, 604, 605, 608, 609, 612, 613, 616, 618–623, 635, 636, 642, 687, 692, 694, 698, 703, 708, 713, 714, 719, 727, 736, 737, 748, 753–756, 761, 768,
val write_substring : file_descr -> string -> int -> int -> int

Same as Unix.write[31.1], but take the data from a string instead of a byte sequence.

Since: 4.02

val single_write_substring : file_descr -> string -> int -> int -> int

Same as Unix.single_write[31.1], but take the data from a string instead of a byte sequence.

Since: 4.02

val single_write_bigarray :

file_descr ->
('a, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray Array1.t -> int -> int -> int

Same as Unix.single_write[31.1], but take the data from a bigarray.

Since: 5.2

## Interfacing with the standard input/output library

val in_channel_of_descr : file_descr -> in_channel

Create an input channel reading from the given descriptor. The channel is initially in binary mode; use `set_binary_mode_in` if text mode is desired. Text mode is supported only if the descriptor refers to a file or pipe, but is not supported if it refers to a socket.

On Windows: `set_binary_mode_in`[28.2] always fails on channels created with this function.

Beware that input channels are buffered, so more characters may have been read from the descriptor than those accessed using channel functions. Channels also keep a copy of the current position in the file.

Closing the channel `ic` returned by `in_channel_of_descr` `fd` using `close_in` `ic` also closes the underlying descriptor `fd`. It is incorrect to close both the channel `ic` and the descriptor `fd`.

If several channels are created on the same descriptor, one of the channels must be closed, but not the others. Consider for example a descriptor `s` connected to a socket and two channels `ic = in_channel_of_descr s` and `oc = out_channel_of_descr s`. The recommended closing protocol is to perform `close_out oc`, which flushes buffered output to the socket then closes the socket. The `ic` channel must not be closed and will be collected by the GC eventually.

val out_channel_of_descr : file_descr -> out_channel

Create an output channel writing on the given descriptor. The channel is initially in binary mode; use `set_binary_mode_out` if text mode is desired. Text mode is supported only if the descriptor refers to a file or pipe, but is not supported if it refers to a socket.

On Windows: `set_binary_mode_out`[28.2] always fails on channels created with this function.
769, 774, 778, 780, 781, 786, 791, 797, 802, 804, 817, 830, 836–838, 841, 849, 866–868, 871, 873, 883, 890, 976–978, 981
tag, 661, 977
take, 797, 824
take_opt, 797
takewhile, 824
tan, 502, 632
tanh, 503, 633
tcdrain, 961
tcflow, 962
tcflush, 961
tcgetattr, 961
tcsendbreak, 961
tcsetattr, 961
temp_dir, 626
temp_file, 626
terminal_io, 961
terminfo_tLEVELer, 886
Thread, 981
time, 859, 945
times, 946
Timestamp, 976
tl, 720, 728
tm, 945
to_binary_string, 803
to_buffer, 745
to_bytes, 571, 745, 841, 850
to_channel, 744
to_char, 870
to_dispenser, 829
to_float, 570, 705, 708, 712, 778
to_hex, 613
to_int, 570, 630, 707, 712, 777, 869
to_int32, 712, 778
to_int64, 976
to_list, 532, 539, 638, 644, 742, 767, 773, 781, 806, 835
to_nativeint, 712
to_option, 806
to_result, 781
to_rev_seq, 743, 767, 773, 835
to_seq, 536, 543, 574, 584, 598, 640, 647, 690, 693, 695, 727, 735, 742, 752, 754, 756,

767, 773, 781, 798, 806, 835, 839, 846, 855
to_seq_from, 743, 767, 773, 835
to_seq_keys, 691, 693, 695, 752, 754, 757
to_seq_values, 691, 693, 695, 752, 755, 757
to_seqi, 536, 543, 574, 584, 598, 641, 647, 846, 855
to_string, 570, 577, 591, 631, 705, 708, 713, 745, 778, 786, 871
to_string_default, 787
tool_name, 879
top, 798, 838
top_opt, 839
top_phrase, 916
toplevel_directive, 916
toplevel_phrase, 890, 916
total_size, 746
tracker, 685
transfer, 798
transpose, 825
trim, 579, 593, 844, 852
trunc, 634
truncate, 504, 572, 931, 932
try_acquire, 836, 837
try_lock, 774
try_with, 614
Type, 521, 866, 976
type_declaration, 902
type_exception, 904
type_extension, 903
type_ident, 891
type, 902
tyvar, 917
Uchar, 522, 868
uid, 867
umask, 936
uncapitalize_ascii, 581, 595, 844, 853
uncons, 818
Undefined, 714
Undefined_recursive_module, 495
Undefined_recursive_module, 494
unescaped, 816
unflatten, 890
unfold, 822
Beware that output channels are buffered, so you may have to call `flush[28.2]` to ensure that all data has been sent to the descriptor. Channels also keep a copy of the current position in the file.

Closing the channel `oc` returned by `out_channel_of_descr fd` using `close_out oc` also closes the underlying descriptor `fd`. It is incorrect to close both the channel `ic` and the descriptor `fd`.

See `Unix.in_channel_of_descr[31.1]` for a discussion of the closing protocol when several channels are created on the same descriptor.

`val descr_of_in_channel : in_channel -> file_descr`

Return the descriptor corresponding to an input channel.

`val descr_of_out_channel : out_channel -> file_descr`

Return the descriptor corresponding to an output channel.

## Seeking and truncating

`type seek_command =`

`| SEEK_SET`

indicates positions relative to the beginning of the file

`| SEEK_CUR`

indicates positions relative to the current position

`| SEEK_END`

indicates positions relative to the end of the file

Positioning modes for `Unix.lseek[31.1]`.

`val lseek : file_descr -> int -> seek_command -> int`

Set the current position for a file descriptor, and return the resulting offset (from the beginning of the file).

`val truncate : string -> int -> unit`

Truncates the named file to the given size.

`val ftruncate : file_descr -> int -> unit`

Truncates the file corresponding to the given descriptor to the given size.
Unhandled, 613
union, 738, 762, 769, 831
Unit, 522, 871
unit, 492, 976
Unix, 919
unix, 860
Unix_error, 924
UnixLabels (module), 962
unlink, 935
 unlock, 774
unsafe_environment, 924
unsafe_get, 560, 563, 567
unsafe_getenv, 924
unsafe_of_string, 583, 597
unsafe_set, 560, 563, 567
unsafe_to_string, 582, 595
unsigned_compare, 709, 713, 778
unsigned_div, 706, 710, 776
unsigned_rem, 706, 710, 776
unsigned_to_int, 707, 712, 777
unzip, 828
update, 737, 762
update_geometry, 658
uppercase_ascii, 581, 594, 604, 844, 853
usage, 529
usage msg, 527
usage_string, 529
use_file, 890
use_printers, 788
User, 977
utf_16_byte_length, 871
utf_8Byte_length, 871
utf_decode, 870
utf_decode_valid, 870
utf_decode_is_valid, 870
utf_decode_length, 870
utf_decode_uchar, 870
utimes, 946
val_ident, 891
value, 780, 805
value_bind, 915
value_constraint, 915
value_description, 901
variance, 882

virtual_flag, 882
wait, 609, 926
wait_flag, 925
wait_pid, 983
wait_signal, 984
wait_timed_read, 983
wait_timed_write, 983
waitpid, 926
warning_reporter, 887
Weak, 522, 871
win32, 860
with_constraint, 913
with_open_bin, 699, 783
with_open_gen, 700, 783
with_open_text, 699, 783
with positions, 718
word_size, 860
wrap, 985
wrap_abort, 985
write, 929, 977
write_arg, 530
write_arg0, 530
write_substring, 929
yield, 982
zero, 605, 628, 703, 705, 710, 775
zip, 826
File status

type file kind =

| S_REG
Regular file

| S_DIR
Directory

| S CHR
Character device

| S BLK
Block device

| S LNK
Symbolic link

| S FIFO
Named pipe

| S SOCK
Socket

type stats =

{ st_dev : int ;
Device number

st_ino : int ;
Inode number

st kind : file kind ;
Kind of the file

stperm : fileperm ;
Access rights

st_nlink : int ;
Number of links

st_uid : int ;
User id of the owner

st gid : int ;
Group ID of the file's group

st_rdev : int ;
Device ID (if special file)

st_size : int ;
Size in bytes
Index of keywords

and, 171, 193, 198, 202, 203, 207, 214, 219
as, 160, 161, 164, 165, 198, 200
asr, 158, 172, 186
assert, 191

begin, 163, 171, 173

class, 202, 203, 205, 207, 209
constraint, 193, 196, 198, 202

do, see while, for
done, see while, for
downto, see for

else, see if
end, 163, 171, 173, 196, 198, 203, 204, 207, 208
exception, 196, 203, 205, 207, 209
external, 203, 204, 207, 209

false, 163
for, 171, 182
fun, 171, 172, 176, 198, 218
function, 171, 172, 175
functor, 203, 206, 207, 210

if, 171, 172, 180
in, see let
include, 203, 206, 207, 210, 222
inherit, 196, 198, 200
initializer, 198, 202

land, 158, 172, 186
lazy, 169, 171, 192
let, 171, 172, 178, 192, 198, 207, 209
lor, 158, 172, 186
lsl, 158, 172, 186
lsr, 158, 172, 186
lxor, 158, 172, 186

match, 171, 172, 180, 227
method, 196, 198, 201, 202
mod, 158, 172, 186
module, 192, 203, 206, 207, 209, 210, 214, 219,
222, 225
open, 192

mutable, 193, 195, 196, 198, 201
new, 171, 187
nonrec, 193

object, 171, 188, 196, 198
of, 162, 193, 222
open, 169, 203, 206, 207, 210
open!, 227
or, 171, 172, 181

private, 196, 198, 201, 202, 216, 217

rec, see let, module

sig, 203, 204
struct, 207, 208

then, see if
to, see for
true, 163
try, 171, 172, 182
type, 193, 203–207, 209, 210, 218, 222, 227

val, 196, 198, 201, 203, 204, 219
virtual, see val, method, class

when, 171, 177, 228
while, 182
with, 171, 203, 207, 219, 222
st_atime : float ;
Last access time

st_mtime : float ;
Last modification time

st_ctime : float ;
Last status change time
}
The information returned by the Unix.stat[31.1] calls.

val stat : string -> stats

Return the information for the named file.

val lstat : string -> stats

Same as Unix.stat[31.1], but in case the file is a symbolic link, return the information for the link itself.

val fstat : file_descr -> stats

Return the information for the file associated with the given descriptor.

val isatty : file_descr -> bool

Return true if the given file descriptor refers to a terminal or console window, false otherwise.

File operations on large files

module LargeFile :
sig
    val lseek : Unix.file_descr -> int64 -> Unix.seek_command -> int64
        See lseek.
    val truncate : string -> int64 -> unit
        See truncate.
    val ftruncate : Unix.file_descr -> int64 -> unit
        See ftruncate.
type stats =
    { st_dev : int ;
        Device number
    st_ino : int ;
Inode number
st kind : Unix.file kind ;
Kind of the file
st perm : Unix.file perm ;
Access rights
st nlink : int ;
Number of links
st uid : int ;
User id of the owner
st gid : int ;
Group ID of the file's group
st rdev : int ;
Device ID (if special file)
st size : int64 ;
Size in bytes
st_atime : float ;
Last access time
st mtime : float ;
Last modification time
st ctime : float ;
Last status change time
}
val stat : string -> stats
val lstat : string -> stats
val fstat : Unix.file_descr -> stats
end

File operations on large files. This sub-module provides 64-bit variants of the functions Unix.LargeFile.lseek[31.1] (for positioning a file descriptor), Unix.LargeFile.truncate[31.1] and Unix.LargeFile.ftruncate[31.1] (for changing the size of a file), and Unix.LargeFile.stat[31.1], Unix.LargeFile.lstat[31.1] and Unix.LargeFile.fstat[31.1] (for obtaining information on files). These alternate functions represent positions and sizes by 64-bit integers (type int64) instead of regular integers (type int), thus allowing operating on files whose sizes are greater than max_int.
Mapping files into memory

```hcl
val map_file :
    file_descr ->
    ?pos:int64 ->
    ('a, 'b) Bigarray.kind ->
    'c Bigarraylayout ->
    bool -> int array -> ('a, 'b, 'c) Bigarray.Genarray.t
```

Memory mapping of a file as a Bigarray. `map_file fd kind layout shared dims` returns a Bigarray of kind `kind`, layout `layout`, and dimensions as specified in `dims`. The data contained in this Bigarray are the contents of the file referred to by the file descriptor `fd` (as opened previously with `Unix.openfile[31.1]`, for example). The optional `pos` parameter is the byte offset in the file of the data being mapped; it defaults to 0 (map from the beginning of the file).

If `shared` is `true`, all modifications performed on the array are reflected in the file. This requires that `fd` be opened with write permissions. If `shared` is `false`, modifications performed on the array are done in memory only, using copy-on-write of the modified pages; the underlying file is not affected.

`Unix.map_file[31.1]` is much more efficient than reading the whole file in a Bigarray, modifying that Bigarray, and writing it afterwards.

To adjust automatically the dimensions of the Bigarray to the actual size of the file, the major dimension (that is, the first dimension for an array with C layout, and the last dimension for an array with Fortran layout) can be given as `-1`. `Unix.map_file[31.1]` then determines the major dimension from the size of the file. The file must contain an integral number of sub-arrays as determined by the non-major dimensions, otherwise `Failure` is raised.

If all dimensions of the Bigarray are given, the file size is matched against the size of the Bigarray. If the file is larger than the Bigarray, only the initial portion of the file is mapped to the Bigarray. If the file is smaller than the big array, the file is automatically grown to the size of the Bigarray. This requires write permissions on `fd`.

Array accesses are bounds-checked, but the bounds are determined by the initial call to `map_file`. Therefore, you should make sure no other process modifies the mapped file while you're accessing it, or a `SIGBUS` signal may be raised. This happens, for instance, if the file is shrunk.

`Invalid_argument` or `Failure` may be raised in cases where argument validation fails.

Since: 4.06

Operations on file names

```hcl
val unlink : string -> unit
```

Removes the named file.

If the named file is a directory, raises:
* EPERM on POSIX compliant system

* EISDIR on Linux ≥ 2.1.132

* EACCESS on Windows

**val rename : string -> string -> unit**

`rename src dst` changes the name of a file from `src` to `dst`, moving it between directories if needed. If `dst` already exists, its contents will be replaced with those of `src`. Depending on the operating system, the metadata (permissions, owner, etc) of `dst` can either be preserved or be replaced by those of `src`.

**val link : ?follow:bool -> string -> string -> unit**

`link ?follow src dst` creates a hard link named `dst` to the file named `src`.

**Raises**

* ENOSYS On Unix if `?follow:` is requested, but `linkat` is unavailable.

* ENOSYS On Windows if `?follow`:false is requested.

**val realpath : string -> string**

`realpath p` is an absolute pathname for `p` obtained by resolving all extra / characters, relative path segments and symbolic links.

**Since:** 4.13

## File permissions and ownership

**type access permission =**

| R_OK

Read permission

| W_OK

Write permission

| X_OK

Execution permission

| F_OK

File exists

Flags for the Unix.access[31.1] call.

**val chmod : string -> file perm -> unit**

Change the permissions of the named file.

**val fchmod : file descr -> file perm -> unit**
Change the permissions of an opened file.

**Raises** Invalid_argument on Windows

val chown : string -> int -> int -> unit

Change the owner uid and owner gid of the named file.

**Raises** Invalid_argument on Windows

val fchown : file_descr -> int -> int -> unit

Change the owner uid and owner gid of an opened file.

**Raises** Invalid_argument on Windows

val umask : file_perm -> file_perm

Set the process's file mode creation mask, and return the previous mask.

**Raises** Invalid_argument on Windows

val access : string -> access permission list -> unit

Check that the process has the given permissions over the named file.

On Windows: execute permission X_OK cannot be tested, just tests for read permission instead.

**Raises** Unix_error otherwise.

## Operations on file descriptors

val dup : ?cloexec:bool -> file_descr -> file_descr

Return a new file descriptor referencing the same file as the given descriptor. See Unix.set_close_on_exec[31.1] for documentation on the cloexec optional argument.

val dup2 : ?cloexec:bool -> file_descr -> file_descr -> unit

dup2 src dst duplicates src to dst, closing dst if already opened. See Unix.set_close_on_exec[31.1] for documentation on the cloexec optional argument.

val set_nonblock : file_descr -> unit

Set the "non-blocking" flag on the given descriptor. When the non-blocking flag is set, reading on a descriptor on which there is temporarily no data available raises the EAGAIN or EWOULDBLOCK error instead of blocking; writing on a descriptor on which there is temporarily no room for writing also raises EAGAIN or EWOULDBLOCK.

val clear_nonblock : file_descr -> unit

Clear the "non-blocking" flag on the given descriptor. See Unix.set_nonblock[31.1].

val set_close_on_exec : file_descr -> unit
Set the “close-on-exec” flag on the given descriptor. A descriptor with the close-on-exec flag is automatically closed when the current process starts another program with one of the `exec`, `create_process` and `open_process` functions.

It is often a security hole to leak file descriptors opened on, say, a private file to an external program: the program, then, gets access to the private file and can do bad things with it. Hence, it is highly recommended to set all file descriptors “close-on-exec”, except in the very few cases where a file descriptor actually needs to be transmitted to another program.

The best way to set a file descriptor “close-on-exec” is to create it in this state. To this end, the `openfile` function has `O_CLOEXEC` and `O_KEEPEXEC` flags to enforce “close-on-exec” mode or “keep-on-exec” mode, respectively. All other operations in the Unix module that create file descriptors have an optional argument `?cloexec:bool` to indicate whether the file descriptor should be created in “close-on-exec” mode (by writing `~cloexec:true`) or in “keep-on-exec” mode (by writing `~cloexec:false`). For historical reasons, the default file descriptor creation mode is “keep-on-exec”, if no `cloexec` optional argument is given. This is not a safe default, hence it is highly recommended to pass explicit `cloexec` arguments to operations that create file descriptors.

The `cloexec` optional arguments and the `O_KEEPEXEC` flag were introduced in OCaml 4.05. Earlier, the common practice was to create file descriptors in the default, “keep-on-exec” mode, then call `set_close_on_exec` on those freshly-created file descriptors. This is not as safe as creating the file descriptor in “close-on-exec” mode because, in multithreaded programs, a window of vulnerability exists between the time when the file descriptor is created and the time `set_close_on_exec` completes. If another thread spawns another program during this window, the descriptor will leak, as it is still in the “keep-on-exec” mode.

Regarding the atomicity guarantees given by `~cloexec:true` or by the use of the `O_CLOEXEC` flag: on all platforms it is guaranteed that a concurrently-executing Caml thread cannot leak the descriptor by starting a new process. On Linux, this guarantee extends to concurrently-executing C threads. As of Feb 2017, other operating systems lack the necessary system calls and still expose a window of vulnerability during which a C thread can see the newly-created file descriptor in “keep-on-exec” mode.

val clear_close_on_exec : file_descr -> unit

Clear the “close-on-exec” flag on the given descriptor. See Unix.set_close_on_exec[31.1].

## Directories

val mkdir : string -> file_perm -> unit

Create a directory with the given permissions (see Unix.umask[31.1]).

val rmdir : string -> unit

Remove an empty directory.

val chdir : string -> unit

Change the process working directory.
val getcwd : unit -> string

Return the name of the current working directory.

val chroot : string -> unit

Change the process root directory.

Raises Invalid_argument on Windows

type dir_handle

The type of descriptors over opened directories.

val opendir : string -> dir_handle

Open a descriptor on a directory

val readdir : dir_handle -> string

Return the next entry in a directory.

Raises End_of_file when the end of the directory has been reached.

val rewinddir : dir_handle -> unit

Reposition the descriptor to the beginning of the directory

val closedir : dir_handle -> unit

Close a directory descriptor.

Pipes and redirections

val pipe : ?cloexec:bool -> unit -> file_descr * file_descr

Create a pipe. The first component of the result is opened for reading, that's the exit to the
pipe. The second component is opened for writing, that's the entrance to the pipe. See
Unix.set_close_on_exec[31.1] for documentation on the cloexec optional argument.

val mkfifo : string -> file_perm -> unit

Create a named pipe with the given permissions (see Unix.umask[31.1]).

Raises Invalid_argument on Windows

High-level process and redirection management

val create_process :

string ->

string array -> file_descr -> file_descr -> file_descr -> int
`create_process prog args stdin stdout stderr` creates a new process that executes the program in file `prog`, with arguments `args`. Note that the first argument, `args.(0)`, is by convention the filename of the program being executed, just like `Sys.argv.(0)`. The pid of the new process is returned immediately; the new process executes concurrently with the current process. The standard input and outputs of the new process are connected to the descriptors `stdin`, `stdout` and `stderr`. Passing e.g. `Unix.stdout[31.1]` for `stdout` prevents the redirection and causes the new process to have the same standard output as the current process. The executable file `prog` is searched in the path. The new process has the same environment as the current process.

**`val create_process_env`:**

```
string ->
string array ->
string array -> file_descr -> file_descr -> file_descr -> int
    create_process_env prog args env stdin stdout stderr works as
    Unix.create_process[31.1], except that the extra argument env specifies the environment
    passed to the program.
```

**`val open_process_in`:** `string -> in_channel`

High-level pipe and process management. This function runs the given command in parallel with the program. The standard output of the command is redirected to a pipe, which can be read via the returned input channel. The command is interpreted by the shell `/bin/sh` (or `cmd.exe` on Windows), cf. `Unix.system[31.1]`. The `Filename.quote_command[29.21]` function can be used to quote the command and its arguments as appropriate for the shell being used. If the command does not need to be run through the shell, `Unix.open_process_args_in[31.1]` can be used as a more robust and more efficient alternative to `Unix.open_process_in[31.1]`.

**`val open_process_out`:** `string -> out_channel`

Same as `Unix.open_process_in[31.1]`, but redirect the standard input of the command to a pipe. Data written to the returned output channel is sent to the standard input of the command. Warning: writes on output channels are buffered, hence be careful to call `flush[28.2]` at the right times to ensure correct synchronization. If the command does not need to be run through the shell, `Unix.open_process_args_out[31.1]` can be used instead of `Unix.open_process_out[31.1]`.

**`val open_process`:** `string -> in_channel * out_channel`

Same as `Unix.open_process_out[31.1]`, but redirects both the standard input and standard output of the command to pipes connected to the two returned channels. The input channel is connected to the output of the command, and the output channel to the input of the command. If the command does not need to be run through the shell, `Unix.open_process_args[31.1]` can be used instead of `Unix.open_process[31.1]`.

**`val open_process_full`:**

```
string ->
string array -> in_channel * out_channel * in_channel
```
Similar to Unix.open_process[31.1], but the second argument specifies the environment passed to the command. The result is a triple of channels connected respectively to the standard output, standard input, and standard error of the command. If the command does not need to be run through the shell, Unix.open_process_args_full[31.1] can be used instead of Unix.open_process_full[31.1].

val open_process_args : string -> string array -> in_channel * out_channel
open_process_args prog args runs the program prog with arguments args. Note that the
first argument, args.(0), is by convention the filename of the program being executed, just
like Sys.argv.(0). The new process executes concurrently with the current process. The
standard input and output of the new process are redirected to pipes, which can be
respectively read and written via the returned channels. The input channel is connected to
the output of the program, and the output channel to the input of the program.

Warning: writes on output channels are buffered, hence be careful to call flush[28.2] at the
right times to ensure correct synchronization.

The executable file prog is searched for in the path. This behaviour changed in 4.12;
previously prog was looked up only in the current directory.

The new process has the same environment as the current process.

Since: 4.08

val open_process_args_in : string -> string array -> in_channel
Same as Unix.open_process_args[31.1], but redirects only the standard output of the new
process.

Since: 4.08

val open_process_args_out : string -> string array -> out_channel
Same as Unix.open_process_args[31.1], but redirects only the standard input of the new
process.

Since: 4.08

val open_process_args_full :
string ->
string array ->
string array -> in_channel * out_channel * in_channel
Similar to Unix.open_process_args[31.1], but the third argument specifies the environment
passed to the new process. The result is a triple of channels connected respectively to the
standard output, standard input, and standard error of the program.

Since: 4.08

val process_in_pid : in_channel -> int
Return the pid of a process opened via Unix.open_process_args_in[31.1] or the pid of the
shell opened via Unix.open_process_in[31.1].

Since: 4.08 (4.12 in UnixLabels)
val process_out_pid : out_channel -> int

Return the pid of a process opened via Unix.open_process_args_out[31.1] or the pid of the shell opened via Unix.open_process_out[31.1].

**Since:** 4.08 (4.12 in UnixLabels)

val process_pid : in_channel * out_channel -> int

Return the pid of a process opened via Unix.open_process_args[31.1] or the pid of the shell opened via Unix.open_process_args[31.1].

**Since:** 4.08 (4.12 in UnixLabels)

val process_full_pid : in_channel * out_channel * in_channel -> int

Return the pid of a process opened via Unix.open_process_args_full[31.1] or the pid of the shell opened via Unix.open_process_full[31.1].

**Since:** 4.08 (4.12 in UnixLabels)

val close_process_in : in_channel -> process_status

Close channels opened by Unix.open_process_in[31.1], wait for the associated command to terminate, and return its termination status.

val close_process_out : out_channel -> process_status

Close channels opened by Unix.open_process_out[31.1], wait for the associated command to terminate, and return its termination status.

val close_process : in_channel * out_channel -> process_status

Close channels opened by Unix.open_process[31.1], wait for the associated command to terminate, and return its termination status.

val close_process_full :

in_channel * out_channel * in_channel ->

process_status

Close channels opened by Unix.open_process_full[31.1], wait for the associated command to terminate, and return its termination status.

## Symbolic links

val symlink : ?to_dir:bool -> string -> string -> unit

symlink ?to_dir src dst creates the file dst as a symbolic link to the file src. On Windows, `~to_dir` indicates if the symbolic link points to a directory or a file; if omitted, symlink examines src using stat and picks appropriately, if src does not exist then false is assumed (for this reason, it is recommended that the `~to_dir` parameter be specified in new code). On Unix, `~to_dir` is ignored.

Windows symbolic links are available in Windows Vista onwards. There are some important differences between Windows symlinks and their POSIX counterparts.
Windows symbolic links come in two flavours: directory and regular, which designate whether the symbolic link points to a directory or a file. The type must be correct - a directory symlink which actually points to a file cannot be selected with chdir and a file symlink which actually points to a directory cannot be read or written (note that Cygwin's emulation layer ignores this distinction).

When symbolic links are created to existing targets, this distinction doesn't matter and **symlink** will automatically create the correct kind of symbolic link. The distinction matters when a symbolic link is created to a non-existent target.

The other caveat is that by default symbolic links are a privileged operation. Administrators will always need to be running elevated (or with UAC disabled) and by default normal user accounts need to be granted the SeCreateSymbolicLinkPrivilege via Local Security Policy (secpol.msc) or via Active Directory.

`Unix.has_symlink[31.1]` can be used to check that a process is able to create symbolic links.

**val has_symlink : unit -> bool**

Returns **true** if the user is able to create symbolic links. On Windows, this indicates that the user not only has the SeCreateSymbolicLinkPrivilege but is also running elevated, if necessary. On other platforms, this is simply indicates that the symlink system call is available.

**Since: 4.03**

**val readlink : string -> string**

Read the contents of a symbolic link.

## Polling

**val select :**

```
file_descr list ->
```

```
file_descr list ->
```

```
file_descr list ->
```

```
float -> file_descr list * file_descr list * file_descr list
```

Wait until some input/output operations become possible on some channels. The three list arguments are, respectively, a set of descriptors to check for reading (first argument), for writing (second argument), or for exceptional conditions (third argument). The fourth argument is the maximal timeout, in seconds; a negative fourth argument means no timeout (unbounded wait). The result is composed of three sets of descriptors: those ready for reading (first component), ready for writing (second component), and over which an exceptional condition is pending (third component).

On Windows, if one of descriptor lists exceeds `FD_SETSIZE` elements (64 by default), or if at least one non-socket file descriptor is used, the maximal timeout is capped to $2^{32}$ milliseconds.
Locking

type lock_command =

| FULOCK

Unlock a region

| F_LOCK

Lock a region for writing, and block if already locked

| F_TLOCK

Lock a region for writing, or fail if already locked

| F_TEST

Test a region for other process locks

| FRLOCK

Lock a region for reading, and block if already locked

| F_RLOCK

Lock a region for reading, or fail if already locked

Commands for Unix.lockf[31.1].

val lockf : file_descr -> lock_command -> int -> unit

lockf fd mode len puts a lock on a region of the file opened as fd. The region starts at the
current read/write position for fd (as set by Unix.lseek[31.1]), and extends len bytes
forward if len is positive, len bytes backwards if len is negative, or to the end of the file if
len is zero. A write lock prevents any other process from acquiring a read or write lock on
the region. A read lock prevents any other process from acquiring a write lock on the region,
but lets other processes acquire read locks on it.

The F_LOCK and F_TLOCK commands attempts to put a write lock on the specified region. The F_RLOCK and F_TRLOCK commands attempts to put a read lock on the specified region. If one or several locks put by another process prevent the current process from acquiring the lock, F_LOCK and F_RLOCK block until these locks are removed, while F_TLOCK and F_TRLOCK fail immediately with an exception. The F_ULOCK removes whatever locks the current process has on the specified region. Finally, the F_TEST command tests whether a write lock can be acquired on the specified region, without actually putting a lock. It returns immediately if successful, or fails otherwise.

What happens when a process tries to lock a region of a file that is already locked by the
same process depends on the OS. On POSIX-compliant systems, the second lock operation
succeeds and may "promote" the older lock from read lock to write lock. On Windows, the
second lock operation will block or fail.
Signals

Note: installation of signal handlers is performed via the functions Sys.signal[29.60] and Sys.set-
signal[29.60].

val kill : int -> Sys.signal -> unit

kill pid signal sends signal number signal to the process with id pid.

On Windows: only the Sys sigkill[29.60] signal is emulated.

type sigprocmask_command =
| SIG_SETMASK
| SIG_BLOCK
| SIG_UNBLOCK

val sigprocmask : sigprocmask_command -> Sys.signal list -> Sys.signal list

sigprocmask mode sigs changes the set of blocked signals. If mode is SIG_SETMASK, blocked
signals are set to those in the list sigs. If mode is SIG_BLOCK, the signals in sigs are added
to the set of blocked signals. If mode is SIG_UNBLOCK, the signals in sigs are removed from
the set of blocked signals. sigprocmask returns the set of previously blocked signals.

Each domain, and each thread when the Thread module is loaded, has its own signal mask.
sigprocmask only changes the mask of the current domain or current thread.

Raises Invalid_argument on Windows (no inter-process signals on Windows)

val sigpending : unit -> Sys.signal list

Return the set of blocked signals that are currently pending.

Raises Invalid_argument on Windows (no inter-process signals on Windows)

val sigsuspend : Sys.signal list -> unit

sigsuspend sigs atomically sets the blocked signals to sigs and waits for a non-ignored,
non-blocked signal to be delivered. On return, the blocked signals are reset to their initial
value.

Raises Invalid_argument on Windows (no inter-process signals on Windows)

val pause : unit -> unit

Wait until a non-ignored, non-blocked signal is delivered.

Raises Invalid_argument on Windows (no inter-process signals on Windows)

val sigwait : Sys.signal list -> Sys.signal

sigwait sigs waits until one of the signals in the list sigs becomes pending. It then removes this signal from the set of pending signals, and returns the number of this signal. Signal handlers attached to the signals in sigs will not be invoked. The signals sigs are expected to be blocked before calling sigwait.

Since: 5.4

Raises Invalid_argument on Windows (no inter-process signals on Windows)
## Time functions

```c
type process_times =
{
    tms utime : float ;
        User time for the process
    tms stime : float ;
        System time for the process
    tms cutime : float ;
        User time for the children processes
    tms cstime : float ;
        System time for the children processes
}
The execution times (CPU times) of a process.
```

```c
type tm =
{
    tm_sec : int ;
        Seconds 0..60
    tm_min : int ;
        Minutes 0..59
    tm_hour : int ;
        Hours 0..23
    tm_mday : int ;
        Day of month 1..31
    tm_mon : int ;
        Month of year 0..11
    tm_year : int ;
        Year - 1900
    tm_wday : int ;
        Day of week (Sunday is 0)
    tm_yday : int ;
        Day of year 0..365
    tm_isdst : bool ;
        Daylight time savings in effect
}
The type representing wallclock time and calendar date.
```

```c
val time : unit -> float
```
Return the current time since 00:00:00 GMT, Jan. 1, 1970, in seconds.

val gettimeofday : unit -> float

Same as Unix.time[31.1], but with resolution better than 1 second.

val gmtime : float -> tm

Convert a time in seconds, as returned by Unix.time[31.1], into a date and a time. Assumes
UTC (Coordinated Universal Time), also known as GMT. To perform the inverse conversion,
set the TZ environment variable to "UTC", use Unix.mktime[31.1], and then restore the
original value of TZ.

val localtime : float -> tm

Convert a time in seconds, as returned by Unix.time[31.1], into a date and a time. Assumes
the local time zone. The function performing the inverse conversion is Unix.mktime[31.1].

val mktime : tm -> float * tm

Convert a date and time, specified by the *tm* argument, into a time in seconds, as returned by Unix.time[31.1]. The *tm_isdst*, *tm_wday* and *tm_yday* fields of *tm* are ignored. Also return a normalized copy of the given *tm* record, with the *tm_wday*, *tm_yday*, and *tm_isdst* fields recomputed from the other fields, and the other fields normalized (so that, e.g., 40 October is changed into 9 November). The *tm* argument is interpreted in the local time zone.

val alarm : int -> int

Schedule a SIGALRM signal after the given number of seconds.

Raises Invalid_argument on Windows

val sleep : int -> unit

Stop execution for the given number of seconds.

val sleepf : float -> unit

Stop execution for the given number of seconds. Like sleep, but fractions of seconds are supported.

Since: 4.03 (4.12 in UnixLabels)

val times : unit -> process_times

Return the execution times of the process.

On Windows: partially implemented, will not report timings for child processes.

val utimes : string -> float -> float -> unit

Set the last access time (second arg) and last modification time (third arg) for a file. Times
are expressed in seconds from 00:00:00 GMT, Jan. 1, 1970. If both times are 0.0, the access
and last modification times are both set to the current time.
```c
type interval_timer =
```

| ITIMER_REAL

decrements in real time, and sends the signal `SIGALRM` when expired.

| ITIMER_VIRTUAL

decrements in process virtual time, and sends `SIGVTALRM` when expired.

| ITIMER_PROF

(for profiling) decrements both when the process is running and when the system is
running on behalf of the process; it sends `SIGPROF` when expired.

The three kinds of interval timers.

```c
type interval_timer_status =
{
    it_interval : float ;
    Period
    it_value : float ;
    Current value of the timer
}
```

The type describing the status of an interval timer

```c
val getitimer : interval_timer -> interval_timer_status
```

Return the current status of the given interval timer.

Raises Invalid_argument on Windows

```c
val setitimer :
    interval_timer ->
    interval_timer_status -> interval_timer_status
```

`setitimer` sets the interval timer `t` and returns its previous status. The `s` argument is interpreted as follows: `s.it_value`, if nonzero, is the time to the next timer expiration; `s.it_interval`, if nonzero, specifies a value to be used in reloading `it_value` when the timer expires. Setting `s.it_value` to zero disables the timer. Setting `s.it_interval` to zero causes the timer to be disabled after its next expiration.

Raises Invalid_argument on Windows

## User id, group id

```c
val getuid : unit -> int
```

Return the user id of the user executing the process.

On Windows: always returns 1.

```c
val geteuid : unit -> int
```
Return the effective user id under which the process runs.

On Windows: always returns 1.

val setuid : int -> unit

Set the real user id and effective user id for the process.

**Raises** Invalid_argument on Windows

val getgid : unit -> int

Return the group id of the user executing the process.

On Windows: always returns 1.

val getegid : unit -> int

Return the effective group id under which the process runs.

On Windows: always returns 1.

val setgid : int -> unit

Set the real group id and effective group id for the process.

**Raises** Invalid_argument on Windows

val getgroups : unit -> int array

Return the list of groups to which the user executing the process belongs.

On Windows: always returns [1].

val setgroups : int array -> unit

`setgroups` groups sets the supplementary group IDs for the calling process. Appropriate privileges are required.

**Raises** Invalid_argument on Windows

val initgroups : string -> int -> unit

`initgroups` user group initializes the group access list by reading the group database `/etc/group` and using all groups of which `user` is a member. The additional group `group` is also added to the list.

**Raises** Invalid_argument on Windows

type passwd_entry =
{
    pw_name : string ;
    pw_passwd : string ;
    pw_uid : int ;
    pw_gid : int ;
    pw_gecos : string ;
    pw_dir : string ;
    pw_shell : string ;
}
Structure of entries in the `passwd` database.

```perl
type group_entry =
{
    gr_name : string ;
    gr_passwd : string ;
    gr_gid : int ;
    gr_mem : string array ;
}
```

Structure of entries in the `groups` database.

`val getlogin : unit -> string`

Return the login name of the user executing the process.

`val getpwnam : string -> passwd_entry`

Find an entry in `passwd` with the given name.

**Raises** `Not_found` if no such entry exists, or always on Windows.

`val getgrnam : string -> group_entry`

Find an entry in `group` with the given name.

**Raises** `Not_found` if no such entry exists, or always on Windows.

`val getpwuid : int -> passwd_entry`

Find an entry in `passwd` with the given user id.

**Raises** `Not_found` if no such entry exists, or always on Windows.

`val getgrgid : int -> group_entry`

Find an entry in `group` with the given group id.

**Raises** `Not_found` if no such entry exists, or always on Windows.

## Internet addresses

`type inet_addr`

The abstract type of Internet addresses.

`val inet_addr_of_string : string -> inet_addr`

Conversion from the printable representation of an Internet address to its internal representation. The argument string consists of 4 numbers separated by periods (XXX.YYY.ZZZ.TTT) for IPv4 addresses, and up to 8 numbers separated by colons for IPv6 addresses.

**Raises** `Failure` when given a string that does not match these formats.

`val string_of_inet_addr : inet_addr -> string`
Return the printable representation of the given Internet address. See
Unix.inet_addr_of_string[31.1] for a description of the printable representation.

val inet_addr_any : inet_addr

A special IPv4 address, for use only with `bind`, representing all the Internet addresses that the host machine possesses.

val inet_addr_loopback : inet_addr

A special IPv4 address representing the host machine (127.0.0.1).

val inet6_addr_any : inet_addr

A special IPv6 address, for use only with `bind`, representing all the Internet addresses that the host machine possesses.

val inet6_addr_loopback : inet_addr

A special IPv6 address representing the host machine (::1).

val is_inet6_addr : inet_addr -> bool

Whether the given `inet_addr` is an IPv6 address.

Since: 4.12

## Sockets

type socket_domain =

| PF_UNIX
  Unix domain

| PF_INET
  Internet domain (IPv4)

| PF_INET6
  Internet domain (IPv6)

The type of socket domains. Not all platforms support IPv6 sockets (type PF_INET6).

On Windows: `PF_UNIX` supported since 4.14.0 on Windows 10 1803 and later.

type socket_type =

| SOCK_STREAM
  Stream socket

| SOCK_DGRAM
  Datagram socket

| SOCK_RAW
  Raw socket
| SOCKSEQPACKETE

Sequenced packets socket

The type of socket kinds, specifying the semantics of communications. SOCKATO is
included for completeness, but is rarely supported by the OS, and needs system calls that are
not available in this library.

type sockaddr =
| ADDR_UNIX of string
| ADDR_INET of inet_addr * int

The type of socket addresses. ADDR_UNIX *name* is a socket address in the Unix domain; *name*
is a file name in the file system. ADDR_INET(*addr*, *port*) is a socket address in the Internet
domain; *addr* is the Internet address of the machine, and *port* is the port number.

val socket :
?cloexec:bool ->
socket_domain -> socket_type -> int -> file_descr

Create a new socket in the given domain, and with the given kind. The third argument is the protocol type; 0 selects the default protocol for that kind of sockets. See Unix.set_close_on_exec[31.1] for documentation on the cloexec optional argument.

val domain_of_sockaddr : sockaddr -> socket_domain

Return the socket domain adequate for the given socket address.

val socketpair :
?cloexec:bool ->
socket_domain ->
socket_type -> int -> file_descr * file_descr

Create a pair of unnamed sockets, connected together. See Unix.set_close_on_exec[31.1]
for documentation on the cloexec optional argument.

val accept : ?cloexec:bool -> file_descr -> file_descr * sockaddr

Accept connections on the given socket. The returned descriptor is a socket connected to the
client; the returned address is the address of the connecting client. See
Unix.set_close_on_exec[31.1] for documentation on the cloexec optional argument.

val bind : file_descr -> sockaddr -> unit

Bind a socket to an address.

val connect : file_descr -> sockaddr -> unit

Connect a socket to an address.

val listen : file_descr -> int -> unit

Set up a socket for receiving connection requests. The integer argument is the maximal
number of pending requests.
type shutdown_command =
| SHUTDOWN_RECEIVED
  Close for receiving

| SHUTDOWN_SEND
Close for sending

| SHUTDOWN_ALL
Close both

The type of commands for shutdown.

val shutdown : file_descr -> shutdown_command -> unit

Shutdown a socket connection. SHUTDOWN_SEND as second argument causes reads on the other end of the connection to return an end-of-file condition. SHUTDOWN_RECEIVED causes writes on the other end of the connection to return a closed pipe condition (SIGPIPE signal).

val getsockname : file_descr -> sockaddr
Return the address of the given socket.

val getpeername : file_descr -> sockaddr
Return the address of the host connected to the given socket.

type msg_flag =
| MSG_OOB
| MSG_DONTROUTE
| MSG_PEEK

The flags for Unix.recv[31.1], Unix.recvfrom[31.1], Unix.send[31.1] and Unix.sendto[31.1].

val recv : file_descr -> bytes -> int -> int -> msg_flag list -> int
Receive data from a connected socket.

val recvfrom :
  file_descr ->
  bytes -> int -> int -> msg_flag list -> int * sockaddr

  Receive data from an unconnected socket.

val send : file_descr -> bytes -> int -> int -> msg_flag list -> int
Send data over a connected socket.

val send_substring :
  file_descr -> string -> int -> int -> msg_flag list -> int

  Same as send, but take the data from a string instead of a byte sequence.

Since: 4.02
val sendto :
  file_descr ->
  bytes -> int -> int -> msg_flag list -> sockaddr -> int

Send data over an unconnected socket.

val sendto_substring :
  file_descr ->
  string -> int -> int -> msg_flag list -> sockaddr -> int

Same as sendto, but take the data from a string instead of a byte sequence.

**Since:** 4.02

## Socket options

type socket_bool_option =
| SO_DEBUG
  Record debugging information
| SO_BROADCAST
  Permit sending of broadcast messages
| SO_REUSEADDR
  Allow reuse of local addresses for bind
| SO_KEEPALIVE
  Keep connection active
| SO_DONTROUTE
  Bypass the standard routing algorithms
| SO_OOBILINE
  Leave out-of-band data in line
| SO_ACCEPTCONN
  Report whether socket listening is enabled
| TCP_NODELAY
  Control the Nagle algorithm for TCP sockets
| IPV6_ONLY
  Forbid binding an IPv6 socket to an IPv4 address
| SO_REUSEPORT
  Allow reuse of address and port bindings.

**Since:** 4.12.

The socket options that can be consulted with Unix.getsockopt[31.1] and modified with Unix.setsockopt[31.1]. These options have a boolean (true/false) value.
type socket_int_option =

| SO_SNDBUF

Size of send buffer

| SO_RCVBUF

Size of received buffer

| SO_ERROR

Deprecated. Use Unix.getsockopt_error instead. Deprecated. Use Unix.getsockopt_error[31.1] instead.

| SO_TYPE

Report the socket type

| SO_RCVLOWAT

Minimum number of bytes to process for input operations

| SO_SNDLOWAT

Minimum number of bytes to process for output operations

The socket options that can be consulted with Unix.getsockopt_int[31.1] and modified
with Unix.setsockopt_int[31.1]. These options have an integer value.

type socket_optint_option =

| SO_LINGER

Whether to linger on closed connections that have data present, and for how long (in seconds)

The socket options that can be consulted with Unix.getsockopt_optint[31.1] and modified
with Unix.setsockopt_optint[31.1]. These options have a value of type int option, with
None meaning "disabled".

type socket_float_option =

| SO_RCVTIMEO

Timeout for input operations

| SO_SNDTIMEO

Timeout for output operations

The socket options that can be consulted with Unix.getsockopt_float[31.1] and modified
with Unix.setsockopt_float[31.1]. These options have a floating-point value representing a
time in seconds. The value 0 means infinite timeout.

val getsockopt : file_descr -> socket_bool_option -> bool

Return the current status of a boolean-valued option in the given socket.

val setsockopt : file_descr -> socket_bool_option -> bool -> unit

Set or clear a boolean-valued option in the given socket.
val getsockopt_int : file_descr -> socket_int_option -> int
Same as Unix.getsockopt[31.1] for an integer-valued socket option.

val setsockopt_int : file_descr -> socket_int_option -> int -> unit
Same as Unix.setsockopt[31.1] for an integer-valued socket option.

val getsockopt_optint : file_descr -> socket_optint_option -> int option
Same as Unix.getsockopt[31.1] for a socket option whose value is an int option.

val setsockopt_optint : file_descr -> socket_optint_option -> int option -> unit
Same as Unix.setsockopt[31.1] for a socket option whose value is an int option.

val getsockopt_float : file_descr -> socket_float_option -> float
Same as Unix.getsockopt[31.1] for a socket option whose value is a floating-point number.

val setsockopt_float : file_descr -> socket_float_option -> float -> unit
Same as Unix.setsockopt[31.1] for a socket option whose value is a floating-point number.

val getsockopt_error : file_descr -> error_option
Return the error condition associated with the given socket, and clear it.

## High-level network connection functions

val open_connection : sockaddr -> in_channel * out_channel
Connect to a server at the given address. Return a pair of buffered channels connected to the server. Remember to call flush[28.2] on the output channel at the right times to ensure correct synchronization.

The two channels returned by open_connection share a descriptor to a socket. Therefore, when the connection is over, you should call close_out[28.2] on the output channel, which will also close the underlying socket. Do not call close_in[28.2] on the input channel; it will be collected by the GC eventually.

val shutdown_connection : in_channel -> unit
“Shut down” a connection established with Unix.open_connection[31.1]; that is, transmit an end-of-file condition to the server reading on the other side of the connection. This does not close the socket and the channels used by the connection. See Unix.open_connection[31.1] for how to close them once the connection is over.

val establish_server :
(in_channel -> out_channel -> unit) -> sockaddr -> unit
Establish a server on the given address. The function given as first argument is called for each connection with two buffered channels connected to the client. A new process is created for each connection. The function Unix.establish_server[31.1] never returns normally.

The two channels given to the function share a descriptor to a socket. The function does not need to close the channels, since this occurs automatically when the function returns. If the function prefers explicit closing, it should close the output channel using `close_out`[28.2] and leave the input channel unclosed, for reasons explained in Unix.in_channel_of_descr[31.1].

Raises Invalid_argument on Windows. Use threads instead.

## Host and protocol databases

```typescript
type host_entry =
{
  h_name : string ;
  h_aliases : string array ;
  h_addrtype : socket_domain ;
  h_addr_list : inet_addr array ;
}
```

Structure of entries in the hosts database.

```typescript
type protocol_entry =
{
  p_name : string ;
  p_aliases : string array ;
  p_protot : int ;
}
```

Structure of entries in the protocols database.

```typescript
type service_entry =
{
  s_name : string ;
  s_aliases : string array ;
  s_port : int ;
  s_protot : string ;
}
```

Structure of entries in the services database.

* `val gethostname : unit -> string`
  Return the name of the local host.

* `val gethostbyname : string -> host_entry`
  Find an entry in hosts with the given name.

Raises `Not_found` if no such entry exists.

* `val gethostbyaddr : inet_addr -> host_entry`
Find an entry in `hosts` with the given address.

**Raises** `Not_found` if no such entry exists.

`val getprotobyname : string -> protocol_entry`

Find an entry in `protocols` with the given name.

**Raises** `Not_found` if no such entry exists.

`val getprotobynumber : int -> protocol_entry`

Find an entry in `protocols` with the given protocol number.

**Raises** `Not_found` if no such entry exists.

`val getservbyname : string -> string -> service_entry`

Find an entry in `services` with the given name.

**Raises** `Not_found` if no such entry exists.

`val getservbyport : int -> string -> service_entry`

Find an entry in `services` with the given service number.

**Raises** `Not_found` if no such entry exists.

```typescript
type addr_info =
{
  ai_family : socket_domain;
    Socket domain
  ai_socktype : socket_type;
    Socket type
  ai_protocol : int;
    Socket protocol number
  ai_addr : sockaddr;
    Address
  ai_canonname : string;
    Canonical host name
}
```

Address information returned by `Unix.getaddrinfo[31.1]`.

```typescript
type getaddrinfo_option =
  | AI_FAMILY of socket_domain
    Impose the given socket domain
  | AI_SOCKETTYPE of socket_type
    Impose the given socket type
  | AI_PROTOCOL of int
```
Impose the given protocol

| AI_NUMERICHOST

Do not call name resolver, expect numeric IP address

| AI_CANONNAME

Fill the *ai_canonname* field of the result

| AI_PASSIVE

Set address to “any” address for use with Unix.bind[31.1]

Options to Unix.getaddrinfo[31.1].

val getaddrinfo :

string -> string -> getaddrinfo_option list -> addr_info list

getaddrinfo host service opts returns a list of Unix .addr_info [31.1] records describing
socket parameters and addresses suitable for communicating with the given host and service.
The empty list is returned if the host or service names are unknown, or the constraints
expressed in opts cannot be satisfied.

host is either a host name or the string representation of an IP address. host can be given as
the empty string; in this case, the “any” address or the “loopback” address are used,
depending whether opts contains AI_PASSIVE. service is either a service name or the string
representation of a port number. service can be given as the empty string; in this case, the
port field of the returned addresses is set to 0. opts is a possibly empty list of options that
allows the caller to force a particular socket domain (e.g. IPv6 only or IPv4 only) or a
particular socket type (e.g. TCP only or UDP only).

type name_info =

{ ni_hostname : string ;

Name or IP address of host

ni_service : string ;

Name of service or port number

}

Host and service information returned by Unix.getnameinfo[31.1].

type getnameinfo_option =

| NI_NOFQDN

Do not qualify local host names

| NI_NUMERICHOST

Always return host as IP address

| NI_NAMEREQD

Fail if host name cannot be determined

| NI_NUMERICSERV
Always return service as port number

| NI_DGRAM

Consider the service as UDP-based instead of the default TCP

Options to Unix.getnameinfo[31.1].

val getnameinfo : sockaddr -> getnameinfo_option list -> name_info

getnameinfo addr opts returns the host name and service name corresponding to the
socket address addr. opts is a possibly empty list of options that governs how these names
are obtained.

Raises `Not_found` if an error occurs.

Terminal interface

The following functions implement the POSIX standard terminal interface. They provide control
over asynchronous communication ports and pseudo-terminals. Refer to the termios man page for
a complete description.

type terminal_io =

{ mutable c_ignbrk : bool ;

Ignore the break condition.

mutable c_brkint : bool ;

Signal interrupt on break condition.

mutable c_ignpar : bool ;

Ignore characters with parity errors.

mutable c_parmrk : bool ;

Mark parity errors.

mutable c_inpck : bool ;

Enable parity check on input.

mutable c_istrip : bool ;

Strip 8th bit on input characters.

mutable c_inlcr : bool ;

Map NL to CR on input.

mutable c_igncr : bool ;

Ignore CR on input.

mutable c_icrn1 : bool ;

Map CR to NL on input.

mutable c_ixon : bool ;

Recognize XON/XOFF characters on input.
mutable c_ixoff : bool ;
Emit XON/XOFF chars to control input flow.

mutable c_opost : bool ;
Enable output processing.

mutable c_obaud : int ;
Output baud rate (0 means close connection).

mutable c_ibaud : int ;
Input baud rate.

mutable c_csize : int ;
Number of bits per character (5-8).

mutable c_cstopb : int ;
Number of stop bits (1-2).

mutable c_cread : bool ;
Reception is enabled.

mutable c_parenb : bool ;
Enable parity generation and detection.

mutable c_parodd : bool ;
Specify odd parity instead of even.

mutable c_hupcl : bool ;
Hang up on last close.

mutable c_clocal : bool ;
Ignore modem status lines.

mutable c_isig : bool ;
Generate signal on INTR, QUIT, SUSP.

mutable c_icanon : bool ;
Enable canonical processing (line buffering and editing)

mutable c_noflsh : bool ;
Disable flush after INTR, QUIT, SUSP.

mutable c.echo : bool ;
Echo input characters.

mutable c.echoe : bool ;
Echo ERASE (to erase previous character).

mutable c_echok : bool ;
Echo KILL (to erase the current line).
mutable c_echonl : bool ;

Echo NL even if c.echo is not set.

mutable c_vintr : char ;

Interrupt character (usually ctrl-C).

mutable c_vquit : char ;

Quit character (usually ctrl-\).

mutable c_verase : char ;

Erase character (usually DEL or ctrl-H).

mutable c_vkill : char ;

Kill line character (usually ctrl-U).

mutable c_veof : char ;

End-of-file character (usually ctrl-D).

mutable c_veol : char ;

Alternate end-of-line char. (usually none).

mutable c_vmin : int ;

Minimum number of characters to read before the read request is satisfied.

mutable c_vtime : int ;

Maximum read wait (in 0.1s units).

mutable c_vstart : char ;

Start character (usually ctrl-Q).

mutable c_vstop : char ;

Stop character (usually ctrl-S).

}

val tcgetattr : file_descr -> terminal_io

Return the status of the terminal referred to by the given file descriptor.

Raises Invalid_argument on Windows

typesetattr : when =

| TCSANOW

| TCSADRAIN

| TCSAFLUSH

val tcsetattr : file_descr ->Set the status of the terminal referred to by the given file descriptor. The second argument indicates when the status change takes place: immediately (TCSANOW), when all pending output has been transmitted (TCSADRAIN), or after flushing all input that has been received but not read (TCSAFLUSH). TCSADRAIN is recommended when changing the output parameters; TCSAFLUSH, when changing the input parameters.

Raises Invalid_argument on Windows
val tcsendbreak : file_descr -> int -> unit

Send a break condition on the given file descriptor. The second argument is the duration of the break, in 0.1s units; 0 means standard duration (0.25s).

Raises Invalid_argument on Windows

val tcdrain : file_descr -> unit

Waits until all output written on the given file descriptor has been transmitted.

Raises Invalid_argument on Windows

type flush_queue =

| TCIFLUSH

| TCOFLUSH

| TCIOFLUSH

val tcflush : file_descr -> flush_queue -> unit

Discard data written on the given file descriptor but not yet transmitted, or data received but not yet read, depending on the second argument: TCIFLUSH flushes data received but not read, TCOFLUSH flushes data written but not transmitted, and TCIOFLUSH flushes both.

Raises Invalid_argument on Windows

type flow_action =

| TCOOFF

| TCOON

| TCIOFF

| TCION

val tcflow : file_descr -> flow_action -> unit

Suspend or restart reception or transmission of data on the given file descriptor, depending on the second argument: TCOOFF suspends output, TCOON restarts output, TCIOFF transmits a STOP character to suspend input, and TCION transmits a START character to restart input.

Raises Invalid_argument on Windows

val setsid : unit -> int

Put the calling process in a new session and detach it from its controlling terminal.

Raises Invalid_argument on Windows

## 31.2 Module UnixLabels: labeled version of the interface

This module is identical to Unix (31.1), and only differs by the addition of labels. You may see these labels directly by looking at unixLabels.mli, or by using the ocamlbrowsër tool.
**Windows:**

The Cygwin port of OCaml fully implements all functions from the Unix module. The native Win32 ports implement a subset of them. Below is a list of the functions that are not implemented, or only partially implemented, by the Win32 ports. Functions not mentioned are fully implemented and behave as described previously in this chapter.
<table><thead><tr><td>Functions</td><td>Comment</td></tr></thead><tbody><tr><td>fork</td><td>not implemented, use create_process or threads</td></tr><tr><td>wait</td><td>not implemented, use waitpid</td></tr><tr><td>waitpid</td><td>can only wait for a given PID, not any child process</td></tr><tr><td>getppid</td><td>not implemented (meaningless under Windows)</td></tr><tr><td>nice</td><td>not implemented</td></tr><tr><td>truncate, ftruncate</td><td>implemented (since 4.10.0)</td></tr><tr><td>link</td><td>implemented (since 3.02)</td></tr><tr><td>fchmod</td><td>not implemented</td></tr><tr><td>chown, fchown</td><td>not implemented (make no sense on a DOS file system)</td></tr><tr><td>umask</td><td>not implemented</td></tr><tr><td>access</td><td>execute permission X_OK cannot be tested, it just tests for read permission instead</td></tr><tr><td>chroot</td><td>not implemented</td></tr><tr><td>mkfifo</td><td>not implemented</td></tr><tr><td>symlink, readlink</td><td>implemented (since 4.03.0)</td></tr><tr><td>kill</td><td>partially implemented (since 4.00.0): only the sigkill signal is implemented</td></tr><tr><td>sigprocmask, sigpending, sigsuspend</td><td>not implemented (no inter-process signals on Windows)</td></tr><tr><td>pause</td><td>not implemented (no inter-process signals in Windows)</td></tr><tr><td>alarm</td><td>not implemented</td></tr><tr><td>times</td><td>partially implemented, will not report timings for child processes</td></tr><tr><td>getitimer, setitimer</td><td>not implemented</td></tr><tr><td>getuid, geteuid, getgid, getegid</td><td>always return 1</td></tr><tr><td>setuid, setgid, setgroups, initgroups</td><td>not implemented</td></tr><tr><td>getgroups</td><td>always returns [1] (since 2.00)</td></tr><tr><td>getpwnam, getpwuid</td><td>always raise Not_found</td></tr><tr><td>getgrnam, getgrgid</td><td>always raise Not_found</td></tr><tr><td>type socket_domain</td><td>PF_INET is fully supported; PF_INET6 is fully supported (since 4.01.0); PF_UNIX is supported since 4.14.0, but only works on Windows 10 1803 and later.</td></tr><tr><td>establish_server</td><td>not implemented; use threads</td></tr><tr><td>terminal functions (tc*)</td><td>not implemented</td></tr><tr><td>setsid</td><td>not implemented</td></tr></tbody></table>
Chapter 32

The str library: regular expressions
and string processing

The `str` library provides high-level string processing functions, some based on regular expressions. It is intended to support the kind of file processing that is usually performed with scripting languages such as `awk`, `perl` or `sed`.

Programs that use the `str` library must be linked as follows:

`ocamlc other options -I +str str.cma other files`

`ocamlopt other options -I +str str.cmxa other files`

For interactive use of the `str` library, do:

`ocamlmktop -o mytop str.cma
./mytop`

or (if dynamic linking of C libraries is supported on your platform), start `ocaml` and type

`# #directory "+str";;`

`# #load "str.cma";;`

32.1 Module Str : Regular expressions and high-level string processing

Regular expressions

The `Str[32.1]` library provides regular expressions on sequences of bytes. It is, in general, unsuitable to match Unicode characters.

type regexp

The type of compiled regular expressions.

val regexp : string -> regexp

Compile a regular expression. The following constructs are recognized:
* `.` Matches any character except newline.

* `*` (postfix) Matches the preceding expression zero, one or several times

* `+` (postfix) Matches the preceding expression one or several times

* `?` (postfix) Matches the preceding expression once or not at all

* `[..]` Character set. Ranges are denoted with `-`, as in `[a-z]`. An initial `^`, as in `[^0-9]`, complements the set. To include a `]` character in a set, make it the first character of the set. To include a `-` character in a set, make it the first or the last character of the set.

* `^` Matches at beginning of line: either at the beginning of the matched string, or just after a `\n` character.

* `$` Matches at end of line: either at the end of the matched string, or just before a `\n` character.

* `\|` (infix) Alternative between two expressions.

* `\(..\)` Grouping and naming of the enclosed expression.

* `\1` The text matched by the first `\(...\)` expression (`\2` for the second expression, and so on up to `\9`).

* `\b` Matches word boundaries.

* `\` Quotes special characters. The special characters are `$^\.\*+?[]`.

In regular expressions you will often use backslash characters; it's easier to use a quoted string literal `{|...|}` to avoid having to escape backslashes.

For example, the following expression:

```python
let r = Str.regexp {|hello \([A-Za-z]+\)|} in
    Str.replace_first r {|\1|} "hello world"
```

returns the string `"world"`.

If you want a regular expression that matches a literal backslash character, you need to double it: `Str.regexp {|\\}|`.

You can use regular string literals `"..."` too, however you will have to escape backslashes.

The example above can be rewritten with a regular string literal as:

```python
let r = Str.regexp "hello \\[A-Za-z]+\\)" in
    Str.replace_first r "\\1" "hello world"
```

And the regular expression for matching a backslash becomes a quadruple backslash:

```
Str.regexp "\\\\".
```

### `val regexp_caseFold: string -> regexp`

Same as `regexp`, but the compiled expression will match text in a case-insensitive way: uppercase and lowercase letters will be considered equivalent.

### `val quote: string -> string`

`Str.quote` s returns a regexp string that matches exactly s and nothing else.

### `val regexp_string: string -> regexp`