From ab5201ff6902b9cf366c62e3858eba9413203b64 Mon Sep 17 00:00:00 2001 From: Nikolai Kosmatov <nikolai.kosmatov@cea.fr> Date: Fri, 22 Feb 2019 17:15:25 +0100 Subject: [PATCH] [extlib] add recursive mkdir function (fixes #425) --- src/kernel_services/plugin_entry_points/plugin.ml | 2 +- src/libraries/stdlib/extlib.ml | 12 ++++++++++++ src/libraries/stdlib/extlib.mli | 11 +++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/kernel_services/plugin_entry_points/plugin.ml b/src/kernel_services/plugin_entry_points/plugin.ml index bd956deba6c..1ba3d14939c 100644 --- a/src/kernel_services/plugin_entry_points/plugin.ml +++ b/src/kernel_services/plugin_entry_points/plugin.ml @@ -325,7 +325,7 @@ struct let mk_dir d = try - Unix.mkdir d 0o755; + Extlib.mkdir ~parents:true d 0o755; L.warning "creating %s directory `%s'" O.option_name d; d with Unix.Unix_error _ -> diff --git a/src/libraries/stdlib/extlib.ml b/src/libraries/stdlib/extlib.ml index c24744c1154..df326129833 100644 --- a/src/libraries/stdlib/extlib.ml +++ b/src/libraries/stdlib/extlib.ml @@ -343,6 +343,18 @@ let try_finally ~finally f x = hence interrupting the process, might not work: child processes still need to run some daemons, such as [flush_all] which is registered by default. *) +let rec mkdir ?(parents=false) name perm = + try Unix.mkdir name perm + with + | Unix.Unix_error (Unix.ENOENT,_,_) when parents -> + let parent_name = Filename.dirname name in + if name <> parent_name then + begin + mkdir ~parents parent_name perm; + Unix.mkdir name perm + end + | e -> raise e + let pid = Unix.getpid () let safe_at_exit f = at_exit diff --git a/src/libraries/stdlib/extlib.mli b/src/libraries/stdlib/extlib.mli index 389a34fc00d..89d1cc38c08 100644 --- a/src/libraries/stdlib/extlib.mli +++ b/src/libraries/stdlib/extlib.mli @@ -331,6 +331,17 @@ val try_finally: finally:(unit -> unit) -> ('a -> 'b) -> 'a -> 'b (** System commands *) (* ************************************************************************* *) +val mkdir : ?parents:bool -> string -> Unix.file_perm -> unit + (** [mkdir ?parents name perm] creates directory [name] with permission + [perm]. If [parents] is true, recursively create parent directories + if needed. [parents] defaults to false. + Note that this function may create some of the parent directories + and then fail to create the children, e.g. if [perm] does not allow + user execution of the created directory. This will leave the filesystem + in a modified state before raising an exception. + @raise [Unix.Unix_error] if cannot create [name] or its parents. + @since Frama-C+dev *) + val safe_at_exit : (unit -> unit) -> unit (** Register function to call with [Pervasives.at_exit], but only for non-child process (fork). The order of execution is preserved -- GitLab