Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
085a0dc
eio_linux: don't call submit immediately before wait
talex5 May 14, 2024
e403d8f
eio_linux: don't record submit events when there's nothing to submit
talex5 May 14, 2024
fffcf23
Add examples/fs showing how to walk a directory tree
talex5 May 21, 2024
72bf01b
Prepare release
talex5 May 21, 2024
68e50f8
eio_linux: add work-around for signals race
talex5 May 23, 2024
877af2e
Add Eio_unix.Net.import_socket_listening
alyssais May 22, 2024
14fefcb
Prepare release
talex5 May 28, 2024
a68438f
Add example to `Buf_read.seq` documentation
talex5 Jun 14, 2024
3de9383
define struct clone_args for linux-lts versions that don't have it
copy Jun 17, 2024
60a3c42
eio_windows: improve openat error handling
talex5 Jun 19, 2024
e364ed6
eio_windows: run the fs example in CI
talex5 Jun 19, 2024
c698586
Eio.Path: always use "/" as separator
talex5 Jun 19, 2024
0769ce3
Eio_unix.Net: make some return types more polymorphic
talex5 Jun 20, 2024
c92704f
examples/fs: show how to read files while scanning
talex5 Jun 22, 2024
9e00b15
Record trace event when spawning processes
talex5 Aug 8, 2024
b3f089a
eio_linux: refactor fixed buffer code
talex5 Sep 4, 2024
175ccaf
eio_linux: allow alloc_fixed_or_wait to be cancelled
talex5 Sep 4, 2024
ee5f2c5
eio_linux: avoid triggering a TSan warning
talex5 Sep 6, 2024
339582d
Remove unused library
talex5 Sep 18, 2024
c95c2fe
Move Dla to eio.utils
talex5 Sep 18, 2024
ecf63d4
eio_windows: unregister FDs on cancel
talex5 Sep 29, 2024
c1b4a3a
Add advice about using AI for code generation
patricoferris Oct 6, 2024
2fc47fb
Make fork_action.h a public_header
patricoferris Oct 17, 2024
b9bba29
Check if windows has_symlink for tests (#771)
create2000 Oct 21, 2024
df2a120
implementing the chmod function in eio lib
webbunivAdmin Oct 24, 2024
a16a439
commit
webbunivAdmin Oct 24, 2024
4bc7526
Update eio_linux.ml
webbunivAdmin Oct 24, 2024
68f1ab9
COMMIT
webbunivAdmin Oct 25, 2024
5980592
COMMIT
webbunivAdmin Oct 25, 2024
ace1f49
Update main.ml
webbunivAdmin Oct 25, 2024
a294b64
Update fs.md
webbunivAdmin Oct 25, 2024
94fae9e
Update fs.md
webbunivAdmin Oct 25, 2024
112a261
Update fs.md
webbunivAdmin Oct 25, 2024
dc85be0
Update fs.md
webbunivAdmin Oct 25, 2024
dc5a0d8
Update fs.md
webbunivAdmin Oct 25, 2024
e425842
tests on the ``chmod`` for eio
webbunivAdmin Oct 28, 2024
e218917
Update fs.md
webbunivAdmin Oct 28, 2024
1719151
Update fs.md
webbunivAdmin Oct 28, 2024
662792a
Consolidate updates to fs.md
webbunivAdmin Nov 17, 2024
651ebd5
Update fs.md
webbunivAdmin Oct 29, 2024
ba943ff
Update fs.md
webbunivAdmin Oct 29, 2024
0bb124d
Update fs.ml
webbunivAdmin Oct 31, 2024
75732f1
trying to remove some bugs from the tests
webbunivAdmin Oct 31, 2024
02225be
Update fs.md
webbunivAdmin Oct 31, 2024
9390eb4
Update fs.md
webbunivAdmin Oct 31, 2024
17a20aa
Update fs.md
webbunivAdmin Oct 31, 2024
e54ce95
Update fs.md
webbunivAdmin Oct 31, 2024
84cc303
Update fs.md
webbunivAdmin Nov 2, 2024
04843a7
try_chmod implementation
webbunivAdmin Nov 4, 2024
34e7ac4
following the comments
webbunivAdmin Nov 4, 2024
650088b
Update fs.md
webbunivAdmin Nov 4, 2024
cd4fb2b
Update fs.md
webbunivAdmin Nov 4, 2024
ce4adee
Update fs.md
webbunivAdmin Nov 4, 2024
e9b4c36
Update fs.md
webbunivAdmin Nov 4, 2024
97d9220
Update fs.md
webbunivAdmin Oct 29, 2024
e051c6e
Update fs.ml
webbunivAdmin Oct 31, 2024
a0e5da2
trying to remove some bugs from the tests
webbunivAdmin Oct 31, 2024
e6c0861
Update fs.md
webbunivAdmin Oct 31, 2024
7fb0485
Update fs.md
webbunivAdmin Oct 31, 2024
f477b32
Update fs.md
webbunivAdmin Oct 31, 2024
0393837
Update fs.md
webbunivAdmin Oct 31, 2024
55e7f8d
following the comments
webbunivAdmin Nov 4, 2024
65689dc
Preserve backtraces in fork_daemon and fork_promise_exn
talex5 Nov 16, 2024
0c79cbc
to resolve the conflicts
webbunivAdmin Nov 21, 2024
121137d
Merge branch 'ocaml-multicore:main' into main
webbunivAdmin Nov 21, 2024
a060da7
now they are set
webbunivAdmin Nov 21, 2024
fa65b09
Merge branch 'main' of https://github.com/webbunivAdmin/eio
webbunivAdmin Nov 21, 2024
38b1f77
putint the new line
webbunivAdmin Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ _opam
.ocamlformat
.*.swp
*.install
.vscode
1 change: 1 addition & 0 deletions lib_eio/fs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ module Pi = struct
val rename : t -> path -> _ dir -> path -> unit
val read_link : t -> path -> string
val symlink : link_to:path -> t -> path -> unit
val chmod : t -> follow:bool -> perm:File.Unix_perm.t -> path -> unit
val pp : t Fmt.t
val native : t -> string -> string option
end
Expand Down
9 changes: 9 additions & 0 deletions lib_eio/path.ml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,15 @@ let symlink ~link_to source =
let bt = Printexc.get_raw_backtrace () in
Exn.reraise_with_context ex bt "creating symlink %a -> %s" pp source link_to

let chmod ~follow ~perm t =
let (Resource.T (dir, ops), path) = t in
let module X = (val (Resource.get ops Fs.Pi.Dir)) in
try
X.chmod dir ~follow ~perm path
with Exn.Io _ as ex ->
let bt = Printexc.get_raw_backtrace () in
Exn.reraise_with_context ex bt "chmoding file %a" pp t

let rec mkdirs ?(exists_ok=false) ~perm t =
(* Check parent exists first. *)
split t |> Option.iter (fun (parent, _) ->
Expand Down
6 changes: 6 additions & 0 deletions lib_eio/path.mli
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,9 @@ val symlink : link_to:string -> _ t -> unit
{[
Eio.Path.symlink (dir / "current") ~link_to:"version-1.0"
]} *)

val chmod : follow:bool -> perm:int -> _ t -> unit
(** [chmod ~follow ~perm t] changes the permissions of [t] to [perm].

If [follow = true], the permissions of the target of a symlink are changed.
Otherwise, the permissions of the symlink itself are changed. *)
3 changes: 3 additions & 0 deletions lib_eio_linux/eio_linux.ml
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ end = struct

let symlink ~link_to t path =
Low_level.symlink ~link_to t.fd path

let chmod t ~follow ~perm path =
Low_level.chmod t.fd ~follow ~perm path

let pp f t = Fmt.string f (String.escaped t.label)

Expand Down
14 changes: 14 additions & 0 deletions lib_eio_linux/eio_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ CAMLprim value caml_eio_symlinkat(value v_old_path, value v_new_fd, value v_new_
CAMLreturn(Val_unit);
}

CAMLprim value caml_eio_fchmodat(value v_fd, value v_path, value v_mode, value v_flags) {
CAMLparam1(v_path);
char *path;
int ret;
caml_unix_check_path(v_path, "fchmodat");
path = caml_stat_strdup(String_val(v_path));
caml_enter_blocking_section();
ret = fchmodat(Int_val(v_fd), path, Int_val(v_mode), Int_val(v_flags));
caml_leave_blocking_section();
caml_stat_free(path);
if (ret == -1) uerror("fchmodat", v_path);
CAMLreturn(Val_unit);
}

CAMLprim value caml_eio_getrandom(value v_ba, value v_off, value v_len) {
CAMLparam1(v_ba);
ssize_t ret;
Expand Down
10 changes: 10 additions & 0 deletions lib_eio_linux/low_level.ml
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,8 @@ external eio_renameat : Unix.file_descr -> string -> Unix.file_descr -> string -

external eio_symlinkat : string -> Unix.file_descr -> string -> unit = "caml_eio_symlinkat"

external eio_fchmodat : Unix.file_descr -> string -> int -> int -> unit = "caml_eio_fchmodat"

external eio_getrandom : Cstruct.buffer -> int -> int -> int = "caml_eio_getrandom"

external eio_getdents : Unix.file_descr -> string list = "caml_eio_getdents"
Expand Down Expand Up @@ -486,6 +488,14 @@ let symlink ~link_to dir path =
eio_symlinkat link_to parent leaf
with Unix.Unix_error (code, name, arg) -> raise @@ Err.wrap_fs code name arg

let chmod ~follow ~perm dir path =
let module X = Uring.Statx in
with_parent_dir "chmodat" dir path @@ fun parent leaf ->
let flags = if follow then 0 else 0x100 in
try
eio_fchmodat parent leaf perm flags
with Unix.Unix_error (code, name, arg) -> raise @@ Err.wrap_fs code name arg

let shutdown socket command =
try
Fd.use_exn "shutdown" socket @@ fun fd ->
Expand Down
3 changes: 3 additions & 0 deletions lib_eio_linux/low_level.mli
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ val rename : dir_fd -> string -> dir_fd -> string -> unit
val symlink : link_to:string -> dir_fd -> string -> unit
(** [symlink ~link_to dir path] creates a new symlink at [dir / path] pointing to [link_to]. *)

val chmod : follow:bool -> perm:int -> dir_fd -> string -> unit
(** [chmod ~follow ~perm dir path] sets the permissions of [dir / path]. *)

val pipe : sw:Switch.t -> fd * fd
(** [pipe ~sw] returns a pair [r, w] with the readable and writeable ends of a new pipe. *)

Expand Down
14 changes: 14 additions & 0 deletions lib_eio_posix/eio_posix_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,20 @@ CAMLprim value caml_eio_posix_symlinkat(value v_old_path, value v_new_fd, value
CAMLreturn(Val_unit);
}

CAMLprim value caml_eio_posix_fchmodat(value v_fd, value v_path, value v_mode, value v_flags) {
CAMLparam1(v_path);
char *path;
int ret;
caml_unix_check_path(v_path, "fchmodat");
path = caml_stat_strdup(String_val(v_path));
caml_enter_blocking_section();
ret = fchmodat(Int_val(v_fd), path, Int_val(v_mode), Int_val(v_flags));
caml_leave_blocking_section();
caml_stat_free_preserving_errno(path);
if (ret == -1) uerror("fchmodat", v_path);
CAMLreturn(Val_unit);
}

CAMLprim value caml_eio_posix_spawn(value v_errors, value v_actions) {
CAMLparam1(v_actions);
pid_t child_pid;
Expand Down
3 changes: 3 additions & 0 deletions lib_eio_posix/fs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ end = struct
let symlink ~link_to t path =
Err.run (Low_level.symlink ~link_to t.fd) path

let chmod t ~follow ~perm path =
Err.run (Low_level.chmod ~follow ~mode:perm t.fd) path

let open_dir t ~sw path =
let flags = Low_level.Open_flags.(rdonly + directory +? path) in
let fd = Err.run (Low_level.openat ~sw ~mode:0 t.fd path) flags in
Expand Down
9 changes: 9 additions & 0 deletions lib_eio_posix/low_level.ml
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,15 @@ let symlink ~link_to new_dir new_path =
let new_dir = Option.value new_dir ~default:at_fdcwd in
eio_symlinkat link_to new_dir new_path

external eio_fchmodat : Unix.file_descr -> string -> int -> int -> unit = "caml_eio_posix_fchmodat"

let chmod ~follow ~mode dir path =
in_worker_thread "chmod" @@ fun () ->
Resolve.with_parent "chmod" dir path @@ fun dir path ->
let new_dir = Option.value dir ~default:at_fdcwd in
let flags = if follow then 0 else Config.at_symlink_nofollow in
eio_fchmodat new_dir path mode flags

let read_link dirfd path =
in_worker_thread "read_link" @@ fun () ->
Resolve.with_parent "read_link" dirfd path @@ fun dirfd path ->
Expand Down
2 changes: 2 additions & 0 deletions lib_eio_posix/low_level.mli
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ val rename : dir_fd -> string -> dir_fd -> string -> unit
val symlink : link_to:string -> dir_fd -> string -> unit
(** [symlink ~link_to dir path] will create a new symlink at [dir / path]
linking to [link_to]. *)

val chmod : follow:bool -> mode:int -> dir_fd -> string -> unit

val readdir : dir_fd -> string -> string array

Expand Down
4 changes: 4 additions & 0 deletions lib_eio_windows/eio_windows_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ CAMLprim value caml_eio_windows_symlinkat(value v_old_path, value v_new_fd, valu
uerror("symlinkat is not supported on windows yet", Nothing);
}

CAMLprim value eio_windows_chmod(value path, value perm) {
caml_failwith("chmod is not implemented on Windows");
}

CAMLprim value caml_eio_windows_spawn(value v_errors, value v_actions)
{
uerror("processes are not supported on windows yet", Nothing);
Expand Down
5 changes: 5 additions & 0 deletions lib_eio_windows/fs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ end = struct

let v ~label ~sandbox dir_path = { dir_path; sandbox; label; closed = false }

let chmod (_t : t) ~(follow : bool) ~(perm : int) (_path : string) : unit =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like with the other functions that do not have an implementation, we should actually still create a stub in eio_windows_stubs.c that fails. See, for example, how symlink does it. This reduces the burden for someone to come along and do a chmod implementation for Windows.

ignore (follow);
ignore (perm);
failwith "chmod not implemented on Windows yet"

(* Sandboxes use [O_NOFOLLOW] when opening files ([resolve] already removed any symlinks).
This avoids a race where symlink might be added after [realpath] returns.
TODO: Emulate [O_NOFOLLOW] here. *)
Expand Down
51 changes: 46 additions & 5 deletions tests/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Path = Eio.Path
let () = Eio.Exn.Backend.show := false

open Eio.Std
open Eio.Exn

let ( / ) = Path.( / )

Expand Down Expand Up @@ -77,12 +78,13 @@ let chdir path =
traceln "chdir %S" path;
Unix.chdir path

let try_stat path =
let try_stat ?(info_type=`Kind) path =
let stat ~follow =
match Eio.Path.stat ~follow path with
| info -> Fmt.str "@[<h>%a@]" Eio.File.Stat.pp_kind info.kind
| exception Eio.Io (e, _) -> Fmt.str "@[<h>%a@]" Eio.Exn.pp_err e
in
match Eio.Path.stat ~follow path, info_type with
| info, `Perm -> Fmt.str "@[<h>%o@]" info.perm
| info, `Kind -> Fmt.str "@[<h>%a@]" Eio.File.Stat.pp_kind info.kind
| exception Eio.Io (e, _) -> Fmt.str "@[<h>%a@]" Eio.Exn.pp_err e
in
let a = stat ~follow:false in
let b = stat ~follow:true in
if a = b then
Expand All @@ -94,6 +96,11 @@ let try_symlink ~link_to path =
match Path.symlink ~link_to path with
| s -> traceln "symlink %a -> %S" Path.pp path link_to
| exception ex -> traceln "@[<h>%a@]" Eio.Exn.pp ex

let try_chmod path ~follow ~perm =
match Eio.Path.chmod ~follow path ~perm with
| () -> traceln "chmod %a to %o -> ok" Path.pp path perm
| exception ex -> traceln "@[<h>%a@]" Eio.Exn.pp ex
```

# Basic test cases
Expand Down Expand Up @@ -829,6 +836,7 @@ Unconfined:
try_stat cwd;
try_stat (cwd / "..");
try_stat (cwd / "stat_subdir2/..");

Path.symlink ~link_to:".." (cwd / "parent-symlink");
try_stat (cwd / "parent-symlink");
try_stat (cwd / "missing1" / "missing2");
Expand Down Expand Up @@ -1011,3 +1019,36 @@ Exception: Failure "Simulated error".
+"/" / "" = "/"
- : unit = ()
```

```ocaml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To run the test make sure you run dune runtest and dune promote the output back to this file.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still holds true.

# run ~clear:["test-file"] @@ fun env ->
let cwd = Eio.Stdenv.cwd env in
Switch.run @@ fun sw ->

let file_path = cwd / "test-file" in
Path.save ~create:(`Exclusive 0o644) file_path "test data";
traceln "+create <cwd:test-file> with permissions 0o644 -> ok";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of these tests is that the try_x variant of all of the Path functions does two things. (1) it invokes the function it is named after e.g. chmod and (2) it prints something using traceln that we can then inspect to see what it did.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we don't need this.

Suggested change
traceln "+create <cwd:test-file> with permissions 0o644 -> ok";


let initial_perm = (Path.stat ~follow:true file_path).perm in
traceln "+<cwd:test-file> initial permissions = %o" initial_perm;
assert (initial_perm = 0o644);

try_chmod ~follow:true ~perm:0o400 file_path;

try_stat ~info_type:`Perm file_path;

try_chmod ~follow:true ~perm:0o600 file_path;
try_stat ~info_type:`Perm file_path;

Eio.Path.unlink file_path;
traceln "+unlink <cwd:test-file> -> ok";
()
++create <cwd:test-file> with permissions 0o644 -> ok
++<cwd:test-file> initial permissions = 644
+chmod <cwd:test-file> to 400 -> ok
+<cwd:test-file> -> 400
+chmod <cwd:test-file> to 600 -> ok
+<cwd:test-file> -> 600
++unlink <cwd:test-file> -> ok
- : unit = ()
```