Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit d0cc37a

Browse files
committed
Implement fd_fdstat_get and fd_fdstat_set_flags.
This incoporates several wasi-filesystem repo changes too.
1 parent 7ec7715 commit d0cc37a

File tree

3 files changed

+179
-62
lines changed

3 files changed

+179
-62
lines changed

host/src/filesystem.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,25 @@ impl wasi_filesystem::WasiFilesystem for WasiCtx {
3030
todo!()
3131
}
3232

33-
fn info(
33+
fn flags(
3434
&mut self,
3535
fd: wasi_filesystem::Descriptor,
36-
) -> HostResult<wasi_filesystem::FdInfo, wasi_filesystem::Errno> {
36+
) -> HostResult<wasi_filesystem::DescriptorFlags, wasi_filesystem::Errno> {
37+
todo!()
38+
}
39+
40+
fn todo_type(
41+
&mut self,
42+
fd: wasi_filesystem::Descriptor,
43+
) -> HostResult<wasi_filesystem::DescriptorType, wasi_filesystem::Errno> {
44+
todo!()
45+
}
46+
47+
fn set_flags(
48+
&mut self,
49+
fd: wasi_filesystem::Descriptor,
50+
flags: wasi_filesystem::DescriptorFlags,
51+
) -> HostResult<(), wasi_filesystem::Errno> {
3752
todo!()
3853
}
3954

@@ -111,12 +126,19 @@ impl wasi_filesystem::WasiFilesystem for WasiCtx {
111126
todo!()
112127
}
113128

129+
fn stat(
130+
&mut self,
131+
fd: wasi_filesystem::Descriptor,
132+
) -> HostResult<wasi_filesystem::DescriptorStat, wasi_filesystem::Errno> {
133+
todo!()
134+
}
135+
114136
fn stat_at(
115137
&mut self,
116138
fd: wasi_filesystem::Descriptor,
117139
at_flags: wasi_filesystem::AtFlags,
118140
path: String,
119-
) -> HostResult<wasi_filesystem::Stat, wasi_filesystem::Errno> {
141+
) -> HostResult<wasi_filesystem::DescriptorStat, wasi_filesystem::Errno> {
120142
todo!()
121143
}
122144

@@ -148,7 +170,7 @@ impl wasi_filesystem::WasiFilesystem for WasiCtx {
148170
at_flags: wasi_filesystem::AtFlags,
149171
old_path: String,
150172
oflags: wasi_filesystem::OFlags,
151-
flags: wasi_filesystem::Flags,
173+
flags: wasi_filesystem::DescriptorFlags,
152174
mode: wasi_filesystem::Mode,
153175
) -> HostResult<wasi_filesystem::Descriptor, wasi_filesystem::Errno> {
154176
todo!()

src/lib.rs

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -248,43 +248,47 @@ pub unsafe extern "C" fn fd_datasync(fd: Fd) -> Errno {
248248
pub unsafe extern "C" fn fd_fdstat_get(fd: Fd, stat: *mut Fdstat) -> Errno {
249249
match Descriptor::get(fd) {
250250
Descriptor::File(file) => {
251-
let info = match wasi_filesystem::info(file.fd) {
251+
let flags = match wasi_filesystem::flags(file.fd) {
252+
Ok(info) => info,
253+
Err(err) => return errno_from_wasi_filesystem(err),
254+
};
255+
let type_ = match wasi_filesystem::todo_type(file.fd) {
252256
Ok(info) => info,
253257
Err(err) => return errno_from_wasi_filesystem(err),
254258
};
255259

256-
let fs_filetype = match info.type_ {
257-
wasi_filesystem::Type::RegularFile => FILETYPE_REGULAR_FILE,
258-
wasi_filesystem::Type::Directory => FILETYPE_DIRECTORY,
259-
wasi_filesystem::Type::BlockDevice => FILETYPE_BLOCK_DEVICE,
260-
wasi_filesystem::Type::CharacterDevice => FILETYPE_CHARACTER_DEVICE,
261-
wasi_filesystem::Type::Fifo => FILETYPE_UNKNOWN,
262-
wasi_filesystem::Type::Socket => FILETYPE_SOCKET_STREAM,
263-
wasi_filesystem::Type::SymbolicLink => FILETYPE_SYMBOLIC_LINK,
264-
wasi_filesystem::Type::Unknown => FILETYPE_UNKNOWN,
260+
let fs_filetype = match type_ {
261+
wasi_filesystem::DescriptorType::RegularFile => FILETYPE_REGULAR_FILE,
262+
wasi_filesystem::DescriptorType::Directory => FILETYPE_DIRECTORY,
263+
wasi_filesystem::DescriptorType::BlockDevice => FILETYPE_BLOCK_DEVICE,
264+
wasi_filesystem::DescriptorType::CharacterDevice => FILETYPE_CHARACTER_DEVICE,
265+
wasi_filesystem::DescriptorType::Fifo => FILETYPE_UNKNOWN,
266+
wasi_filesystem::DescriptorType::Socket => FILETYPE_SOCKET_STREAM,
267+
wasi_filesystem::DescriptorType::SymbolicLink => FILETYPE_SYMBOLIC_LINK,
268+
wasi_filesystem::DescriptorType::Unknown => FILETYPE_UNKNOWN,
265269
};
266270

267271
let mut fs_flags = 0;
268272
let mut fs_rights_base = !0;
269-
if !info.flags.contains(wasi_filesystem::Flags::READ) {
273+
if !flags.contains(wasi_filesystem::DescriptorFlags::READ) {
270274
fs_rights_base &= !RIGHTS_FD_READ;
271275
}
272-
if !info.flags.contains(wasi_filesystem::Flags::WRITE) {
276+
if !flags.contains(wasi_filesystem::DescriptorFlags::WRITE) {
273277
fs_rights_base &= !RIGHTS_FD_WRITE;
274278
}
275-
if info.flags.contains(wasi_filesystem::Flags::APPEND) {
279+
if flags.contains(wasi_filesystem::DescriptorFlags::APPEND) {
276280
fs_flags |= FDFLAGS_APPEND;
277281
}
278-
if info.flags.contains(wasi_filesystem::Flags::DSYNC) {
282+
if flags.contains(wasi_filesystem::DescriptorFlags::DSYNC) {
279283
fs_flags |= FDFLAGS_DSYNC;
280284
}
281-
if info.flags.contains(wasi_filesystem::Flags::NONBLOCK) {
285+
if flags.contains(wasi_filesystem::DescriptorFlags::NONBLOCK) {
282286
fs_flags |= FDFLAGS_NONBLOCK;
283287
}
284-
if info.flags.contains(wasi_filesystem::Flags::RSYNC) {
288+
if flags.contains(wasi_filesystem::DescriptorFlags::RSYNC) {
285289
fs_flags |= FDFLAGS_RSYNC;
286290
}
287-
if info.flags.contains(wasi_filesystem::Flags::SYNC) {
291+
if flags.contains(wasi_filesystem::DescriptorFlags::SYNC) {
288292
fs_flags |= FDFLAGS_SYNC;
289293
}
290294
let fs_rights_inheriting = fs_rights_base;
@@ -318,7 +322,31 @@ pub unsafe extern "C" fn fd_fdstat_get(fd: Fd, stat: *mut Fdstat) -> Errno {
318322
/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
319323
#[no_mangle]
320324
pub unsafe extern "C" fn fd_fdstat_set_flags(fd: Fd, flags: Fdflags) -> Errno {
321-
unreachable()
325+
let mut new_flags = wasi_filesystem::DescriptorFlags::empty();
326+
if flags & FDFLAGS_APPEND == FDFLAGS_APPEND {
327+
new_flags |= wasi_filesystem::DescriptorFlags::APPEND;
328+
}
329+
if flags & FDFLAGS_DSYNC == FDFLAGS_DSYNC {
330+
new_flags |= wasi_filesystem::DescriptorFlags::DSYNC;
331+
}
332+
if flags & FDFLAGS_NONBLOCK == FDFLAGS_NONBLOCK {
333+
new_flags |= wasi_filesystem::DescriptorFlags::NONBLOCK;
334+
}
335+
if flags & FDFLAGS_RSYNC == FDFLAGS_RSYNC {
336+
new_flags |= wasi_filesystem::DescriptorFlags::RSYNC;
337+
}
338+
if flags & FDFLAGS_SYNC == FDFLAGS_SYNC {
339+
new_flags |= wasi_filesystem::DescriptorFlags::SYNC;
340+
}
341+
342+
match Descriptor::get(fd) {
343+
Descriptor::File(file) => match wasi_filesystem::set_flags(file.fd, new_flags) {
344+
Ok(()) => ERRNO_SUCCESS,
345+
Err(err) => errno_from_wasi_filesystem(err),
346+
},
347+
Descriptor::Log => ERRNO_INVAL,
348+
Descriptor::Closed => ERRNO_BADF,
349+
}
322350
}
323351

324352
/// Adjust the rights associated with a file descriptor.
@@ -335,7 +363,39 @@ pub unsafe extern "C" fn fd_fdstat_set_rights(
335363
/// Return the attributes of an open file.
336364
#[no_mangle]
337365
pub unsafe extern "C" fn fd_filestat_get(fd: Fd, buf: *mut Filestat) -> Errno {
338-
unreachable()
366+
match Descriptor::get(fd) {
367+
Descriptor::File(file) => match wasi_filesystem::stat(file.fd) {
368+
Ok(stat) => {
369+
let filetype = match stat.type_ {
370+
wasi_filesystem::DescriptorType::Unknown => FILETYPE_UNKNOWN,
371+
wasi_filesystem::DescriptorType::Directory => FILETYPE_DIRECTORY,
372+
wasi_filesystem::DescriptorType::BlockDevice => FILETYPE_BLOCK_DEVICE,
373+
wasi_filesystem::DescriptorType::RegularFile => FILETYPE_REGULAR_FILE,
374+
// TODO: Add a way to disginguish between FILETYPE_SOCKET_STREAM and
375+
// FILETYPE_SOCKET_DGRAM.
376+
wasi_filesystem::DescriptorType::Socket => unreachable(),
377+
wasi_filesystem::DescriptorType::SymbolicLink => FILETYPE_SYMBOLIC_LINK,
378+
wasi_filesystem::DescriptorType::CharacterDevice => FILETYPE_CHARACTER_DEVICE,
379+
// preview1 never had a FIFO code.
380+
wasi_filesystem::DescriptorType::Fifo => FILETYPE_UNKNOWN,
381+
};
382+
*buf = Filestat {
383+
dev: stat.dev,
384+
ino: stat.ino,
385+
filetype,
386+
nlink: stat.nlink,
387+
size: stat.size,
388+
atim: stat.atim,
389+
mtim: stat.mtim,
390+
ctim: stat.ctim,
391+
};
392+
ERRNO_SUCCESS
393+
}
394+
Err(err) => errno_from_wasi_filesystem(err),
395+
},
396+
Descriptor::Closed => ERRNO_BADF,
397+
Descriptor::Log => ERRNO_NOTDIR,
398+
}
339399
}
340400

341401
/// Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
@@ -715,17 +775,17 @@ pub unsafe extern "C" fn path_filestat_get(
715775
Descriptor::File(file) => match wasi_filesystem::stat_at(file.fd, at_flags, path) {
716776
Ok(stat) => {
717777
let filetype = match stat.type_ {
718-
wasi_filesystem::Type::Unknown => FILETYPE_UNKNOWN,
719-
wasi_filesystem::Type::Directory => FILETYPE_DIRECTORY,
720-
wasi_filesystem::Type::BlockDevice => FILETYPE_BLOCK_DEVICE,
721-
wasi_filesystem::Type::RegularFile => FILETYPE_REGULAR_FILE,
778+
wasi_filesystem::DescriptorType::Unknown => FILETYPE_UNKNOWN,
779+
wasi_filesystem::DescriptorType::Directory => FILETYPE_DIRECTORY,
780+
wasi_filesystem::DescriptorType::BlockDevice => FILETYPE_BLOCK_DEVICE,
781+
wasi_filesystem::DescriptorType::RegularFile => FILETYPE_REGULAR_FILE,
722782
// TODO: Add a way to disginguish between FILETYPE_SOCKET_STREAM and
723783
// FILETYPE_SOCKET_DGRAM.
724-
wasi_filesystem::Type::Socket => unreachable(),
725-
wasi_filesystem::Type::SymbolicLink => FILETYPE_SYMBOLIC_LINK,
726-
wasi_filesystem::Type::CharacterDevice => FILETYPE_CHARACTER_DEVICE,
784+
wasi_filesystem::DescriptorType::Socket => unreachable(),
785+
wasi_filesystem::DescriptorType::SymbolicLink => FILETYPE_SYMBOLIC_LINK,
786+
wasi_filesystem::DescriptorType::CharacterDevice => FILETYPE_CHARACTER_DEVICE,
727787
// preview1 never had a FIFO code.
728-
wasi_filesystem::Type::Fifo => FILETYPE_UNKNOWN,
788+
wasi_filesystem::DescriptorType::Fifo => FILETYPE_UNKNOWN,
729789
};
730790
*buf = Filestat {
731791
dev: stat.dev,

wit/wasi-filesystem.wit.md

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,12 @@ type filedelta = s64
4646
type timestamp = u64
4747
```
4848

49-
## `fd-info`
50-
```wit
51-
/// Information associated with a descriptor.
52-
///
53-
/// Note: This was called `fdstat` in earlier versions of WASI.
54-
record fd-info {
55-
/// The type of filesystem object referenced by a descriptor.
56-
%type: %type,
57-
/// Flags associated with a descriptor.
58-
%flags: %flags,
59-
}
60-
```
61-
62-
## `type`
49+
## `descriptor-type`
6350
```wit
6451
/// The type of a filesystem object referenced by a descriptor.
6552
///
6653
/// Note: This was called `filetype` in earlier versions of WASI.
67-
enum %type {
54+
enum descriptor-type {
6855
/// The type of the descriptor or file is unknown or is different from
6956
/// any of the other types specified.
7057
unknown,
@@ -85,12 +72,12 @@ enum %type {
8572
}
8673
```
8774

88-
## `flags`
75+
## `descriptor-flags`
8976
```wit
9077
/// Descriptor flags.
9178
///
92-
/// Note: This was called `fd-flags` in earlier versions of WASI.
93-
flags %flags {
79+
/// Note: This was called `fdflags` in earlier versions of WASI.
80+
flags descriptor-flags {
9481
/// Read mode: Data can be read.
9582
read,
9683
/// Write mode: Data can be written to.
@@ -112,18 +99,18 @@ flags %flags {
11299
}
113100
```
114101

115-
## `stat`
102+
## `descriptor-stat`
116103
```wit
117104
/// File attributes.
118105
///
119106
/// Note: This was called `filestat` in earlier versions of WASI.
120-
record stat {
107+
record descriptor-stat {
121108
/// Device ID of device containing the file.
122109
dev: device,
123110
/// File serial number.
124111
ino: inode,
125112
/// File type.
126-
%type: %type,
113+
%type: descriptor-type,
127114
/// Number of hard links to the file.
128115
nlink: linkcount,
129116
/// For regular files, the file size in bytes. For symbolic links, the length
@@ -220,7 +207,7 @@ record dirent {
220207
/// The length of the name of the directory entry.
221208
namelen: size,
222209
/// The type of the file referred to by this directory entry.
223-
%type: %type,
210+
%type: descriptor-type,
224211
}
225212
```
226213

@@ -445,18 +432,53 @@ datasync: func(
445432
) -> result<_, errno>
446433
```
447434

448-
## `info`
435+
## `flags`
436+
```wit
437+
/// Get flags associated with a descriptor.
438+
///
439+
/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX.
440+
///
441+
/// Note: This returns the value that was the `fs_flags` value returned
442+
/// from `fdstat_get` in earlier versions of WASI.
443+
%flags: func(
444+
/// The resource to operate on.
445+
fd: descriptor,
446+
) -> result<descriptor-flags, errno>
447+
```
448+
449+
## `func-type`
450+
```wit
451+
/// Get the dynamic type of a descriptor.
452+
///
453+
/// Note: This returns the same value as the `type` field of the `descriptor-stat`
454+
/// returned by `stat`, `stat-at` and similar.
455+
///
456+
/// Note: This returns similar flags to the `st_mode & S_IFMT` value provided
457+
/// by `fstat` in POSIX.
458+
///
459+
/// Note: This returns the value that was the `fs_filetype` value returned
460+
/// from `fdstat_get` in earlier versions of WASI.
461+
///
462+
/// TODO: Remove the `todo-` when wit-bindgen is updated.
463+
%todo-type: func(
464+
/// The resource to operate on.
465+
fd: descriptor,
466+
) -> result<descriptor-type, errno>
467+
```
468+
469+
## `set-flags`
449470
```wit
450-
/// Get information associated with a descriptor.
471+
/// Set flags associated with a descriptor.
451472
///
452-
/// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX, as well
453-
/// as additional fields.
473+
/// Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
454474
///
455-
/// Note: This was called `fdstat_get` in earlier versions of WASI.
456-
info: func(
475+
/// Note: This was called `fd_fdstat_set_flags` in earlier versions of WASI.
476+
set-flags: func(
457477
/// The resource to operate on.
458478
fd: descriptor,
459-
) -> result<fd-info, errno>
479+
/// The new flags.
480+
%flags: descriptor-flags
481+
) -> result<_, errno>
460482
```
461483

462484
## `set-size`
@@ -598,6 +620,19 @@ create-directory-at: func(
598620
) -> result<_, errno>
599621
```
600622

623+
## `stat`
624+
```wit
625+
/// Return the attributes of an open file or directory.
626+
///
627+
/// Note: This is similar to `fstat` in POSIX.
628+
///
629+
/// Note: This was called `fd_filestat_get` in earlier versions of WASI.
630+
stat: func(
631+
/// The resource to operate on.
632+
fd: descriptor,
633+
) -> result<descriptor-stat, errno>
634+
```
635+
601636
## `stat-at`
602637
```wit
603638
/// Return the attributes of a file or directory.
@@ -612,7 +647,7 @@ stat-at: func(
612647
at-flags: at-flags,
613648
/// The relative path of the file or directory to inspect.
614649
path: string,
615-
) -> result<stat, errno>
650+
) -> result<descriptor-stat, errno>
616651
```
617652

618653
## `set-times-at`
@@ -676,7 +711,7 @@ open-at: func(
676711
/// The method by which to open the file.
677712
o-flags: o-flags,
678713
/// Flags to use for the resulting descriptor.
679-
%flags: %flags,
714+
%flags: descriptor-flags,
680715
/// Permissions to use when creating a new file.
681716
mode: mode
682717
) -> result<descriptor, errno>

0 commit comments

Comments
 (0)