Compare commits

...

4 Commits

Author SHA1 Message Date
Thomas Leonard
7c4a3adc6e
Merge pull request #617 from talex5/uring-stat
Add Eio_linux.Low_level.statx
2023-09-22 19:25:35 +01:00
Patrick Ferris
602e1d8ae3 Add Eio_linux.Low_level.statx
Co-authored-by: Thomas Leonard <talex5@gmail.com>
2023-09-22 19:07:05 +01:00
Thomas Leonard
b741881d74
Merge pull request #615 from talex5/lintcstubs
Generate prototypes for C stubs from ml files
2023-09-22 11:59:02 +01:00
Thomas Leonard
137399aa6d Generate prototypes for C stubs from ml files 2023-09-19 16:43:31 +01:00
15 changed files with 167 additions and 2 deletions

View File

@ -42,7 +42,7 @@
(logs (>= 0.7.0)) (logs (>= 0.7.0))
(fmt (>= 0.8.9)) (fmt (>= 0.8.9))
(cmdliner (and (>= 1.1.0) :with-test)) (cmdliner (and (>= 1.1.0) :with-test))
(uring (>= 0.5)))) (uring (>= 0.7))))
(package (package
(name eio_posix) (name eio_posix)
(allow_empty) ; Work-around for dune bug #6938 (allow_empty) ; Work-around for dune bug #6938

View File

@ -16,7 +16,7 @@ depends: [
"logs" {>= "0.7.0"} "logs" {>= "0.7.0"}
"fmt" {>= "0.8.9"} "fmt" {>= "0.8.9"}
"cmdliner" {>= "1.1.0" & with-test} "cmdliner" {>= "1.1.0" & with-test}
"uring" {>= "0.5"} "uring" {>= "0.7"}
"odoc" {with-doc} "odoc" {with-doc}
] ]
build: [ build: [

View File

@ -6,3 +6,16 @@
(include_dirs include) (include_dirs include)
(names fork_action stubs)) (names fork_action stubs))
(libraries eio unix threads mtime.clock.os)) (libraries eio unix threads mtime.clock.os))
(rule
(enabled_if %{bin-available:lintcstubs_arity_cmt})
(action
(with-stdout-to
primitives.h.new
(run %{bin:lintcstubs_arity_cmt} %{dep:.eio_unix.objs/byte/eio_unix__Fd.cmt} %{dep:.eio_unix.objs/byte/eio_unix__Fork_action.cmt}))))
(rule
(enabled_if %{bin-available:lintcstubs_arity_cmt})
(alias runtest)
(action
(diff primitives.h primitives.h.new)))

View File

@ -4,6 +4,8 @@
* release it. * release it.
*/ */
#include "primitives.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>

10
lib_eio/unix/primitives.h Normal file
View File

@ -0,0 +1,10 @@
/* AUTOGENERATED FILE, DO NOT EDIT */
#define CAML_NAME_SPACE
#define _GNU_SOURCE
#include <caml/mlvalues.h>
CAMLprim value eio_unix_make_string_array(value);
CAMLprim value eio_unix_fork_execve(value);
CAMLprim value eio_unix_fork_chdir(value);
CAMLprim value eio_unix_fork_fchdir(value);
CAMLprim value eio_unix_fork_dups(value);
CAMLprim value eio_unix_is_blocking(value);

View File

@ -1,3 +1,5 @@
#include "primitives.h"
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>

View File

@ -12,3 +12,28 @@
(include_dirs ../lib_eio/unix/include) (include_dirs ../lib_eio/unix/include)
(names eio_stubs)) (names eio_stubs))
(libraries eio eio.utils eio.unix uring logs fmt)) (libraries eio eio.utils eio.unix uring logs fmt))
(rule
(enabled_if
(and
%{bin-available:lintcstubs_arity_cmt}
(or (= %{system} "linux") ; Historically, just Linux-x86
(= %{system} "linux_eabihf") ; Historically, Linux-arm32
(= %{system} "linux_elf") ; Historically, Linux-x86_32
(= %{system} "elf")))) ; Historically, Linux-ppc64
(action
(with-stdout-to
primitives.h.new
(run %{bin:lintcstubs_arity_cmt} %{dep:.eio_linux.objs/byte/eio_linux__Low_level.cmt} %{dep:.eio_linux.objs/byte/eio_linux__Sched.cmt}))))
(rule
(enabled_if
(and
%{bin-available:lintcstubs_arity_cmt}
(or (= %{system} "linux") ; Historically, just Linux-x86
(= %{system} "linux_eabihf") ; Historically, Linux-arm32
(= %{system} "linux_elf") ; Historically, Linux-x86_32
(= %{system} "elf")))) ; Historically, Linux-ppc64
(alias runtest)
(action
(diff primitives.h primitives.h.new)))

