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
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
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<T: Snapshot1 + Send> wasi_unstable::WasiUnstable for T {
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 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())?;
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 let mut old_subs = Vec::new();
522 for slot in subs_array.iter() {
523 let slot = slot?;
524 let sub = memory.read(slot)?;
525 old_subs.push(sub.clone());
526 memory.write(
527 slot.cast(),
528 snapshot1_types::Subscription {
529 userdata: sub.userdata,
530 u: match sub.u {
531 types::SubscriptionU::Clock(c) => {
532 snapshot1_types::SubscriptionU::Clock(c.into())
533 }
534 types::SubscriptionU::FdRead(c) => {
535 snapshot1_types::SubscriptionU::FdRead(c.into())
536 }
537 types::SubscriptionU::FdWrite(c) => {
538 snapshot1_types::SubscriptionU::FdWrite(c.into())
539 }
540 },
541 },
542 )?;
543 }
544 let ret = Snapshot1::poll_oneoff(self, memory, subs.cast(), events.cast(), nsubscriptions)
545 .await?;
546 for (sub, slot) in old_subs.into_iter().zip(subs_array.iter()) {
547 memory.write(slot?, sub)?;
548 }
549 Ok(ret)
550 }
551
552 fn proc_exit(
553 &mut self,
554 memory: &mut GuestMemory<'_>,
555 status: types::Exitcode,
556 ) -> wasmtime::Error {
557 Snapshot1::proc_exit(self, memory, status)
558 }
559
560 fn proc_raise(
561 &mut self,
562 memory: &mut GuestMemory<'_>,
563 sig: types::Signal,
564 ) -> Result<(), Error> {
565 Snapshot1::proc_raise(self, memory, sig.into())?;
566 Ok(())
567 }
568
569 fn sched_yield(&mut self, memory: &mut GuestMemory<'_>) -> Result<(), Error> {
570 Snapshot1::sched_yield(self, memory)?;
571 Ok(())
572 }
573
574 fn random_get(
575 &mut self,
576 memory: &mut GuestMemory<'_>,
577 buf: GuestPtr<u8>,
578 buf_len: types::Size,
579 ) -> Result<(), Error> {
580 Snapshot1::random_get(self, memory, buf, buf_len)?;
581 Ok(())
582 }
583
584 fn sock_recv(
585 &mut self,
586 _memory: &mut GuestMemory<'_>,
587 _fd: types::Fd,
588 _ri_data: types::IovecArray,
589 _ri_flags: types::Riflags,
590 ) -> Result<(types::Size, types::Roflags), Error> {
591 Err(Error::trap(wasmtime::Error::msg("sock_recv unsupported")))
592 }
593
594 fn sock_send(
595 &mut self,
596 _memory: &mut GuestMemory<'_>,
597 _fd: types::Fd,
598 _si_data: types::CiovecArray,
599 _si_flags: types::Siflags,
600 ) -> Result<types::Size, Error> {
601 Err(Error::trap(wasmtime::Error::msg("sock_send unsupported")))
602 }
603
604 fn sock_shutdown(
605 &mut self,
606 _memory: &mut GuestMemory<'_>,
607 _fd: types::Fd,
608 _how: types::Sdflags,
609 ) -> Result<(), Error> {
610 Err(Error::trap(wasmtime::Error::msg(
611 "sock_shutdown unsupported",
612 )))
613 }
614}
615
616fn assert_iovec_array_same() {
617 assert_eq!(
622 std::mem::size_of::<types::IovecArray>(),
623 std::mem::size_of::<snapshot1_types::IovecArray>()
624 );
625}
626
627fn assert_ciovec_array_same() {
628 assert_eq!(
630 std::mem::size_of::<types::CiovecArray>(),
631 std::mem::size_of::<snapshot1_types::CiovecArray>()
632 );
633}
634
635impl From<snapshot1_types::Error> for Error {
636 fn from(error: snapshot1_types::Error) -> Error {
637 match error.downcast() {
638 Ok(errno) => Error::from(types::Errno::from(errno)),
639 Err(trap) => Error::trap(trap),
640 }
641 }
642}
643
644impl From<types::Fd> for snapshot1_types::Fd {
646 fn from(fd: types::Fd) -> snapshot1_types::Fd {
647 u32::from(fd).into()
648 }
649}
650
651impl From<snapshot1_types::Fd> for types::Fd {
653 fn from(fd: snapshot1_types::Fd) -> types::Fd {
654 u32::from(fd).into()
655 }
656}
657
658macro_rules! convert_enum {
664 ($from:ty, $to:ty, $($var:ident),+) => {
665 impl From<$from> for $to {
666 fn from(e: $from) -> $to {
667 match e {
668 $( <$from>::$var => <$to>::$var, )+
669 }
670 }
671 }
672 }
673}
674convert_enum!(
675 snapshot1_types::Errno,
676 types::Errno,
677 Success,
678 TooBig,
679 Acces,
680 Addrinuse,
681 Addrnotavail,
682 Afnosupport,
683 Again,
684 Already,
685 Badf,
686 Badmsg,
687 Busy,
688 Canceled,
689 Child,
690 Connaborted,
691 Connrefused,
692 Connreset,
693 Deadlk,
694 Destaddrreq,
695 Dom,
696 Dquot,
697 Exist,
698 Fault,
699 Fbig,
700 Hostunreach,
701 Idrm,
702 Ilseq,
703 Inprogress,
704 Intr,
705 Inval,
706 Io,
707 Isconn,
708 Isdir,
709 Loop,
710 Mfile,
711 Mlink,
712 Msgsize,
713 Multihop,
714 Nametoolong,
715 Netdown,
716 Netreset,
717 Netunreach,
718 Nfile,
719 Nobufs,
720 Nodev,
721 Noent,
722 Noexec,
723 Nolck,
724 Nolink,
725 Nomem,
726 Nomsg,
727 Noprotoopt,
728 Nospc,
729 Nosys,
730 Notconn,
731 Notdir,
732 Notempty,
733 Notrecoverable,
734 Notsock,
735 Notsup,
736 Notty,
737 Nxio,
738 Overflow,
739 Ownerdead,
740 Perm,
741 Pipe,
742 Proto,
743 Protonosupport,
744 Prototype,
745 Range,
746 Rofs,
747 Spipe,
748 Srch,
749 Stale,
750 Timedout,
751 Txtbsy,
752 Xdev,
753 Notcapable
754);
755convert_enum!(
756 types::Clockid,
757 snapshot1_types::Clockid,
758 Realtime,
759 Monotonic,
760 ProcessCputimeId,
761 ThreadCputimeId
762);
763
764convert_enum!(
765 types::Advice,
766 snapshot1_types::Advice,
767 Normal,
768 Sequential,
769 Random,
770 Willneed,
771 Dontneed,
772 Noreuse
773);
774convert_enum!(
775 snapshot1_types::Filetype,
776 types::Filetype,
777 Directory,
778 BlockDevice,
779 CharacterDevice,
780 RegularFile,
781 SocketDgram,
782 SocketStream,
783 SymbolicLink,
784 Unknown
785);
786convert_enum!(types::Whence, snapshot1_types::Whence, Cur, End, Set);
787
788convert_enum!(
789 types::Signal,
790 snapshot1_types::Signal,
791 None,
792 Hup,
793 Int,
794 Quit,
795 Ill,
796 Trap,
797 Abrt,
798 Bus,
799 Fpe,
800 Kill,
801 Usr1,
802 Segv,
803 Usr2,
804 Pipe,
805 Alrm,
806 Term,
807 Chld,
808 Cont,
809 Stop,
810 Tstp,
811 Ttin,
812 Ttou,
813 Urg,
814 Xcpu,
815 Xfsz,
816 Vtalrm,
817 Prof,
818 Winch,
819 Poll,
820 Pwr,
821 Sys
822);
823
824impl From<snapshot1_types::Prestat> for types::Prestat {
827 fn from(p: snapshot1_types::Prestat) -> types::Prestat {
828 match p {
829 snapshot1_types::Prestat::Dir(d) => types::Prestat::Dir(d.into()),
830 }
831 }
832}
833
834macro_rules! convert_struct {
837 ($from:ty, $to:path, $($field:ident),+) => {
838 impl From<$from> for $to {
839 fn from(e: $from) -> $to {
840 $to {
841 $( $field: e.$field.into(), )+
842 }
843 }
844 }
845 }
846}
847
848convert_struct!(snapshot1_types::PrestatDir, types::PrestatDir, pr_name_len);
849convert_struct!(
850 snapshot1_types::Fdstat,
851 types::Fdstat,
852 fs_filetype,
853 fs_rights_base,
854 fs_rights_inheriting,
855 fs_flags
856);
857convert_struct!(
858 types::SubscriptionClock,
859 snapshot1_types::SubscriptionClock,
860 id,
861 timeout,
862 precision,
863 flags
864);
865convert_struct!(
866 types::SubscriptionFdReadwrite,
867 snapshot1_types::SubscriptionFdReadwrite,
868 file_descriptor
869);
870
871impl From<snapshot1_types::Filestat> for types::Filestat {
875 fn from(f: snapshot1_types::Filestat) -> types::Filestat {
876 types::Filestat {
877 dev: f.dev,
878 ino: f.ino,
879 filetype: f.filetype.into(),
880 nlink: f.nlink.try_into().unwrap_or(u32::MAX),
881 size: f.size,
882 atim: f.atim,
883 mtim: f.mtim,
884 ctim: f.ctim,
885 }
886 }
887}
888
889macro_rules! convert_flags {
891 ($from:ty, $to:ty, $($flag:ident),+) => {
892 impl From<$from> for $to {
893 fn from(f: $from) -> $to {
894 let mut out = <$to>::empty();
895 $(
896 if f.contains(<$from>::$flag) {
897 out |= <$to>::$flag;
898 }
899 )+
900 out
901 }
902 }
903 }
904}
905
906macro_rules! convert_flags_bidirectional {
908 ($from:ty, $to:ty, $($flag:tt)*) => {
909 convert_flags!($from, $to, $($flag)*);
910 convert_flags!($to, $from, $($flag)*);
911 }
912}
913
914convert_flags_bidirectional!(
915 snapshot1_types::Fdflags,
916 types::Fdflags,
917 APPEND,
918 DSYNC,
919 NONBLOCK,
920 RSYNC,
921 SYNC
922);
923convert_flags!(
924 types::Lookupflags,
925 snapshot1_types::Lookupflags,
926 SYMLINK_FOLLOW
927);
928convert_flags!(
929 types::Fstflags,
930 snapshot1_types::Fstflags,
931 ATIM,
932 ATIM_NOW,
933 MTIM,
934 MTIM_NOW
935);
936convert_flags!(
937 types::Oflags,
938 snapshot1_types::Oflags,
939 CREAT,
940 DIRECTORY,
941 EXCL,
942 TRUNC
943);
944convert_flags_bidirectional!(
945 types::Rights,
946 snapshot1_types::Rights,
947 FD_DATASYNC,
948 FD_READ,
949 FD_SEEK,
950 FD_FDSTAT_SET_FLAGS,
951 FD_SYNC,
952 FD_TELL,
953 FD_WRITE,
954 FD_ADVISE,
955 FD_ALLOCATE,
956 PATH_CREATE_DIRECTORY,
957 PATH_CREATE_FILE,
958 PATH_LINK_SOURCE,
959 PATH_LINK_TARGET,
960 PATH_OPEN,
961 FD_READDIR,
962 PATH_READLINK,
963 PATH_RENAME_SOURCE,
964 PATH_RENAME_TARGET,
965 PATH_FILESTAT_GET,
966 PATH_FILESTAT_SET_SIZE,
967 PATH_FILESTAT_SET_TIMES,
968 FD_FILESTAT_GET,
969 FD_FILESTAT_SET_SIZE,
970 FD_FILESTAT_SET_TIMES,
971 PATH_SYMLINK,
972 PATH_REMOVE_DIRECTORY,
973 PATH_UNLINK_FILE,
974 POLL_FD_READWRITE,
975 SOCK_SHUTDOWN
976);
977convert_flags!(
978 types::Subclockflags,
979 snapshot1_types::Subclockflags,
980 SUBSCRIPTION_CLOCK_ABSTIME
981);
982
983impl From<GuestError> for types::Error {
984 fn from(err: GuestError) -> Self {
985 snapshot1_types::Error::from(err).into()
986 }
987}