Compare commits

..

No commits in common. "1ef8ad491378e0e16372d6229b2e80a19bd83a63" and "9256754fe83c9721e9a30f693d310a23f4a05c6b" have entirely different histories.

5 changed files with 24 additions and 63 deletions

View File

@ -69,16 +69,6 @@ let stat ~follow t =
let bt = Printexc.get_raw_backtrace () in let bt = Printexc.get_raw_backtrace () in
Exn.reraise_with_context ex bt "examining %a" pp t Exn.reraise_with_context ex bt "examining %a" pp t
let kind ~follow t =
try ((stat ~follow t).kind :> [File.Stat.kind | `Not_found])
with Exn.Io (Fs.E Not_found _, _) -> `Not_found
let is_file t =
kind ~follow:true t = `Regular_file
let is_directory t =
kind ~follow:true t = `Directory
let with_open_in path fn = let with_open_in path fn =
Switch.run @@ fun sw -> fn (open_in ~sw path) Switch.run @@ fun sw -> fn (open_in ~sw path)

View File

@ -128,7 +128,7 @@ val read_dir : _ t -> string list
Note: The special Unix entries "." and ".." are not included in the results. *) Note: The special Unix entries "." and ".." are not included in the results. *)
(** {1 Metadata} *) (** {2 Metadata} *)
val stat : follow:bool -> _ t -> File.Stat.t val stat : follow:bool -> _ t -> File.Stat.t
(** [stat ~follow t] returns metadata about the file [t]. (** [stat ~follow t] returns metadata about the file [t].
@ -136,21 +136,6 @@ val stat : follow:bool -> _ t -> File.Stat.t
If [t] is a symlink, the information returned is about the target if [follow = true], If [t] is a symlink, the information returned is about the target if [follow = true],
otherwise it is about the link itself. *) otherwise it is about the link itself. *)
val kind : follow:bool -> _ t -> [ File.Stat.kind | `Not_found ]
(** [kind ~follow t] is the type of [t], or [`Not_found] if it doesn't exist.
@param follow If [true] and [t] is a symlink, return the type of the target rather than [`Symbolic_link]. *)
val is_file : _ t -> bool
(** [is_file t] is [true] if [t] is a regular file, and [false] if it doesn't exist or has a different type.
[is_file t] is [kind ~follow:true t = `Regular_file]. *)
val is_directory : _ t -> bool
(** [is_directory t] is [true] if [t] is a directory, and [false] if it doesn't exist or has a different type.
[is_directory t] is [kind ~follow:true t = `Directory]. *)
(** {1 Other} *) (** {1 Other} *)
val unlink : _ t -> unit val unlink : _ t -> unit

View File

@ -536,34 +536,23 @@ end = struct
else Float.pred f else Float.pred f
let stat t ~follow path = let stat t ~follow path =
if !Sched.statx_works then ( let module X = Uring.Statx in
let module X = Uring.Statx in let x = X.create () in
let x = X.create () in Low_level.statx_confined ~follow ~mask:X.Mask.basic_stats t.fd path x;
Low_level.statx_confined ~follow ~mask:X.Mask.basic_stats t.fd path x; { Eio.File.Stat.
{ Eio.File.Stat. dev = X.dev x;
dev = X.dev x; ino = X.ino x;
ino = X.ino x; kind = X.kind x;
kind = X.kind x; perm = X.perm x;
perm = X.perm x; nlink = X.nlink x;
nlink = X.nlink x; uid = X.uid x;
uid = X.uid x; gid = X.gid x;
gid = X.gid x; rdev = X.rdev x;
rdev = X.rdev x; size = X.size x |> Optint.Int63.of_int64;
size = X.size x |> Optint.Int63.of_int64; atime = float_of_time (X.atime_sec x) (X.atime_nsec x);
atime = float_of_time (X.atime_sec x) (X.atime_nsec x); mtime = float_of_time (X.mtime_sec x) (X.mtime_nsec x);
mtime = float_of_time (X.mtime_sec x) (X.mtime_nsec x); ctime = float_of_time (X.ctime_sec x) (X.ctime_nsec x);
ctime = float_of_time (X.ctime_sec x) (X.ctime_nsec x); }
}
) else (
(* Linux < 5.18 *)
Switch.run @@ fun sw ->
let fd = Low_level.openat ~sw ~seekable:false t.fd (if path = "" then "." else path)
~access:`R
~flags:Uring.Open_flags.(cloexec + path + (if follow then empty else nofollow))
~perm:0
in
Flow.stat fd
)
let rename t old_path t2 new_path = let rename t old_path t2 new_path =
match get_dir_fd_opt t2 with match get_dir_fd_opt t2 with

View File

@ -11,8 +11,6 @@ module Lf_queue = Eio_utils.Lf_queue
let system_thread = Ctf.mint_id () let system_thread = Ctf.mint_id ()
let statx_works = ref false (* Before Linux 5.18, statx is unreliable *)
type exit = [`Exit_scheduler] type exit = [`Exit_scheduler]
type file_offset = [ type file_offset = [
@ -528,7 +526,6 @@ let with_sched ?(fallback=no_fallback) config fn =
Uring.exit uring; Uring.exit uring;
fallback (`Msg "Linux >= 5.11 is required for io_uring support") fallback (`Msg "Linux >= 5.11 is required for io_uring support")
) else ( ) else (
statx_works := Uring.op_supported probe Uring.Op.msg_ring;
match match
let mem = let mem =
let fixed_buf_len = block_size * n_blocks in let fixed_buf_len = block_size * n_blocks in

View File

@ -59,6 +59,10 @@ let try_rmdir path =
let chdir path = let chdir path =
traceln "chdir %S" path; traceln "chdir %S" path;
Unix.chdir path Unix.chdir path
let assert_kind path kind =
Path.with_open_in path @@ fun file ->
assert ((Eio.File.stat file).kind = kind)
``` ```
# Basic test cases # Basic test cases
@ -220,9 +224,7 @@ You can remove a file using unlink:
Path.save ~create:(`Exclusive 0o600) (cwd / "subdir/file2") "data2"; Path.save ~create:(`Exclusive 0o600) (cwd / "subdir/file2") "data2";
try_read_file (cwd / "file"); try_read_file (cwd / "file");
try_read_file (cwd / "subdir/file2"); try_read_file (cwd / "subdir/file2");
assert (Eio.Path.kind ~follow:true (cwd / "file") = `Regular_file);
try_unlink (cwd / "file"); try_unlink (cwd / "file");
assert (Eio.Path.kind ~follow:true (cwd / "file") = `Not_found);
try_unlink (cwd / "subdir/file2"); try_unlink (cwd / "subdir/file2");
try_read_file (cwd / "file"); try_read_file (cwd / "file");
try_read_file (cwd / "subdir/file2"); try_read_file (cwd / "subdir/file2");
@ -539,9 +541,9 @@ let try_stat path =
let cwd = Eio.Stdenv.cwd env in let cwd = Eio.Stdenv.cwd env in
Switch.run @@ fun sw -> Switch.run @@ fun sw ->
try_mkdir (cwd / "stat_subdir"); try_mkdir (cwd / "stat_subdir");
assert (Eio.Path.is_directory (cwd / "stat_subdir")); assert_kind (cwd / "stat_subdir") `Directory;
try_write_file (cwd / "stat_reg") "kingbula" ~create:(`Exclusive 0o600); try_write_file (cwd / "stat_reg") "kingbula" ~create:(`Exclusive 0o600);
assert (Eio.Path.is_file (cwd / "stat_reg")); assert_kind (cwd / "stat_reg") `Regular_file;;
+mkdir <cwd:stat_subdir> -> ok +mkdir <cwd:stat_subdir> -> ok
+write <cwd:stat_reg> -> ok +write <cwd:stat_reg> -> ok
- : unit = () - : unit = ()
@ -563,7 +565,6 @@ Fstatat:
try_stat (cwd / ".."); try_stat (cwd / "..");
Unix.symlink ".." "parent-symlink"; Unix.symlink ".." "parent-symlink";
try_stat (cwd / "parent-symlink"); try_stat (cwd / "parent-symlink");
try_stat (cwd / "missing1" / "missing2");
+mkdir <cwd:stat_subdir2> -> ok +mkdir <cwd:stat_subdir2> -> ok
+<cwd:stat_subdir2> -> directory +<cwd:stat_subdir2> -> directory
+<cwd:symlink> -> symbolic link / directory +<cwd:symlink> -> symbolic link / directory
@ -571,7 +572,6 @@ Fstatat:
+<cwd> -> directory +<cwd> -> directory
+<cwd:..> -> Fs Permission_denied _ +<cwd:..> -> Fs Permission_denied _
+<cwd:parent-symlink> -> symbolic link / Fs Permission_denied _ +<cwd:parent-symlink> -> symbolic link / Fs Permission_denied _
+<cwd:missing1/missing2> -> Fs Not_found _
- : unit = () - : unit = ()
``` ```