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