1use crate::p0::types::Error;
7use crate::p1::WasiP1Ctx;
8use crate::p1::types as snapshot1_types;
9use crate::p1::wasi_snapshot_preview1::WasiSnapshotPreview1 as Snapshot1;
10use wiggle::{GuestError, GuestMemory, GuestPtr};
11
12pub fn add_to_linker_async<T: Send + 'static>(
13 linker: &mut wasmtime::Linker<T>,
14 f: impl Fn(&mut T) -> &mut WasiP1Ctx + Copy + Send + Sync + 'static,
15) -> wasmtime::Result<()> {
16 wasi_unstable::add_to_linker(linker, f)
17}
18
19pub fn add_to_linker_sync<T: Send + 'static>(
20 linker: &mut wasmtime::Linker<T>,
21 f: impl Fn(&mut T) -> &mut WasiP1Ctx + Copy + Send + Sync + 'static,
22) -> wasmtime::Result<()> {
23 sync::add_wasi_unstable_to_linker(linker, f)
24}
25
26wiggle::from_witx!({
27 witx: ["witx/p0/wasi_unstable.witx"],
28 async: {
29 wasi_unstable::{
30 fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
31 fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
32 fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
33 path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
34 path_rename, path_symlink, path_unlink_file, fd_renumber
35 }
36 },
37 errors: { errno => trappable Error },
38});
39
40mod sync {
41 use std::future::Future;
42 use wasmtime::Result;
43
44 wiggle::wasmtime_integration!({
45 witx: ["witx/p0/wasi_unstable.witx"],
46 target: super,
47 block_on[in_tokio]: {
48 wasi_unstable::{
49 fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
50 fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
51 fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
52 path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
53 path_rename, path_symlink, path_unlink_file, fd_renumber
54 }
55 },
56 errors: { errno => trappable Error },
57 });
58
59 fn in_tokio<F: Future>(future: F) -> Result<F::Output> {
62 Ok(crate::runtime::in_tokio(future))
63 }
64}
65
66impl wiggle::GuestErrorType for types::Errno {
67 fn success() -> Self {
68 Self::Success
69 }
70}
71
72impl wasi_unstable::WasiUnstable for WasiP1Ctx {
73 fn set_hostcall_fuel(&mut self, fuel: usize) {
74 Snapshot1::set_hostcall_fuel(self, fuel)
75 }
76 fn args_get(
77 &mut self,
78 memory: &mut GuestMemory<'_>,
79 argv: GuestPtr<GuestPtr<u8>>,
80 argv_buf: GuestPtr<u8>,
81 ) -> Result<(), Error> {
82 Snapshot1::args_get(self, memory, argv, argv_buf)?;
83 Ok(())
84 }
85
86 fn args_sizes_get(
87 &mut self,
88 memory: &mut GuestMemory<'_>,
89 ) -> Result<(types::Size, types::Size), Error> {
90 let s = Snapshot1::args_sizes_get(self, memory)?;
91 Ok(s)
92 }
93
94 fn environ_get(
95 &mut self,
96 memory: &mut GuestMemory<'_>,
97 environ: GuestPtr<GuestPtr<u8>>,
98 environ_buf: GuestPtr<u8>,
99 ) -> Result<(), Error> {
100 Snapshot1::environ_get(self, memory, environ, environ_buf)?;
101 Ok(())
102 }
103
104 fn environ_sizes_get(
105 &mut self,
106 memory: &mut GuestMemory<'_>,
107 ) -> Result<(types::Size, types::Size), Error> {
108 let s = Snapshot1::environ_sizes_get(self, memory)?;
109 Ok(s)
110 }
111
112 fn clock_res_get(
113 &mut self,
114 memory: &mut GuestMemory<'_>,
115 id: types::Clockid,
116 ) -> Result<types::Timestamp, Error> {
117 let t = Snapshot1::clock_res_get(self, memory, id.into())?;
118 Ok(t)
119 }
120
121 fn clock_time_get(
122 &mut self,
123 memory: &mut GuestMemory<'_>,
124 id: types::Clockid,
125 precision: types::Timestamp,
126 ) -> Result<types::Timestamp, Error> {
127 let t = Snapshot1::clock_time_get(self, memory, id.into(), precision)?;
128 Ok(t)
129 }
130
131 async fn fd_advise(
132 &mut self,
133 memory: &mut GuestMemory<'_>,
134 fd: types::Fd,
135 offset: types::Filesize,
136 len: types::Filesize,
137 advice: types::Advice,
138 ) -> Result<(), Error> {
139 Snapshot1::fd_advise(self, memory, fd.into(), offset, len, advice.into()).await?;
140 Ok(())
141 }
142
143 fn fd_allocate(
144 &mut self,
145 memory: &mut GuestMemory<'_>,
146 fd: types::Fd,
147 offset: types::Filesize,
148 len: types::Filesize,
149 ) -> Result<(), Error> {
150 Snapshot1::fd_allocate(self, memory, fd.into(), offset, len)?;
151 Ok(())
152 }
153
154 async fn fd_close(&mut self, memory: &mut GuestMemory<'_>, fd: types::Fd) -> Result<(), Error> {
155 Snapshot1::fd_close(self, memory, fd.into()).await?;
156 Ok(())
157 }
158
159 async fn fd_datasync(
160 &mut self,
161 memory: &mut GuestMemory<'_>,
162 fd: types::Fd,
163 ) -> Result<(), Error> {
164 Snapshot1::fd_datasync(self, memory, fd.into()).await?;
165 Ok(())
166 }
167
168 async fn fd_fdstat_get(
169 &mut self,
170 memory: &mut GuestMemory<'_>,
171 fd: types::Fd,
172 ) -> Result<types::Fdstat, Error> {
173 Ok(Snapshot1::fd_fdstat_get(self, memory, fd.into())
174 .await?
175 .into())
176 }
177
178 fn fd_fdstat_set_flags(
179 &mut self,
180 memory: &mut GuestMemory<'_>,
181 fd: types::Fd,
182 flags: types::Fdflags,
183 ) -> Result<(), Error> {
184 Snapshot1::fd_fdstat_set_flags(self, memory, fd.into(), flags.into())?;
185 Ok(())
186 }
187
188 fn fd_fdstat_set_rights(
189 &mut self,
190 memory: &mut GuestMemory<'_>,
191 fd: types::Fd,
192 fs_rights_base: types::Rights,
193 fs_rights_inheriting: types::Rights,
194 ) -> Result<(), Error> {
195 Snapshot1::fd_fdstat_set_rights(
196 self,
197 memory,
198 fd.into(),
199 fs_rights_base.into(),
200 fs_rights_inheriting.into(),
201 )?;
202 Ok(())
203 }
204
205 async fn fd_filestat_get(
206 &mut self,
207 memory: &mut GuestMemory<'_>,
208 fd: types::Fd,
209 ) -> Result<types::Filestat, Error> {
210 Ok(Snapshot1::fd_filestat_get(self, memory, fd.into())
211 .await?
212 .into())
213 }
214
215 async fn fd_filestat_set_size(
216 &mut self,
217 memory: &mut GuestMemory<'_>,
218 fd: types::Fd,
219 size: types::Filesize,
220 ) -> Result<(), Error> {
221 Snapshot1::fd_filestat_set_size(self, memory, fd.into(), size).await?;
222 Ok(())
223 }
224
225 async fn fd_filestat_set_times(
226 &mut self,
227 memory: &mut GuestMemory<'_>,
228 fd: types::Fd,
229 atim: types::Timestamp,
230 mtim: types::Timestamp,
231 fst_flags: types::Fstflags,
232 ) -> Result<(), Error> {
233 Snapshot1::fd_filestat_set_times(self, memory, fd.into(), atim, mtim, fst_flags.into())
234 .await?;
235 Ok(())
236 }
237
238 async fn fd_read(
239 &mut self,
240 memory: &mut GuestMemory<'_>,
241 fd: types::Fd,
242 iovs: types::IovecArray,
243 ) -> Result<types::Size, Error> {
244 assert_iovec_array_same();
245 let result = Snapshot1::fd_read(self, memory, fd.into(), iovs.cast()).await?;
246 Ok(result)
247 }
248
249 async fn fd_pread(
250 &mut self,
251 memory: &mut GuestMemory<'_>,
252 fd: types::Fd,
253 iovs: types::IovecArray,
254 offset: types::Filesize,
255 ) -> Result<types::Size, Error> {
256 assert_iovec_array_same();
257 let result = Snapshot1::fd_pread(self, memory, fd.into(), iovs.cast(), offset).await?;
258 Ok(result)
259 }
260
261 async fn fd_write(
262 &mut self,
263 memory: &mut GuestMemory<'_>,
264 fd: types::Fd,
265 ciovs: types::CiovecArray,
266 ) -> Result<types::Size, Error> {
267 assert_ciovec_array_same();
268 let result = Snapshot1::fd_write(self, memory, fd.into(), ciovs.cast()).await?;
269 Ok(result)
270 }
271
272 async fn fd_pwrite(
273 &mut self,
274 memory: &mut GuestMemory<'_>,
275 fd: types::Fd,
276 ciovs: types::CiovecArray,
277 offset: types::Filesize,
278 ) -> Result<types::Size, Error> {
279 assert_ciovec_array_same();
280 let result = Snapshot1::fd_pwrite(self, memory, fd.into(), ciovs.cast(), offset).await?;
281 Ok(result)
282 }
283
284 fn fd_prestat_get(
285 &mut self,
286 memory: &mut GuestMemory<'_>,
287 fd: types::Fd,
288 ) -> Result<types::Prestat, Error> {
289 Ok(Snapshot1::fd_prestat_get(self, memory, fd.into())?.into())
290 }
291
292 fn fd_prestat_dir_name(
293 &mut self,
294 memory: &mut GuestMemory<'_>,
295 fd: types::Fd,
296 path: GuestPtr<u8>,
297 path_max_len: types::Size,
298 ) -> Result<(), Error> {
299 Snapshot1::fd_prestat_dir_name(self, memory, fd.into(), path, path_max_len)?;
300 Ok(())
301 }
302
303 async fn fd_renumber(
304 &mut self,
305 memory: &mut GuestMemory<'_>,
306 from: types::Fd,
307 to: types::Fd,
308 ) -> Result<(), Error> {
309 Snapshot1::fd_renumber(self, memory, from.into(), to.into()).await?;
310 Ok(())
311 }
312
313 async fn fd_seek(
314 &mut self,
315 memory: &mut GuestMemory<'_>,
316 fd: types::Fd,
317 offset: types::Filedelta,
318 whence: types::Whence,
319 ) -> Result<types::Filesize, Error> {
320 Ok(Snapshot1::fd_seek(self, memory, fd.into(), offset, whence.into()).await?)
321 }
322
323 async fn fd_sync(&mut self, memory: &mut GuestMemory<'_>, fd: types::Fd) -> Result<(), Error> {
324 Snapshot1::fd_sync(self, memory, fd.into()).await?;
325 Ok(())
326 }
327
328 fn fd_tell(
329 &mut self,
330 memory: &mut GuestMemory<'_>,
331 fd: types::Fd,
332 ) -> Result<types::Filesize, Error> {
333 Ok(Snapshot1::fd_tell(self, memory, fd.into())?)
334 }
335
336 async fn fd_readdir(
337 &mut self,
338 memory: &mut GuestMemory<'_>,
339 fd: types::Fd,
340 buf: GuestPtr<u8>,
341 buf_len: types::Size,
342 cookie: types::Dircookie,
343 ) -> Result<types::Size, Error> {
344 Ok(Snapshot1::fd_readdir(self, memory, fd.into(), buf, buf_len, cookie).await?)
345 }
346
347 async fn path_create_directory(
348 &mut self,
349 memory: &mut GuestMemory<'_>,
350 dirfd: types::Fd,
351 path: GuestPtr<str>,
352 ) -> Result<(), Error> {
353 Snapshot1::path_create_directory(self, memory, dirfd.into(), path).await?;
354 Ok(())
355 }
356
357 async fn path_filestat_get(
358 &mut self,
359 memory: &mut GuestMemory<'_>,
360 dirfd: types::Fd,
361 flags: types::Lookupflags,
362 path: GuestPtr<str>,
363 ) -> Result<types::Filestat, Error> {
364 Ok(
365 Snapshot1::path_filestat_get(self, memory, dirfd.into(), flags.into(), path)
366 .await?
367 .into(),
368 )
369 }
370
371 async fn path_filestat_set_times(
372 &mut self,
373 memory: &mut GuestMemory<'_>,
374 dirfd: types::Fd,
375 flags: types::Lookupflags,
376 path: GuestPtr<str>,
377 atim: types::Timestamp,
378 mtim: types::Timestamp,
379 fst_flags: types::Fstflags,
380 ) -> Result<(), Error> {
381 Snapshot1::path_filestat_set_times(
382 self,
383 memory,
384 dirfd.into(),
385 flags.into(),
386 path,
387 atim,
388 mtim,
389 fst_flags.into(),
390 )
391 .await?;
392 Ok(())
393 }
394
395 async fn path_link(
396 &mut self,
397 memory: &mut GuestMemory<'_>,
398 src_fd: types::Fd,
399 src_flags: types::Lookupflags,
400 src_path: GuestPtr<str>,
401 target_fd: types::Fd,
402 target_path: GuestPtr<str>,
403 ) -> Result<(), Error> {
404 Snapshot1::path_link(
405 self,
406 memory,
407 src_fd.into(),
408 src_flags.into(),
409 src_path,
410 target_fd.into(),
411 target_path,
412 )
413 .await?;
414 Ok(())
415 }
416
417 async fn path_open(
418 &mut self,
419 memory: &mut GuestMemory<'_>,
420 dirfd: types::Fd,
421 dirflags: types::Lookupflags,
422 path: GuestPtr<str>,
423 oflags: types::Oflags,
424 fs_rights_base: types::Rights,
425 fs_rights_inheriting: types::Rights,
426 fdflags: types::Fdflags,
427 ) -> Result<types::Fd, Error> {
428 Ok(Snapshot1::path_open(
429 self,
430 memory,
431 dirfd.into(),
432 dirflags.into(),
433 path,
434 oflags.into(),
435 fs_rights_base.into(),
436 fs_rights_inheriting.into(),
437 fdflags.into(),
438 )
439 .await?
440 .into())
441 }
442
443 async fn path_readlink(
444 &mut self,
445 memory: &mut GuestMemory<'_>,
446 dirfd: types::Fd,
447 path: GuestPtr<str>,
448 buf: GuestPtr<u8>,
449 buf_len: types::Size,
450 ) -> Result<types::Size, Error> {
451 Ok(Snapshot1::path_readlink(self, memory, dirfd.into(), path, buf, buf_len).await?)
452 }
453
454 async fn path_remove_directory(
455 &mut self,
456 memory: &mut GuestMemory<'_>,
457 dirfd: types::Fd,
458 path: GuestPtr<str>,
459 ) -> Result<(), Error> {
460 Snapshot1::path_remove_directory(self, memory, dirfd.into(), path).await?;
461 Ok(())
462 }
463
464 async fn path_rename(
465 &mut self,
466 memory: &mut GuestMemory<'_>,
467 src_fd: types::Fd,
468 src_path: GuestPtr<str>,
469 dest_fd: types::Fd,
470 dest_path: GuestPtr<str>,
471 ) -> Result<(), Error> {
472 Snapshot1::path_rename(
473 self,
474 memory,
475 src_fd.into(),
476 src_path,
477 dest_fd.into(),
478 dest_path,
479 )
480 .await?;
481 Ok(())
482 }
483
484 async fn path_symlink(
485 &mut self,
486 memory: &mut GuestMemory<'_>,
487 src_path: GuestPtr<str>,
488 dirfd: types::Fd,
489 dest_path: GuestPtr<str>,
490 ) -> Result<(), Error> {
491 Snapshot1::path_symlink(self, memory, src_path, dirfd.into(), dest_path).await?;
492 Ok(())
493 }
494
495 async fn path_unlink_file(
496 &mut self,
497 memory: &mut GuestMemory<'_>,
498 dirfd: types::Fd,
499 path: GuestPtr<str>,
500 ) -> Result<(), Error> {
501 Snapshot1::path_unlink_file(self, memory, dirfd.into(), path).await?;
502 Ok(())
503 }
504
505 async fn poll_oneoff(
514 &mut self,
515 memory: &mut GuestMemory<'_>,
516 subs: GuestPtr<types::Subscription>,
517 events: GuestPtr<types::Event>,
518 nsubscriptions: types::Size,
519 ) -> Result<types::Size, Error> {
520 let subs_array = subs.as_array(nsubscriptions);
521 self.consume_fuel_for_array(subs_array)?;
522 let mut old_subs = Vec::new();
523 for slot in subs_array.iter() {
524 let slot = slot?;
525 let sub = memory.read(slot)?;
526 old_subs.push(sub.clone());
527 memory.write(
528 slot.cast(),
529 snapshot1_types::Subscription {
530 userdata: sub.userdata,
531 u: match sub.u {
532 types::SubscriptionU::Clock(c) => {
533 snapshot1_types::SubscriptionU::Clock(c.into())
534 }
535 types::SubscriptionU::FdRead(c) => {
536 snapshot1_types::SubscriptionU::FdRead(c.into())
537 }
538 types::SubscriptionU::FdWrite(c) => {
539 snapshot1_types::SubscriptionU::FdWrite(c.into())
540 }
541 },
542 },
543 )?;
544 }
545 let ret = Snapshot1::poll_oneoff(self, memory, subs.cast(), events.cast(), nsubscriptions)
546 .await?;
547 for (sub, slot) in old_subs.into_iter().zip(subs_array.iter()) {
548 memory.write(slot?, sub)?;
549 }
550 Ok(ret)
551 }
552
553 fn proc_exit(
554 &mut self,
555 memory: &mut GuestMemory<'_>,
556 status: types::Exitcode,
557 ) -> wasmtime::Error {
558 Snapshot1::proc_exit(self, memory, status)
559 }
560
561 fn proc_raise(
562 &mut self,
563 memory: &mut GuestMemory<'_>,
564 sig: types::Signal,
565 ) -> Result<(), Error> {
566 Snapshot1::proc_raise(self, memory, sig.into())?;
567 Ok(())
568 }
569
570 fn sched_yield(&mut self, memory: &mut GuestMemory<'_>) -> Result<(), Error> {
571 Snapshot1::sched_yield(self, memory)?;
572 Ok(())
573 }
574
575 fn random_get(
576 &mut self,
577 memory: &mut GuestMemory<'_>,
578 buf: GuestPtr<u8>,
579 buf_len: types::Size,
580 ) -> Result<(), Error> {
581 Snapshot1::random_get(self, memory, buf, buf_len)?;
582 Ok(())
583 }
584
585 fn sock_recv(
586 &mut self,
587 _memory: &mut GuestMemory<'_>,
588 _fd: types::Fd,
589 _ri_data: types::IovecArray,
590 _ri_flags: types::Riflags,
591 ) -> Result<(types::Size, types::Roflags), Error> {
592 Err(Error::trap(wasmtime::Error::msg("sock_recv unsupported")))
593 }
594
595 fn sock_send(
596 &mut self,
597 _memory: &mut GuestMemory<'_>,
598 _fd: types::Fd,
599 _si_data: types::CiovecArray,
600 _si_flags: types::Siflags,
601 ) -> Result<types::Size, Error> {
602 Err(Error::trap(wasmtime::Error::msg("sock_send unsupported")))
603 }
604
605 fn sock_shutdown(
606 &mut self,
607 _memory: &mut GuestMemory<'_>,
608 _fd: types::Fd,
609 _how: types::Sdflags,
610 ) -> Result<(), Error> {
611 Err(Error::trap(wasmtime::Error::msg(
612 "sock_shutdown unsupported",
613 )))
614 }
615}
616
617fn assert_iovec_array_same() {
618 assert_eq!(
623 std::mem::size_of::<types::IovecArray>(),
624 std::mem::size_of::<snapshot1_types::IovecArray>()
625 );
626}
627
628fn assert_ciovec_array_same() {
629 assert_eq!(
631 std::mem::size_of::<types::CiovecArray>(),
632 std::mem::size_of::<snapshot1_types::CiovecArray>()
633 );
634}
635
636impl From<snapshot1_types::Error> for Error {
637 fn from(error: snapshot1_types::Error) -> Error {
638 match error.downcast() {
639 Ok(errno) => Error::from(types::Errno::from(errno)),
640 Err(trap) => Error::trap(trap),
641 }
642 }
643}
644
645impl From<types::Fd> for snapshot1_types::Fd {
647 fn from(fd: types::Fd) -> snapshot1_types::Fd {
648 u32::from(fd).into()
649 }
650}
651
652impl From<snapshot1_types::Fd> for types::Fd {
654 fn from(fd: snapshot1_types::Fd) -> types::Fd {
655 u32::from(fd).into()
656 }
657}
658
659macro_rules! convert_enum {
665 ($from:ty, $to:ty, $($var:ident),+) => {
666 impl From<$from> for $to {
667 fn from(e: $from) -> $to {
668 match e {
669 $( <$from>::$var => <$to>::$var, )+
670 }
671 }
672 }
673 }
674}
675convert_enum!(
676 snapshot1_types::Errno,
677 types::Errno,
678 Success,
679 TooBig,
680 Acces,
681 Addrinuse,
682 Addrnotavail,
683 Afnosupport,
684 Again,
685 Already,
686 Badf,
687 Badmsg,
688 Busy,
689 Canceled,
690 Child,
691 Connaborted,
692 Connrefused,
693 Connreset,
694 Deadlk,
695 Destaddrreq,
696 Dom,
697 Dquot,
698 Exist,
699 Fault,
700 Fbig,
701 Hostunreach,
702 Idrm,
703 Ilseq,
704 Inprogress,
705 Intr,
706 Inval,
707 Io,
708 Isconn,
709 Isdir,
710 Loop,
711 Mfile,
712 Mlink,
713 Msgsize,
714 Multihop,
715 Nametoolong,
716 Netdown,
717 Netreset,
718 Netunreach,
719 Nfile,
720 Nobufs,
721 Nodev,
722 Noent,
723 Noexec,
724 Nolck,
725 Nolink,
726 Nomem,
727 Nomsg,
728 Noprotoopt,
729 Nospc,
730 Nosys,
731 Notconn,
732 Notdir,
733 Notempty,
734 Notrecoverable,
735 Notsock,
736 Notsup,
737 Notty,
738 Nxio,
739 Overflow,
740 Ownerdead,
741 Perm,
742 Pipe,
743 Proto,
744 Protonosupport,
745 Prototype,
746 Range,
747 Rofs,
748 Spipe,
749 Srch,
750 Stale,
751 Timedout,
752 Txtbsy,
753 Xdev,
754 Notcapable
755);
756convert_enum!(
757 types::Clockid,
758 snapshot1_types::Clockid,
759 Realtime,
760 Monotonic,
761 ProcessCputimeId,
762 ThreadCputimeId
763);
764
765convert_enum!(
766 types::Advice,
767 snapshot1_types::Advice,
768 Normal,
769 Sequential,
770 Random,
771 Willneed,
772 Dontneed,
773 Noreuse
774);
775convert_enum!(
776 snapshot1_types::Filetype,
777 types::Filetype,
778 Directory,
779 BlockDevice,
780 CharacterDevice,
781 RegularFile,
782 SocketDgram,
783 SocketStream,
784 SymbolicLink,
785 Unknown
786);
787convert_enum!(types::Whence, snapshot1_types::Whence, Cur, End, Set);
788
789convert_enum!(
790 types::Signal,
791 snapshot1_types::Signal,
792 None,
793 Hup,
794 Int,
795 Quit,
796 Ill,
797 Trap,
798 Abrt,
799 Bus,
800 Fpe,
801 Kill,
802 Usr1,
803 Segv,
804 Usr2,
805 Pipe,
806 Alrm,
807 Term,
808 Chld,
809 Cont,
810 Stop,
811 Tstp,
812 Ttin,
813 Ttou,
814 Urg,
815 Xcpu,
816 Xfsz,
817 Vtalrm,
818 Prof,
819 Winch,
820 Poll,
821 Pwr,
822 Sys
823);
824
825impl From<snapshot1_types::Prestat> for types::Prestat {
828 fn from(p: snapshot1_types::Prestat) -> types::Prestat {
829 match p {
830 snapshot1_types::Prestat::Dir(d) => types::Prestat::Dir(d.into()),
831 }
832 }
833}
834
835macro_rules! convert_struct {
838 ($from:ty, $to:path, $($field:ident),+) => {
839 impl From<$from> for $to {
840 fn from(e: $from) -> $to {
841 $to {
842 $( $field: e.$field.into(), )+
843 }
844 }
845 }
846 }
847}
848
849convert_struct!(snapshot1_types::PrestatDir, types::PrestatDir, pr_name_len);
850convert_struct!(
851 snapshot1_types::Fdstat,
852 types::Fdstat,
853 fs_filetype,
854 fs_rights_base,
855 fs_rights_inheriting,
856 fs_flags
857);
858convert_struct!(
859 types::SubscriptionClock,
860 snapshot1_types::SubscriptionClock,
861 id,
862 timeout,
863 precision,
864 flags
865);
866convert_struct!(
867 types::SubscriptionFdReadwrite,
868 snapshot1_types::SubscriptionFdReadwrite,
869 file_descriptor
870);
871
872impl From<snapshot1_types::Filestat> for types::Filestat {
876 fn from(f: snapshot1_types::Filestat) -> types::Filestat {
877 types::Filestat {
878 dev: f.dev,
879 ino: f.ino,
880 filetype: f.filetype.into(),
881 nlink: f.nlink.try_into().unwrap_or(u32::MAX),
882 size: f.size,
883 atim: f.atim,
884 mtim: f.mtim,
885 ctim: f.ctim,
886 }
887 }
888}
889
890macro_rules! convert_flags {
892 ($from:ty, $to:ty, $($flag:ident),+) => {
893 impl From<$from> for $to {
894 fn from(f: $from) -> $to {
895 let mut out = <$to>::empty();
896 $(
897 if f.contains(<$from>::$flag) {
898 out |= <$to>::$flag;
899 }
900 )+
901 out
902 }
903 }
904 }
905}
906
907macro_rules! convert_flags_bidirectional {
909 ($from:ty, $to:ty, $($flag:tt)*) => {
910 convert_flags!($from, $to, $($flag)*);
911 convert_flags!($to, $from, $($flag)*);
912 }
913}
914
915convert_flags_bidirectional!(
916 snapshot1_types::Fdflags,
917 types::Fdflags,
918 APPEND,
919 DSYNC,
920 NONBLOCK,
921 RSYNC,
922 SYNC
923);
924convert_flags!(
925 types::Lookupflags,
926 snapshot1_types::Lookupflags,
927 SYMLINK_FOLLOW
928);
929convert_flags!(
930 types::Fstflags,
931 snapshot1_types::Fstflags,
932 ATIM,
933 ATIM_NOW,
934 MTIM,
935 MTIM_NOW
936);
937convert_flags!(
938 types::Oflags,
939 snapshot1_types::Oflags,
940 CREAT,
941 DIRECTORY,
942 EXCL,
943 TRUNC
944);
945convert_flags_bidirectional!(
946 types::Rights,
947 snapshot1_types::Rights,
948 FD_DATASYNC,
949 FD_READ,
950 FD_SEEK,
951 FD_FDSTAT_SET_FLAGS,
952 FD_SYNC,
953 FD_TELL,
954 FD_WRITE,
955 FD_ADVISE,
956 FD_ALLOCATE,
957 PATH_CREATE_DIRECTORY,
958 PATH_CREATE_FILE,
959 PATH_LINK_SOURCE,
960 PATH_LINK_TARGET,
961 PATH_OPEN,
962 FD_READDIR,
963 PATH_READLINK,
964 PATH_RENAME_SOURCE,
965 PATH_RENAME_TARGET,
966 PATH_FILESTAT_GET,
967 PATH_FILESTAT_SET_SIZE,
968 PATH_FILESTAT_SET_TIMES,
969 FD_FILESTAT_GET,
970 FD_FILESTAT_SET_SIZE,
971 FD_FILESTAT_SET_TIMES,
972 PATH_SYMLINK,
973 PATH_REMOVE_DIRECTORY,
974 PATH_UNLINK_FILE,
975 POLL_FD_READWRITE,
976 SOCK_SHUTDOWN
977);
978convert_flags!(
979 types::Subclockflags,
980 snapshot1_types::Subclockflags,
981 SUBSCRIPTION_CLOCK_ABSTIME
982);
983
984impl From<GuestError> for types::Error {
985 fn from(err: GuestError) -> Self {
986 snapshot1_types::Error::from(err).into()
987 }
988}