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