From a4bd5d79c43303561665b21bf6a564434cdf054c Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Mon, 19 Feb 2024 15:48:57 +0000 Subject: [PATCH] eio_posix: add O_DIRECTORY when opening with a trailing slash Most systems do this anyway, but macos doesn't seem to. This makes things consistent. --- lib_eio_posix/low_level.ml | 7 ++++++- lib_eio_posix/test/open_beneath.ml | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib_eio_posix/low_level.ml b/lib_eio_posix/low_level.ml index 9c9197c8b..00b8d0367 100644 --- a/lib_eio_posix/low_level.ml +++ b/lib_eio_posix/low_level.ml @@ -287,6 +287,9 @@ module Resolve = struct close_tmp state; Printexc.raise_with_backtrace ex bt + let trailing_slash x = + x <> "" && x.[String.length x - 1] = '/' + let open_beneath_fallback ?dirfd:base ~sw ~mode path flags = let path = parse_rel path in with_state base @@ fun state -> @@ -294,10 +297,11 @@ module Resolve = struct If it's a symlink, retry with the target. *) let rec aux leaf = let base = current_dir state in + let flags = if trailing_slash leaf then Open_flags.(flags + directory) else flags in match eio_openat base leaf Open_flags.(flags + nofollow) mode with | fd -> Fd.of_unix fd ~sw ~blocking:false ~close_unix:true | exception (Unix.Unix_error ((ELOOP | ENOTDIR | EMLINK | EUNKNOWNERR _), _, _) as e) -> - (* Note: Linux uses ELOOP or ENOTDIR. FreeBSD used EMLINK. NetBSD uses EFTYPE. *) + (* Note: Linux uses ELOOP or ENOTDIR. FreeBSD uses EMLINK. NetBSD uses EFTYPE. *) match Eio_unix.Private.read_link_unix base leaf with | target -> decr_max_follows state leaf; @@ -337,6 +341,7 @@ module Resolve = struct with_parent_loop ~dirfd path (fun x y -> Ok (fn x y)) let open_unconfined ~sw ~mode dirfd path flags = + let flags = if trailing_slash path then Open_flags.(flags + directory) else flags in Fd.use_exn_opt "openat" dirfd @@ fun dirfd -> eio_openat dirfd path Open_flags.(flags + nonblock) mode |> Fd.of_unix ~sw ~blocking:false ~close_unix:true diff --git a/lib_eio_posix/test/open_beneath.ml b/lib_eio_posix/test/open_beneath.ml index ab5b6ae80..f4f0588fa 100644 --- a/lib_eio_posix/test/open_beneath.ml +++ b/lib_eio_posix/test/open_beneath.ml @@ -38,9 +38,7 @@ let test base path = check ~mode:0 base path L.Open_flags.rdonly; if path <> "" then ( check ~mode:0 base (path ^ "/") L.Open_flags.rdonly; - (* This doesn't work on macos, which seems to allow opening files even with - a trailing "/" (but not with a trailing "/."): *) - (* check ~mode:0 base (path ^ "/.") L.Open_flags.rdonly *) + check ~mode:0 base (path ^ "/.") L.Open_flags.rdonly ) let test_denied base path =