1 #![expect(unsafe_op_in_unsafe_fn, reason = "old code, not worth updating yet")]
2 
3 const FIRST_PREOPEN: u32 = 3;
4 
5 unsafe fn path_open_preopen() {
6     let prestat = wasip1::fd_prestat_get(FIRST_PREOPEN).expect("fd 3 is a preopen");
7     assert_eq!(
8         prestat.tag,
9         wasip1::PREOPENTYPE_DIR.raw(),
10         "prestat is a directory"
11     );
12     let mut dst = Vec::with_capacity(prestat.u.dir.pr_name_len);
13     wasip1::fd_prestat_dir_name(FIRST_PREOPEN, dst.as_mut_ptr(), dst.capacity())
14         .expect("get preopen dir name");
15     dst.set_len(prestat.u.dir.pr_name_len);
16 
17     let fdstat = wasip1::fd_fdstat_get(FIRST_PREOPEN).expect("get fdstat");
18 
19     println!(
20         "preopen dir: {:?} base {:?} inheriting {:?}",
21         String::from_utf8_lossy(&dst),
22         fdstat.fs_rights_base,
23         fdstat.fs_rights_inheriting
24     );
25     for (right, name) in directory_base_rights() {
26         assert!(
27             (fdstat.fs_rights_base & right) == right,
28             "fs_rights_base does not have required right `{name}`"
29         );
30     }
31     for (right, name) in directory_inheriting_rights() {
32         assert!(
33             (fdstat.fs_rights_inheriting & right) == right,
34             "fs_rights_inheriting does not have required right `{name}`"
35         );
36     }
37 
38     // Open with same rights it has now:
39     let _ = wasip1::path_open(
40         FIRST_PREOPEN,
41         0,
42         ".",
43         0,
44         fdstat.fs_rights_base,
45         fdstat.fs_rights_inheriting,
46         0,
47     )
48     .expect("open with same rights");
49 
50     // Open with an empty set of rights:
51     let _ = wasip1::path_open(FIRST_PREOPEN, 0, ".", 0, 0, 0, 0).expect("open with empty rights");
52 
53     // Open OFLAGS_DIRECTORY with an empty set of rights:
54     let _ = wasip1::path_open(FIRST_PREOPEN, 0, ".", wasip1::OFLAGS_DIRECTORY, 0, 0, 0)
55         .expect("open with O_DIRECTORY empty rights");
56 
57     // Open OFLAGS_DIRECTORY with just the read right:
58     let _ = wasip1::path_open(
59         FIRST_PREOPEN,
60         0,
61         ".",
62         wasip1::OFLAGS_DIRECTORY,
63         wasip1::RIGHTS_FD_READ,
64         0,
65         0,
66     )
67     .expect("open with O_DIRECTORY and read right");
68 
69     if !test_programs::preview1::config().errno_expect_windows() {
70         // Open OFLAGS_DIRECTORY and read/write rights should fail with isdir:
71         let err = wasip1::path_open(
72             FIRST_PREOPEN,
73             0,
74             ".",
75             wasip1::OFLAGS_DIRECTORY,
76             wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
77             0,
78             0,
79         )
80         .err()
81         .expect("open with O_DIRECTORY and read/write should fail");
82         assert_eq!(
83             err,
84             wasip1::ERRNO_ISDIR,
85             "opening directory read/write should fail with ISDIR"
86         );
87     } else {
88         // Open OFLAGS_DIRECTORY and read/write rights will succeed, only on windows:
89         let _ = wasip1::path_open(
90             FIRST_PREOPEN,
91             0,
92             ".",
93             wasip1::OFLAGS_DIRECTORY,
94             wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
95             0,
96             0,
97         )
98         .expect("open with O_DIRECTORY and read/write should succeed on windows");
99     }
100 }
101 
102 fn main() {
103     unsafe {
104         path_open_preopen();
105     }
106 }
107 
108 // Hard-code the set of rights expected for a preopened directory. This is
109 // more brittle than we wanted to test for, but various userland
110 // implementations expect (at least) this set of rights to be present on all
111 // directories:
112 
113 fn directory_base_rights() -> Vec<(wasip1::Rights, &'static str)> {
114     vec![
115         (
116             wasip1::RIGHTS_PATH_CREATE_DIRECTORY,
117             "PATH_CREATE_DIRECTORY",
118         ),
119         (wasip1::RIGHTS_PATH_CREATE_FILE, "PATH_CREATE_FILE"),
120         (wasip1::RIGHTS_PATH_LINK_SOURCE, "PATH_LINK_SOURCE"),
121         (wasip1::RIGHTS_PATH_LINK_TARGET, "PATH_LINK_TARGET"),
122         (wasip1::RIGHTS_PATH_OPEN, "PATH_OPEN"),
123         (wasip1::RIGHTS_FD_READDIR, "FD_READDIR"),
124         (wasip1::RIGHTS_PATH_READLINK, "PATH_READLINK"),
125         (wasip1::RIGHTS_PATH_RENAME_SOURCE, "PATH_RENAME_SOURCE"),
126         (wasip1::RIGHTS_PATH_RENAME_TARGET, "PATH_RENAME_TARGET"),
127         (wasip1::RIGHTS_PATH_SYMLINK, "PATH_SYMLINK"),
128         (
129             wasip1::RIGHTS_PATH_REMOVE_DIRECTORY,
130             "PATH_REMOVE_DIRECTORY",
131         ),
132         (wasip1::RIGHTS_PATH_UNLINK_FILE, "PATH_UNLINK_FILE"),
133         (wasip1::RIGHTS_PATH_FILESTAT_GET, "PATH_FILESTAT_GET"),
134         (
135             wasip1::RIGHTS_PATH_FILESTAT_SET_TIMES,
136             "PATH_FILESTAT_SET_TIMES",
137         ),
138         (wasip1::RIGHTS_FD_FILESTAT_GET, "FD_FILESTAT_GET"),
139         (
140             wasip1::RIGHTS_FD_FILESTAT_SET_TIMES,
141             "FD_FILESTAT_SET_TIMES",
142         ),
143     ]
144 }
145 
146 pub(crate) fn directory_inheriting_rights() -> Vec<(wasip1::Rights, &'static str)> {
147     let mut rights = directory_base_rights();
148     rights.extend_from_slice(&[
149         (wasip1::RIGHTS_FD_DATASYNC, "FD_DATASYNC"),
150         (wasip1::RIGHTS_FD_READ, "FD_READ"),
151         (wasip1::RIGHTS_FD_SEEK, "FD_SEEK"),
152         (wasip1::RIGHTS_FD_FDSTAT_SET_FLAGS, "FD_FDSTAT_SET_FLAGS"),
153         (wasip1::RIGHTS_FD_SYNC, "FD_SYNC"),
154         (wasip1::RIGHTS_FD_TELL, "FD_TELL"),
155         (wasip1::RIGHTS_FD_WRITE, "FD_WRITE"),
156         (wasip1::RIGHTS_FD_ADVISE, "FD_ADVISE"),
157         (wasip1::RIGHTS_FD_ALLOCATE, "FD_ALLOCATE"),
158         (wasip1::RIGHTS_FD_FILESTAT_GET, "FD_FILESTAT_GET"),
159         (wasip1::RIGHTS_FD_FILESTAT_SET_SIZE, "FD_FILESTAT_SET_SIZE"),
160         (
161             wasip1::RIGHTS_FD_FILESTAT_SET_TIMES,
162             "FD_FILESTAT_SET_TIMES",
163         ),
164         (wasip1::RIGHTS_POLL_FD_READWRITE, "POLL_FD_READWRITE"),
165     ]);
166     rights
167 }
168