mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-07 11:45:31 -05:00
feat(io): add with_temp_dir function
This commit is contained in:
parent
8ddc3de490
commit
76bec991a2
3 changed files with 62 additions and 2 deletions
|
|
@ -351,3 +351,47 @@ module File = struct
|
|||
let name = Filename.temp_file ?temp_dir prefix suffix in
|
||||
finally_ f name ~h:remove_noerr
|
||||
end
|
||||
|
||||
let rand_digits_ =
|
||||
let st = lazy (Random.State.make_self_init()) in
|
||||
fun () ->
|
||||
let rand = Random.State.bits (Lazy.force st) land 0xFFFFFF in
|
||||
Printf.sprintf "%06x" rand
|
||||
|
||||
let rmdir_ dir =
|
||||
try ignore (Sys.command ("rm -r " ^ dir) : int)
|
||||
with _ -> ()
|
||||
|
||||
let with_temp_dir ?(mode=0o700) ?dir pat (f: string -> 'a) : 'a =
|
||||
let dir = match dir with
|
||||
| Some d -> d
|
||||
| None -> Filename.get_temp_dir_name ()
|
||||
in
|
||||
let raise_err msg = raise (Sys_error msg) in
|
||||
let rec loop count =
|
||||
if count < 0 then (
|
||||
raise_err "mk_temp_dir: too many failing attemps"
|
||||
) else (
|
||||
let dir = Filename.concat dir (pat ^ rand_digits_ ()) in
|
||||
match Unix.mkdir dir mode with
|
||||
| () ->
|
||||
finally_ f dir ~h:rmdir_
|
||||
| exception Unix.Unix_error (Unix.EEXIST, _, _) -> loop (count - 1)
|
||||
| exception Unix.Unix_error (Unix.EINTR, _, _) -> loop count
|
||||
| exception Unix.Unix_error (e, _, _) ->
|
||||
raise_err ("mk_temp_dir: " ^ (Unix.error_message e))
|
||||
)
|
||||
in
|
||||
loop 1000
|
||||
|
||||
(*$R
|
||||
let filename = with_temp_dir "test_containers"
|
||||
(fun dir ->
|
||||
let name = Filename.concat dir "test" in
|
||||
CCIO.with_out name (fun oc -> output_string oc "content"; flush oc);
|
||||
assert_bool ("file exists:"^name) (Sys.file_exists name);
|
||||
name)
|
||||
in
|
||||
assert_bool ("file does not exist"^filename) (not (Sys.file_exists filename));
|
||||
()
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -250,3 +250,19 @@ module File : sig
|
|||
See {!Filename.temp_file}.
|
||||
@since 0.17 *)
|
||||
end
|
||||
|
||||
val with_temp_dir :
|
||||
?mode:int -> ?dir:string ->
|
||||
string -> (string -> 'a) -> 'a
|
||||
(** Create a temporary directory, call the function, and then destroy the
|
||||
directory afterwards. Usage [with_temp_dir pattern f].
|
||||
@param pattern the naming pattern for the temporary directory.
|
||||
Helps avoiding collisions.
|
||||
@param mode mode for the directory
|
||||
@param dir the directory under which to make a temporary directory (default [/tmp])
|
||||
|
||||
Note that this is implemented following the discussion at:
|
||||
https://discuss.ocaml.org/t/how-to-create-a-temporary-directory-in-ocaml/1815/
|
||||
|
||||
@since NEXT_RELEASE
|
||||
*)
|
||||
|
|
|
|||
|
|
@ -145,8 +145,8 @@ val replace : ?which:[`Left|`Right|`All] -> sub:string -> by:string -> string ->
|
|||
@since 0.14 *)
|
||||
|
||||
val is_sub : sub:string -> int -> string -> int -> sub_len:int -> bool
|
||||
(** [is_sub ~sub i s j ~len] returns [true] iff the substring of
|
||||
[sub] starting at position [i] and of length [len] is a substring
|
||||
(** [is_sub ~sub i s j ~sub_len] returns [true] iff the substring of
|
||||
[sub] starting at position [i] and of length [sub_len] is a substring
|
||||
of [s] starting at position [j]. *)
|
||||
|
||||
val repeat : string -> int -> string
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue