let replace_file ?(justcreatenewfile = false) path_orig func =
  let dir_orig = Filename.dirname path_orig
  and fn_orig = Filename.basename path_orig in
  let (processing_res, path_tmp) =
    (*
подумать, как ловить ошибку в with -- ибо тут явно она,
Sys_error при вызове replace_file.

0. ловить ли исключения в with-обёртке в try open_.. и try close_.. так,
   чтобы сообщать о них особым образом, типа failwith "Filew.with_..:
open_in_bin failed"?
1. использовать ли Res в Filew?
2. придумать ли шнягу для оборачивания ошибок, возникающих
только в with-обёртке?  (видимо заменой пользовательской функции
на что-то, следящее за исключениями?
"with1_catch thehandler with_file_in_bin path_orig & fun ..."
)
*)

    with_file_in_bin path_orig
      (fun in_ch ->
         with_temp_file_opened_bin ~cleanup: false ~temp_dir: dir_orig
           (fn_orig ^ "."".new"
           (fun path_tmp out_ch ->
              let res =
                try
                  match func in_ch out_ch with
                  | None -> `Ok
                  | Some e -> `Error e
                with | e -> `Exn e
              in (res, path_tmp)))
  in
    match processing_res with
    | `Exn e -> (remove_file path_tmp; raise e)
    | `Error e -> (remove_file path_tmp; Some e)
    | `Ok ->
        (if justcreatenewfile
         then ()
         else
           (let path_bak = rename_to_tmp path_orig (fn_orig ^ "."".bak" in
            let new_to_orig = rename_opt path_tmp path_orig
            in
              match new_to_orig with
              | None -> remove_file path_bak
              | Some e -> (rename path_bak path_orig; raise e));
         None)