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