Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion files.ml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ let mkdir_p ?(perm=0o755) path =
in
aux path

let save_as name ?(mode=0o644) f =
let save_as_regular name ?(mode=0o644) f =
(* not using make_temp_file cause same dir is needed for atomic rename *)
let temp = Printf.sprintf "%s.save.%d.tmp" name (U.gettid ()) in
bracket (Unix.openfile temp [Unix.O_WRONLY;Unix.O_CREAT] mode) Unix.close begin fun fd ->
Expand All @@ -81,3 +81,13 @@ let save_as name ?(mode=0o644) f =
with
exn -> Exn.suppress Unix.unlink temp; raise exn
end

let save_as name ?mode f =
let name =
match (Unix.lstat name).st_kind with
| Unix.S_LNK -> Unix.realpath name
| (exception Unix.Unix_error (Unix.ENOENT, _, _)) | _ -> name
in
match (Unix.stat name).st_kind with
| Unix.S_REG | (exception Unix.Unix_error (Unix.ENOENT, _, _)) -> save_as_regular name ?mode f
| _ -> Out_channel.with_open_gen [ Open_wronly ] 0 name f
5 changes: 4 additions & 1 deletion files.mli
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ val open_out_append_text : string -> out_channel
val mkdir_p : ?perm:Unix.file_perm -> string -> unit

(** [save_as filename ?mode f] is similar to
[Control.with_open_file_bin] except that writing is done to a
[Control.with_open_file_bin] for regular files, except that writing is done to a
temporary file that will be renamed to [filename] after [f] has
succesfully terminated. Therefore this guarantee that either
[filename] will not be modified or will contain whatever [f] was
writing to it as a side-effect.

There is no such special treatment for special files, instead they
are written to directly.

FIXME windows *)
val save_as : string -> ?mode:Unix.file_perm -> (out_channel -> unit) -> unit
Loading