1 // Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/
3 // SPDX-License-Identifier: BSD-2-Clause
5 #ifndef SYS_STAT_STAT_IMPL_H
6 #define SYS_STAT_STAT_IMPL_H
8 #include <common/time.h>
16 static_assert(S_ISBLK(S_IFBLK
), "Value mismatch");
17 static_assert(S_ISCHR(S_IFCHR
), "Value mismatch");
18 static_assert(S_ISDIR(S_IFDIR
), "Value mismatch");
19 static_assert(S_ISFIFO(S_IFIFO
), "Value mismatch");
20 static_assert(S_ISLNK(S_IFLNK
), "Value mismatch");
21 static_assert(S_ISREG(S_IFREG
), "Value mismatch");
22 static_assert(S_ISSOCK(S_IFSOCK
), "Value mismatch");
24 static inline void to_public_stat(const __wasi_filestat_t
*in
,
26 // Ensure that we don't truncate any values.
27 static_assert(sizeof(in
->dev
) == sizeof(out
->st_dev
), "Size mismatch");
28 static_assert(sizeof(in
->ino
) == sizeof(out
->st_ino
), "Size mismatch");
30 * The non-standard __st_filetype field appears to only be used for shared
31 * memory, which we don't currently support.
33 /* nlink_t is 64-bit on wasm32, following the x32 ABI. */
34 static_assert(sizeof(in
->nlink
) <= sizeof(out
->st_nlink
), "Size shortfall");
35 static_assert(sizeof(in
->size
) == sizeof(out
->st_size
), "Size mismatch");
40 .st_nlink
= in
->nlink
,
42 .st_atim
= timestamp_to_timespec(in
->atim
),
43 .st_mtim
= timestamp_to_timespec(in
->mtim
),
44 .st_ctim
= timestamp_to_timespec(in
->ctim
),
47 // Convert file type to legacy types encoded in st_mode.
48 switch (in
->filetype
) {
49 case __WASI_FILETYPE_BLOCK_DEVICE
:
50 out
->st_mode
|= S_IFBLK
;
52 case __WASI_FILETYPE_CHARACTER_DEVICE
:
53 out
->st_mode
|= S_IFCHR
;
55 case __WASI_FILETYPE_DIRECTORY
:
56 out
->st_mode
|= S_IFDIR
;
58 case __WASI_FILETYPE_REGULAR_FILE
:
59 out
->st_mode
|= S_IFREG
;
61 case __WASI_FILETYPE_SOCKET_DGRAM
:
62 case __WASI_FILETYPE_SOCKET_STREAM
:
63 out
->st_mode
|= S_IFSOCK
;
65 case __WASI_FILETYPE_SYMBOLIC_LINK
:
66 out
->st_mode
|= S_IFLNK
;
71 static inline bool utimens_get_timestamps(const struct timespec
*times
,
72 __wasi_timestamp_t
*st_atim
,
73 __wasi_timestamp_t
*st_mtim
,
74 __wasi_fstflags_t
*flags
) {
76 // Update both timestamps.
77 *flags
= __WASI_FSTFLAGS_ATIM_NOW
| __WASI_FSTFLAGS_MTIM_NOW
;
78 *st_atim
= (__wasi_timestamp_t
) { 0 };
79 *st_mtim
= (__wasi_timestamp_t
) { 0 };
81 // Set individual timestamps.
83 switch (times
[0].tv_nsec
) {
85 *flags
|= __WASI_FSTFLAGS_ATIM_NOW
;
86 *st_atim
= (__wasi_timestamp_t
) { 0 };
89 *st_atim
= (__wasi_timestamp_t
) { 0 };
92 *flags
|= __WASI_FSTFLAGS_ATIM
;
93 if (!timespec_to_timestamp_exact(×
[0], st_atim
))
98 switch (times
[1].tv_nsec
) {
100 *flags
|= __WASI_FSTFLAGS_MTIM_NOW
;
101 *st_mtim
= (__wasi_timestamp_t
) { 0 };
104 *st_mtim
= (__wasi_timestamp_t
) { 0 };
107 *flags
|= __WASI_FSTFLAGS_MTIM
;
108 if (!timespec_to_timestamp_exact(×
[1], st_mtim
))