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