From 70bd7f1e97bf278fadc17787c313ac34722a7ba7 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Wed, 11 Dec 2019 09:46:21 -0600 Subject: [PATCH] fix: move `with_temp_dir` from CCIO to CCUnix it depends on unix, which is a deal breaker for core --- src/core/CCIO.ml | 44 ----------------------------------------- src/core/CCIO.mli | 16 --------------- src/unix/CCUnix.ml | 48 ++++++++++++++++++++++++++++++++++++++++++++- src/unix/CCUnix.mli | 19 ++++++++++++++++++ 4 files changed, 66 insertions(+), 61 deletions(-) diff --git a/src/core/CCIO.ml b/src/core/CCIO.ml index 1f363465..e616f49b 100644 --- a/src/core/CCIO.ml +++ b/src/core/CCIO.ml @@ -351,47 +351,3 @@ 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)); - () -*) diff --git a/src/core/CCIO.mli b/src/core/CCIO.mli index 1b39187d..5f16d69f 100644 --- a/src/core/CCIO.mli +++ b/src/core/CCIO.mli @@ -250,19 +250,3 @@ 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 - *) diff --git a/src/unix/CCUnix.ml b/src/unix/CCUnix.ml index 23692b0e..3cfcaf84 100644 --- a/src/unix/CCUnix.ml +++ b/src/unix/CCUnix.ml @@ -243,7 +243,7 @@ let establish_server sockaddr ~f = done -(** {6 Locking} *) +(** {2 Locking} *) let with_file_lock ~kind filename f = let lock_file = Unix.openfile filename [Unix.O_CREAT; Unix.O_WRONLY] 0o644 in @@ -292,3 +292,49 @@ module Infix = struct end include Infix + +(** {2 Temporary directory} *) + +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:(fun () -> rmdir_ dir) + | 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)); + () +*) diff --git a/src/unix/CCUnix.mli b/src/unix/CCUnix.mli index a66f32d9..3e1c9c56 100644 --- a/src/unix/CCUnix.mli +++ b/src/unix/CCUnix.mli @@ -165,3 +165,22 @@ module Infix : sig end include module type of Infix + + +(** {2 Temporary directory} *) + +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 + *)