Skip to content

Commit

Permalink
Merge pull request #4827 from jonahbeckford/feature-win32-permission-…
Browse files Browse the repository at this point in the history
…denied

Fix Permission Denied on Win32 install operation
  • Loading branch information
rjbou authored Apr 4, 2022
2 parents c830b25 + bb8833c commit 47847d9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
1 change: 1 addition & 0 deletions master_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ users)
* OpamCudf: provide machine-readable information on conflicts caused by cycles [#4039 @gasche]
* Remove memoization from `best_effort ()` to allow for multiple different settings during the same session (useful for libaray users) [#4805 @LasseBlaauwbroek]
* [BUG] Catch `EACCES` in lock function [#4948 @oandrieu - fix #4944]
* Permissions: chmod+unlink before copy [#4827 @jonahbeckford @dra27]

## Test
* Update crowbar with compare functions [#4918 @rjbou]
Expand Down
27 changes: 18 additions & 9 deletions src/core/opamSystem.ml
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,13 @@ let remove_file file =
if
try ignore (Unix.lstat file); true with Unix.Unix_error _ -> false
then (
log "rm %s" file;
try
log "rm %s" file;
Unix.unlink file
try Unix.unlink file
with Unix.Unix_error(EACCES, _, _) when Sys.win32 ->
(* Attempt to remove the read-only bit on Windows *)
Unix.chmod file 0o666;
Unix.unlink file
with Unix.Unix_error _ as e ->
internal_error "Cannot remove %s (%s)." file (Printexc.to_string e)
)
Expand Down Expand Up @@ -184,18 +188,23 @@ let setup_copy ?(chmod = fun x -> x) ~src ~dst () =
remove_file dst
with Unix.Unix_error(ENOENT, _, _) -> ()
in
let oc =
open_out_gen
[ Open_wronly; Open_creat; Open_trunc; Open_binary ]
perm dst
let fd =
let flags = Unix.[ O_WRONLY; O_CREAT; O_TRUNC ] in
try Unix.openfile dst flags perm
with Unix.Unix_error(EACCES, _, _) when Sys.win32 ->
(* Attempt to remove the read-only bit on Windows *)
begin
try Unix.chmod dst 0o666
with Unix.Unix_error(_, _, _) -> ()
end;
Unix.openfile dst flags perm
in
let fd = Unix.descr_of_out_channel oc in
try
if Unix.((fstat fd).st_perm) <> perm then
Unix.fchmod fd perm;
(ic, oc)
(ic, Unix.out_channel_of_descr fd)
with exn ->
OpamStd.Exn.finalise exn (fun () -> close_out oc)
OpamStd.Exn.finalise exn (fun () -> Unix.close fd)
with exn ->
OpamStd.Exn.finalise exn (fun () -> close_in ic)
Expand Down

0 comments on commit 47847d9

Please sign in to comment.