The Unix library provides:
val write : file_descr -> bytes -> int -> int -> int
(** [write fd buff ofs len] writes [len] bytes to descriptor [fd],
taking them from byte sequence [buff], starting at position [ofs]
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 single_write : file_descr -> bytes -> int -> int -> int
(** Same as [write], but attempts to write only once.
Thus, if an error occurs, [single_write] guarantees that no data
has been written. *)
Both require the caller to deal with exceptions like Unix.EINTR
and this has lead to really_write
in Unix system programming in OCaml:
let rec really_write fd buffer offset len =
let n = restart_on_EINTR (single_write fd buffer offset) len in
if n < len then really_write fd buffer (offset + n) (len - n);;
So it appears that what a typical client would need for writing to a file descriptor is not provided by the standard library. Isn’t that a bit unsatisfying and risks clients providing their own solutions that possibly overlook an edge case?