package eio
Effect-based direct-style IO API for OCaml
Install
Dune Dependency
Authors
Maintainers
Sources
eio-1.2.tbz
sha256=3792e912bd8d494bb2e38f73081825e4d212b1970cf2c1f1b2966caa9fd6bc40
sha512=4a80dbcf8cf2663bdad0f2970871844f37bd293c56bd1ce602910e0a613754945f1f942719f9630906453be7c73c1732dc97526c6c90b0b36100d04fd5e871e4
doc/src/eio.unix/fd.ml.html
Source file fd.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
open Eio.Std type tristate = No | Yes | Unknown (* Note: [blocking] and [seekable] are not atomic, but it doesn't matter if we query twice in rare cases. *) type t = { fd : Rcfd.t; mutable blocking : tristate; mutable seekable : tristate; close_unix : bool; (* Whether closing this also closes the underlying FD. *) mutable release_hook : Eio.Switch.hook; (* Use this on close to remove switch's [on_release] hook. *) } let err_closed op = Invalid_argument (op ^ ": file descriptor used after calling close!") let use t f ~if_closed = Rcfd.use t.fd f ~if_closed let use_exn op t f = Rcfd.use t.fd f ~if_closed:(fun () -> raise (err_closed op)) let close t = Switch.remove_hook t.release_hook; if t.close_unix then ( ignore (Rcfd.close t.fd : bool) ) else ( ignore (Rcfd.remove t.fd : Unix.file_descr option) ) let remove t = Switch.remove_hook t.release_hook; Rcfd.remove t.fd let tristate_of_bool_opt = function | None -> Unknown | Some true -> Yes | Some false -> No let of_unix_no_hook ?(close_unix=true) ?blocking ?seekable fd = let seekable = tristate_of_bool_opt seekable in let blocking = tristate_of_bool_opt blocking in { fd = Rcfd.make fd; blocking; seekable; close_unix; release_hook = Switch.null_hook } let of_unix ~sw ?blocking ?seekable ~close_unix fd = let t = of_unix_no_hook ?blocking ?seekable ~close_unix fd in t.release_hook <- Switch.on_release_cancellable sw (fun () -> close t); t let of_unix_list ~sw fds = match Switch.get_error sw with | Some e -> List.iter Unix.close fds; raise e | None -> List.map (of_unix ~sw ~close_unix:true) fds external eio_is_blocking : Unix.file_descr -> bool = "eio_unix_is_blocking" let is_blocking t = match t.blocking with | No -> false | Yes -> true | Unknown -> use t ~if_closed:(Fun.const false) @@ fun fd -> let blocking = eio_is_blocking fd in t.blocking <- if blocking then Yes else No; blocking let is_seekable t = match t.seekable with | No -> false | Yes -> true | Unknown -> use t ~if_closed:(Fun.const false) @@ fun fd -> let seekable = match Unix.lseek fd 0 Unix.SEEK_CUR with | (_ : int) -> true | exception Unix.Unix_error (Unix.ESPIPE, "lseek", "") -> false in t.seekable <- if seekable then Yes else No; seekable let is_open t = Rcfd.is_open t.fd let rec use_exn_list op xs k = match xs with | [] -> k [] | x :: xs -> use_exn op x @@ fun x -> use_exn_list op xs @@ fun xs -> k (x :: xs) let use_exn_opt op x f = match x with | None -> f None | Some x -> use_exn op x (fun x -> f (Some x)) let stdin = of_unix_no_hook Unix.stdin let stdout = of_unix_no_hook Unix.stdout let stderr= of_unix_no_hook Unix.stderr let pp f t = Rcfd.pp f t.fd
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>