Module Stdio.Out_channel

An output channel for doing blocking writes to destinations like files and sockets.

Note that an Out_channel.t is a custom block with a finalizer, and so is allocated directly to the major heap. Creating a lot of out_channels can result in many major collections and poor performance.

Note that this is simply another interface on the out_channel type in the OCaml standard library.

type t = Caml.out_channel
include sig ... end
val sexp_of_t : t ‑> Base.Sexp.t
include Base.Equal.S with type t := t
type t
val equal : t Base.Equal.equal
val stdout : t
val stderr : t
type 'a with_create_args = ?⁠binary:Base.bool ‑> ?⁠append:Base.bool ‑> ?⁠fail_if_exists:Base.bool ‑> ?⁠perm:Base.int ‑> 'a
val create : (Base.string ‑> t) with_create_args
val with_file : (Base.string ‑> f:(t ‑> 'a) ‑> 'a) with_create_args
val close : t ‑> Base.unit

close t flushes and closes t, and may raise an exception. close returns () and does not raise if t is already closed. close raises an exception if the close() system call on the underlying file descriptor fails (i.e. returns -1), which would happen in the following cases:

EBADF -- this would happen if someone else did close() system call on the underlying fd, which I would think a rare event.

EINTR -- would happen if the system call was interrupted by a signal, which would be rare. Also, I think we should probably just catch EINTR and re-attempt the close. Unfortunately, we can't do that in OCaml because the OCaml library marks the out_channel as closed even if the close syscall fails, so a subsequent call close_out_channel will be a no-op. This should really be fixed in the OCaml library C code, having it restart the close() syscall on EINTR. I put a couple CRs in fixed_close_channel, our rework of OCaml's caml_ml_close_channel,

EIO -- I don't recall seeing this. I think it's rare.

See "man 2 close" for details.

val close_no_err : t ‑> Base.unit

close_no_err tries to flush and close t. It does not raise.

val set_binary_mode : t ‑> Base.bool ‑> Base.unit
val flush : t ‑> Base.unit
val output : t ‑> buf:Base.bytes ‑> pos:Base.int ‑> len:Base.int ‑> Base.unit
val output_string : t ‑> Base.string ‑> Base.unit
val output_substring : t ‑> buf:Base.string ‑> pos:Base.int ‑> len:Base.int ‑> Base.unit
val output_bytes : t ‑> Base.Bytes.t ‑> Base.unit
val output_char : t ‑> Base.char ‑> Base.unit
val output_byte : t ‑> Base.int ‑> Base.unit
val output_binary_int : t ‑> Base.int ‑> Base.unit
val output_buffer : t ‑> Base.Buffer.t ‑> Base.unit
val output_value : t ‑> _ ‑> Base.unit

OCaml's internal Marshal format

val newline : t ‑> Base.unit
val output_lines : t ‑> Base.string Base.list ‑> Base.unit

Outputs a list of lines, each terminated by a newline character

val fprintf : t ‑> ('atBase.unitBase.format ‑> 'a

Formatted printing to an out channel. This is the same as Printf.sprintf except that it outputs to t instead of returning a string. Similarly, the function arguments corresponding to conversions specifications such as %a or %t takes t as argument and must print to it instead of returning a string.

val printf : ('atBase.unitBase.format ‑> 'a

printf fmt is the same as fprintf stdout fmt

val eprintf : ('atBase.unitBase.format ‑> 'a

printf fmt is the same as fprintf stderr fmt

val kfprintf : (t ‑> 'a) ‑> t ‑> ('btBase.unit'aBase.format4 ‑> 'b

kfprintf k t fmt is the same as fprintf t fmt, but instead of returning immediately, passes the out channel to k at the end of printing.

val print_endline : Base.string ‑> Base.unit

print_endline str outputs str to stdout followed by a newline then flushes stdout

val prerr_endline : Base.string ‑> Base.unit

prerr_endline str outputs str to stderr followed by a newline then flushes stderr

val seek : t ‑> Base.int64 ‑> Base.unit
val pos : t ‑> Base.int64
val length : t ‑> Base.int64
val write_lines : Base.string ‑> Base.string Base.list ‑> Base.unit

The first argument of these is the file name to write to.

val write_all : Base.string ‑> data:Base.string ‑> Base.unit