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 #ifdef __wasilibc_unmodified_upstream
28 static_assert(sizeof(in
->st_dev
) == sizeof(out
->st_dev
), "Size mismatch");
29 static_assert(sizeof(in
->st_ino
) == sizeof(out
->st_ino
), "Size mismatch");
30 static_assert(sizeof(in
->st_filetype
) == sizeof(out
->__st_filetype
),
33 static_assert(sizeof(in
->dev
) == sizeof(out
->st_dev
), "Size mismatch");
34 static_assert(sizeof(in
->ino
) == sizeof(out
->st_ino
), "Size mismatch");
36 * The non-standard __st_filetype field appears to only be used for shared
37 * memory, which we don't currently support.
40 #ifdef __wasilibc_unmodified_upstream
41 static_assert(sizeof(in
->st_nlink
) == sizeof(out
->st_nlink
), "Size mismatch");
42 static_assert(sizeof(in
->st_size
) == sizeof(out
->st_size
), "Size mismatch");
44 /* nlink_t is 64-bit on wasm32, following the x32 ABI. */
45 static_assert(sizeof(in
->nlink
) <= sizeof(out
->st_nlink
), "Size shortfall");
46 static_assert(sizeof(in
->size
) == sizeof(out
->st_size
), "Size mismatch");
50 #ifdef __wasilibc_unmodified_upstream
51 #define COPY_FIELD(field) .field = in->field
54 .__st_filetype
= in
->st_filetype
,
58 #define COPY_TIMESPEC(field) .field = timestamp_to_timespec(in->field)
59 COPY_TIMESPEC(st_atim
),
60 COPY_TIMESPEC(st_mtim
),
61 COPY_TIMESPEC(st_ctim
),
66 .st_nlink
= in
->nlink
,
68 .st_atim
= timestamp_to_timespec(in
->atim
),
69 .st_mtim
= timestamp_to_timespec(in
->mtim
),
70 .st_ctim
= timestamp_to_timespec(in
->ctim
),
74 // Convert file type to legacy types encoded in st_mode.
75 #ifdef __wasilibc_unmodified_upstream
76 switch (in
->st_filetype
) {
78 switch (in
->filetype
) {
80 case __WASI_FILETYPE_BLOCK_DEVICE
:
81 out
->st_mode
|= S_IFBLK
;
83 case __WASI_FILETYPE_CHARACTER_DEVICE
:
84 out
->st_mode
|= S_IFCHR
;
86 case __WASI_FILETYPE_DIRECTORY
:
87 out
->st_mode
|= S_IFDIR
;
89 case __WASI_FILETYPE_REGULAR_FILE
:
90 out
->st_mode
|= S_IFREG
;
92 case __WASI_FILETYPE_SOCKET_DGRAM
:
93 case __WASI_FILETYPE_SOCKET_STREAM
:
94 out
->st_mode
|= S_IFSOCK
;
96 case __WASI_FILETYPE_SYMBOLIC_LINK
:
97 out
->st_mode
|= S_IFLNK
;
102 static inline bool utimens_get_timestamps(const struct timespec
*times
,
103 #ifdef __wasilibc_unmodified_upstream // fstat
104 __wasi_filestat_t
*fs
,
105 __wasi_fsflags_t
*flags
) {
107 __wasi_timestamp_t
*st_atim
,
108 __wasi_timestamp_t
*st_mtim
,
109 __wasi_fstflags_t
*flags
) {
112 // Update both timestamps.
113 #ifdef __wasilibc_unmodified_upstream // fstat
114 *flags
= __WASI_FILESTAT_ATIM_NOW
| __WASI_FILESTAT_MTIM_NOW
;
116 *flags
= __WASI_FSTFLAGS_ATIM_NOW
| __WASI_FSTFLAGS_MTIM_NOW
;
119 // Set individual timestamps.
121 switch (times
[0].tv_nsec
) {
123 #ifdef __wasilibc_unmodified_upstream // fstat
124 *flags
|= __WASI_FILESTAT_ATIM_NOW
;
126 *flags
|= __WASI_FSTFLAGS_ATIM_NOW
;
132 #ifdef __wasilibc_unmodified_upstream // fstat
133 *flags
|= __WASI_FILESTAT_ATIM
;
134 if (!timespec_to_timestamp_exact(×
[0], &fs
->st_atim
))
136 *flags
|= __WASI_FSTFLAGS_ATIM
;
137 if (!timespec_to_timestamp_exact(×
[0], st_atim
))
143 switch (times
[1].tv_nsec
) {
145 #ifdef __wasilibc_unmodified_upstream // fstat
146 *flags
|= __WASI_FILESTAT_MTIM_NOW
;
148 *flags
|= __WASI_FSTFLAGS_MTIM_NOW
;
154 #ifdef __wasilibc_unmodified_upstream // fstat
155 *flags
|= __WASI_FILESTAT_MTIM
;
156 if (!timespec_to_timestamp_exact(×
[1], &fs
->st_mtim
))
158 *flags
|= __WASI_FSTFLAGS_MTIM
;
159 if (!timespec_to_timestamp_exact(×
[1], st_mtim
))