1
- use std:: {
2
- path:: { Path , PathBuf } ,
3
- str,
4
- } ;
1
+ use std:: { path:: Path , str} ;
5
2
6
- use wasi_common:: {
7
- dir:: { OpenResult , ReaddirCursor , ReaddirEntity } ,
8
- file:: { FdFlags , Filestat , OFlags } ,
9
- ErrorExt , WasiCtx , WasiDir ,
10
- } ;
11
- use wasmtime_wasi:: { ambient_authority, WasiCtxBuilder } ;
3
+ use wasmtime_wasi:: { preview1:: WasiP1Ctx , DirPerms , FilePerms , WasiCtxBuilder } ;
12
4
13
5
use crate :: wasi_path;
14
6
15
- pub fn build ( script_path : Option < & Path > ) -> WasiCtx {
16
- let mut wasi = WasiCtxBuilder :: new ( ) . build ( ) ;
7
+ pub fn build ( script_path : Option < & Path > ) -> WasiP1Ctx {
8
+ let mut wasi = WasiCtxBuilder :: new ( ) ;
17
9
18
10
if let Some ( script_path) = script_path {
19
11
if let Some ( path) = wasi_path:: from_native ( script_path) {
20
- let _ = wasi. push_env ( "SCRIPT_PATH" , & path) ;
12
+ wasi. env ( "SCRIPT_PATH" , & path) ;
21
13
}
22
14
}
23
15
@@ -32,164 +24,25 @@ pub fn build(script_path: Option<&Path>) -> WasiCtx {
32
24
}
33
25
drives &= !( 1 << drive_idx) ;
34
26
let drive = drive_idx as u8 + b'a' ;
35
- if let Ok ( path) = wasmtime_wasi:: Dir :: open_ambient_dir (
27
+ // Unfortunate if this fails, but we should still continue.
28
+ let _ = wasi. preopened_dir (
36
29
str:: from_utf8 ( & [ b'\\' , b'\\' , b'?' , b'\\' , drive, b':' , b'\\' ] ) . unwrap ( ) ,
37
- ambient_authority ( ) ,
38
- ) {
39
- wasi. push_dir (
40
- Box :: new ( ReadOnlyDir ( wasmtime_wasi:: dir:: Dir :: from_cap_std ( path) ) ) ,
41
- PathBuf :: from ( str:: from_utf8 ( & [ b'/' , b'm' , b'n' , b't' , b'/' , drive] ) . unwrap ( ) ) ,
42
- )
43
- . unwrap ( ) ;
44
- }
30
+ str:: from_utf8 ( & [ b'/' , b'm' , b'n' , b't' , b'/' , drive] ) . unwrap ( ) ,
31
+ DirPerms :: READ ,
32
+ FilePerms :: READ ,
33
+ ) ;
45
34
}
46
35
47
- wasi. push_dir ( Box :: new ( DeviceDir ) , PathBuf :: from ( "/mnt/device" ) )
48
- . unwrap ( ) ;
36
+ // FIXME: Unfortunately wasmtime doesn't support us defining our own
37
+ // file system logic anymore.
38
+
39
+ // wasi.push_dir(Box::new(DeviceDir), PathBuf::from("/mnt/device"))
40
+ // .unwrap();
49
41
}
50
42
#[ cfg( not( windows) ) ]
51
43
{
52
- if let Ok ( path) = wasmtime_wasi:: Dir :: open_ambient_dir ( "/" , ambient_authority ( ) ) {
53
- wasi. push_dir (
54
- Box :: new ( ReadOnlyDir ( wasmtime_wasi:: dir:: Dir :: from_cap_std ( path) ) ) ,
55
- PathBuf :: from ( "/mnt" ) ,
56
- )
57
- . unwrap ( ) ;
58
- }
59
- }
60
- wasi
61
- }
62
-
63
- struct ReadOnlyDir ( wasmtime_wasi:: dir:: Dir ) ;
64
-
65
- #[ async_trait:: async_trait]
66
- impl WasiDir for ReadOnlyDir {
67
- fn as_any ( & self ) -> & dyn std:: any:: Any {
68
- self
69
- }
70
-
71
- async fn open_file (
72
- & self ,
73
- symlink_follow : bool ,
74
- path : & str ,
75
- oflags : OFlags ,
76
- read : bool ,
77
- write : bool ,
78
- fdflags : FdFlags ,
79
- ) -> Result < OpenResult , wasi_common:: Error > {
80
- // We whitelist the OFlags and FdFlags to not accidentally allow
81
- // ways to modify the file system.
82
- const WHITELISTED_O_FLAGS : OFlags = OFlags :: DIRECTORY ;
83
- const WHITELISTED_FD_FLAGS : FdFlags = FdFlags :: NONBLOCK ;
84
-
85
- if write || !WHITELISTED_O_FLAGS . contains ( oflags) || !WHITELISTED_FD_FLAGS . contains ( fdflags)
86
- {
87
- return Err ( wasi_common:: Error :: not_supported ( ) ) ;
88
- }
89
-
90
- Ok (
91
- match self
92
- . 0
93
- . open_file_ ( symlink_follow, path, oflags, read, write, fdflags) ?
94
- {
95
- wasmtime_wasi:: dir:: OpenResult :: Dir ( d) => OpenResult :: Dir ( Box :: new ( ReadOnlyDir ( d) ) ) ,
96
- // We assume that wrapping the file type itself is not
97
- // necessary, because we ensure that the open flags don't allow
98
- // for any modifications anyway.
99
- wasmtime_wasi:: dir:: OpenResult :: File ( f) => OpenResult :: File ( Box :: new ( f) ) ,
100
- } ,
101
- )
102
- }
103
-
104
- async fn readdir (
105
- & self ,
106
- cursor : ReaddirCursor ,
107
- ) -> Result <
108
- Box < dyn Iterator < Item = Result < ReaddirEntity , wasi_common:: Error > > + Send > ,
109
- wasi_common:: Error ,
110
- > {
111
- self . 0 . readdir ( cursor) . await
112
- }
113
-
114
- async fn read_link ( & self , path : & str ) -> Result < PathBuf , wasi_common:: Error > {
115
- self . 0 . read_link ( path) . await
116
- }
117
-
118
- async fn get_filestat ( & self ) -> Result < Filestat , wasi_common:: Error > {
119
- // FIXME: Make sure this says it's readonly, if it ever contains the
120
- // permissions.
121
- self . 0 . get_filestat ( ) . await
44
+ // Unfortunate if this fails, but we should still continue.
45
+ let _ = wasi. preopened_dir ( "/" , "/mnt" , DirPerms :: READ , FilePerms :: READ ) ;
122
46
}
123
-
124
- async fn get_path_filestat (
125
- & self ,
126
- path : & str ,
127
- follow_symlinks : bool ,
128
- ) -> Result < Filestat , wasi_common:: Error > {
129
- // FIXME: Make sure this says it's readonly, if it ever contains the
130
- // permissions.
131
- self . 0 . get_path_filestat ( path, follow_symlinks) . await
132
- }
133
- }
134
-
135
- #[ cfg( windows) ]
136
- struct DeviceDir ;
137
-
138
- #[ cfg( windows) ]
139
- #[ async_trait:: async_trait]
140
- impl WasiDir for DeviceDir {
141
- fn as_any ( & self ) -> & dyn std:: any:: Any {
142
- self
143
- }
144
-
145
- async fn open_file (
146
- & self ,
147
- symlink_follow : bool ,
148
- path : & str ,
149
- oflags : OFlags ,
150
- read : bool ,
151
- write : bool ,
152
- fdflags : FdFlags ,
153
- ) -> Result < OpenResult , wasi_common:: Error > {
154
- let ( dir, file) = device_path ( path) ?;
155
- dir. open_file ( symlink_follow, file, oflags, read, write, fdflags)
156
- . await
157
- }
158
-
159
- // FIXME: cap-primitives/src/windows/fs/get_path tries to strip `\\?\`,
160
- // which breaks paths that aren't valid without it, such as UNC paths:
161
- // https://github.com/bytecodealliance/cap-std/issues/348
162
-
163
- async fn read_link ( & self , path : & str ) -> Result < PathBuf , wasi_common:: Error > {
164
- let ( dir, file) = device_path ( path) ?;
165
- dir. read_link ( file) . await
166
- }
167
-
168
- async fn get_path_filestat (
169
- & self ,
170
- path : & str ,
171
- follow_symlinks : bool ,
172
- ) -> Result < Filestat , wasi_common:: Error > {
173
- let ( dir, file) = device_path ( path) ?;
174
- dir. get_path_filestat ( file, follow_symlinks) . await
175
- }
176
- }
177
-
178
- #[ cfg( windows) ]
179
- fn device_path ( path : & str ) -> Result < ( ReadOnlyDir , & str ) , wasi_common:: Error > {
180
- let ( parent, file) = path
181
- . strip_suffix ( '/' )
182
- . unwrap_or ( path)
183
- . rsplit_once ( '/' )
184
- . ok_or_else ( wasi_common:: Error :: not_supported) ?;
185
-
186
- let parent = wasi_path:: to_native ( & format ! ( "/mnt/device/{parent}" ) , true )
187
- . ok_or_else ( wasi_common:: Error :: not_supported) ?;
188
-
189
- let dir = wasmtime_wasi:: dir:: Dir :: from_cap_std (
190
- wasmtime_wasi:: Dir :: open_ambient_dir ( parent, ambient_authority ( ) )
191
- . map_err ( |_| wasi_common:: Error :: not_supported ( ) ) ?,
192
- ) ;
193
-
194
- Ok ( ( ReadOnlyDir ( dir) , file) )
47
+ wasi. build_p1 ( )
195
48
}
0 commit comments