View File

@ -156,6 +156,12 @@ module Low_level : sig
val fstat : fd -> Eio.File.Stat.t val fstat : fd -> Eio.File.Stat.t
(** Like {!Unix.LargeFile.fstat}. *) (** Like {!Unix.LargeFile.fstat}. *)
val statx : ?fd:fd -> mask:Uring.Statx.Mask.t -> string -> Uring.Statx.t -> Uring.Statx.Flags.t -> unit
(** [statx t ?fd ~mask path buf flags] stats [path], which is resolved relative to [fd]
(or the current directory if [fd] is not given).
The results are written to [buf]. *)
val read_dir : fd -> string list val read_dir : fd -> string list
(** [read_dir dir] reads all directory entries from [dir]. (** [read_dir dir] reads all directory entries from [dir].
The entries are not returned in any particular order The entries are not returned in any particular order

View File

@ -19,6 +19,8 @@
// We need caml_convert_signal_number // We need caml_convert_signal_number
#define CAML_INTERNALS #define CAML_INTERNALS
#include "primitives.h"
#include <caml/mlvalues.h> #include <caml/mlvalues.h>
#include <caml/memory.h> #include <caml/memory.h>
#include <caml/alloc.h> #include <caml/alloc.h>

View File

@ -56,6 +56,15 @@ let rec enqueue_openat2 ((access, flags, perm, resolve, fd, path) as args) st ac
if retry then (* wait until an sqe is available *) if retry then (* wait until an sqe is available *)
Queue.push (fun st -> enqueue_openat2 args st action) st.io_q Queue.push (fun st -> enqueue_openat2 args st action) st.io_q
let rec enqueue_statx ((fd, path, buf, flags, mask) as args) st action =
Ctf.label "statx";
let retry = Sched.with_cancel_hook ~action st (fun () ->
Uring.statx st.uring ?fd ~mask path buf flags (Job action)
)
in
if retry then (* wait until an sqe is available *)
Queue.push (fun st -> enqueue_statx args st action) st.io_q
let rec enqueue_unlink ((dir, fd, path) as args) st action = let rec enqueue_unlink ((dir, fd, path) as args) st action =
Ctf.label "unlinkat"; Ctf.label "unlinkat";
let retry = Sched.with_cancel_hook ~action st (fun () -> let retry = Sched.with_cancel_hook ~action st (fun () ->
@ -360,6 +369,16 @@ let with_parent_dir op dir path fn =
fn parent leaf fn parent leaf
) )
let statx ?fd ~mask path buf flags =
let res =
match fd with
| None -> Sched.enter (enqueue_statx (None, path, buf, flags, mask))
| Some fd ->
Fd.use_exn "statx" fd @@ fun fd ->
Sched.enter (enqueue_statx (Some fd, path, buf, flags, mask))
in
if res <> 0 then raise @@ Err.wrap_fs (Uring.error_of_errno res) "statx" path
let mkdir_beneath ~perm dir path = let mkdir_beneath ~perm dir path =
(* [mkdir] is really an operation on [path]'s parent. Get a reference to that first: *) (* [mkdir] is really an operation on [path]'s parent. Get a reference to that first: *)
with_parent_dir "mkdir" dir path @@ fun parent leaf -> with_parent_dir "mkdir" dir path @@ fun parent leaf ->

View File

@ -0,0 +1,11 @@
/* AUTOGENERATED FILE, DO NOT EDIT */
#define CAML_NAME_SPACE
#define _GNU_SOURCE
#include <caml/mlvalues.h>
CAMLprim value caml_eio_eventfd(value);
CAMLprim value caml_eio_mkdirat(value, value, value);
CAMLprim value caml_eio_renameat(value, value, value, value);
CAMLprim value caml_eio_getrandom(value, value, value);
CAMLprim value caml_eio_getdents(value);
CAMLprim value caml_eio_clone3(value, value);
CAMLprim value caml_eio_pidfd_send_signal(value, value);

View File

@ -155,6 +155,49 @@ let test_expose_backend () =
let backend = Eio.Stdenv.backend_id env in let backend = Eio.Stdenv.backend_id env in
assert (backend = "linux") assert (backend = "linux")
let kind_t = Alcotest.of_pp Uring.Statx.pp_kind
let test_statx () =
let module X = Uring.Statx in
Eio_linux.run ~queue_depth:4 @@ fun env ->
let ( / ) = Eio.Path.( / ) in
let path = env#cwd / "test2.data" in
Eio.Path.with_open_out path ~create:(`Exclusive 0o600) @@ fun file ->
Eio.Flow.copy_string "hello" file;
let buf = Uring.Statx.create () in
let test expected_len ~flags ?fd path =
Eio_linux.Low_level.statx ~mask:X.Mask.(type' + size) ?fd path buf flags;
Alcotest.check kind_t "kind" `Regular_file (Uring.Statx.kind buf);
Alcotest.(check int64) "size" expected_len (Uring.Statx.size buf)
in
(* Lookup via cwd *)
test 5L ~flags:X.Flags.empty ?fd:None "test2.data";
Eio.Flow.copy_string "+" file;
(* Lookup via file FD *)
Switch.run (fun sw ->
let fd = Eio_linux.Low_level.openat2 ~sw
~access:`R
~flags:Uring.Open_flags.empty
~perm:0
~resolve:Uring.Resolve.empty
"test2.data"
in
test 6L ~flags:X.Flags.empty_path ~fd ""
);
(* Lookup via directory FD *)
Eio.Flow.copy_string "+" file;
Switch.run (fun sw ->
let fd = Eio_linux.Low_level.openat2 ~sw
~access:`R
~flags:Uring.Open_flags.path
~perm:0
~resolve:Uring.Resolve.empty
"."
in
test 7L ~flags:X.Flags.empty_path ~fd "test2.data"
);
()
let () = let () =
let open Alcotest in let open Alcotest in
run "eio_linux" [ run "eio_linux" [
@ -167,5 +210,6 @@ let () =
test_case "no_sqe" `Quick test_no_sqe; test_case "no_sqe" `Quick test_no_sqe;
test_case "read_exact" `Quick test_read_exact; test_case "read_exact" `Quick test_read_exact;
test_case "expose_backend" `Quick test_expose_backend; test_case "expose_backend" `Quick test_expose_backend;
test_case "statx" `Quick test_statx;
]; ];
] ]

View File

@ -13,3 +13,16 @@
(targets config.ml) (targets config.ml)
(enabled_if (= %{os_type} "Unix")) (enabled_if (= %{os_type} "Unix"))
(action (run ./include/discover.exe))) (action (run ./include/discover.exe)))
(rule
(enabled_if (and (= %{os_type} "Unix") %{bin-available:lintcstubs_arity_cmt}))
(action
(with-stdout-to
primitives.h.new
(run %{bin:lintcstubs_arity_cmt} %{dep:.eio_posix.objs/byte/eio_posix__Low_level.cmt}))))
(rule
(enabled_if (and (= %{os_type} "Unix") %{bin-available:lintcstubs_arity_cmt}))
(alias runtest)
(action
(diff primitives.h primitives.h.new)))

View File

@ -1,3 +1,5 @@
#include "primitives.h"
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include <sys/types.h> #include <sys/types.h>

View File

@ -0,0 +1,16 @@
/* AUTOGENERATED FILE, DO NOT EDIT */
#define CAML_NAME_SPACE
#define _GNU_SOURCE
#include <caml/mlvalues.h>
CAMLprim value caml_eio_posix_send_msg(value, value, value, value, value);
CAMLprim value caml_eio_posix_recv_msg(value, value, value);
CAMLprim value caml_eio_posix_getrandom(value, value, value);
CAMLprim value caml_eio_posix_readv(value, value);
CAMLprim value caml_eio_posix_writev(value, value);
CAMLprim value caml_eio_posix_preadv(value, value, value);
CAMLprim value caml_eio_posix_pwritev(value, value, value);
CAMLprim value caml_eio_posix_openat(value, value, value, value);
CAMLprim value caml_eio_posix_mkdirat(value, value, value);
CAMLprim value caml_eio_posix_unlinkat(value, value, value);
CAMLprim value caml_eio_posix_renameat(value, value, value, value);
CAMLprim value caml_eio_posix_spawn(value, value);