mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
fix: move with_temp_dir from CCIO to CCUnix
it depends on unix, which is a deal breaker for core
This commit is contained in:
parent
28f8872ef5
commit
70bd7f1e97
4 changed files with 66 additions and 61 deletions
|
|
@ -351,47 +351,3 @@ module File = struct
|
||||||
let name = Filename.temp_file ?temp_dir prefix suffix in
|
let name = Filename.temp_file ?temp_dir prefix suffix in
|
||||||
finally_ f name ~h:remove_noerr
|
finally_ f name ~h:remove_noerr
|
||||||
end
|
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,19 +250,3 @@ module File : sig
|
||||||
See {!Filename.temp_file}.
|
See {!Filename.temp_file}.
|
||||||
@since 0.17 *)
|
@since 0.17 *)
|
||||||
end
|
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
|
|
||||||
*)
|
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ let establish_server sockaddr ~f =
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
(** {6 Locking} *)
|
(** {2 Locking} *)
|
||||||
|
|
||||||
let with_file_lock ~kind filename f =
|
let with_file_lock ~kind filename f =
|
||||||
let lock_file = Unix.openfile filename [Unix.O_CREAT; Unix.O_WRONLY] 0o644 in
|
let lock_file = Unix.openfile filename [Unix.O_CREAT; Unix.O_WRONLY] 0o644 in
|
||||||
|
|
@ -292,3 +292,49 @@ module Infix = struct
|
||||||
end
|
end
|
||||||
|
|
||||||
include Infix
|
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));
|
||||||
|
()
|
||||||
|
*)
|
||||||
|
|
|
||||||
|
|
@ -165,3 +165,22 @@ module Infix : sig
|
||||||
end
|
end
|
||||||
|
|
||||||
include module type of Infix
|
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
|
||||||
|
*)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue