]>
Commit | Line | Data |
---|---|---|
320054e8 DG |
1 | // Copyright (c) 2015-2017 Nuxi, https://nuxi.nl/ |
2 | // | |
3 | // SPDX-License-Identifier: BSD-2-Clause | |
4 | ||
5 | #ifndef SYS_STAT_STAT_IMPL_H | |
6 | #define SYS_STAT_STAT_IMPL_H | |
7 | ||
8 | #include <common/time.h> | |
9 | ||
10 | #include <sys/stat.h> | |
11 | ||
12 | #include <assert.h> | |
446cb3f1 | 13 | #include <wasi/api.h> |
320054e8 DG |
14 | #include <stdbool.h> |
15 | ||
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"); | |
23 | ||
24 | static inline void to_public_stat(const __wasi_filestat_t *in, | |
25 | struct stat *out) { | |
26 | // Ensure that we don't truncate any values. | |
446cb3f1 DG |
27 | static_assert(sizeof(in->dev) == sizeof(out->st_dev), "Size mismatch"); |
28 | static_assert(sizeof(in->ino) == sizeof(out->st_ino), "Size mismatch"); | |
320054e8 DG |
29 | /* |
30 | * The non-standard __st_filetype field appears to only be used for shared | |
31 | * memory, which we don't currently support. | |
32 | */ | |
320054e8 | 33 | /* nlink_t is 64-bit on wasm32, following the x32 ABI. */ |
446cb3f1 DG |
34 | static_assert(sizeof(in->nlink) <= sizeof(out->st_nlink), "Size shortfall"); |
35 | static_assert(sizeof(in->size) == sizeof(out->st_size), "Size mismatch"); | |
320054e8 DG |
36 | |
37 | *out = (struct stat){ | |
446cb3f1 DG |
38 | .st_dev = in->dev, |
39 | .st_ino = in->ino, | |
40 | .st_nlink = in->nlink, | |
41 | .st_size = in->size, | |
42 | .st_atim = timestamp_to_timespec(in->atim), | |
43 | .st_mtim = timestamp_to_timespec(in->mtim), | |
44 | .st_ctim = timestamp_to_timespec(in->ctim), | |
320054e8 DG |
45 | }; |
46 | ||
47 | // Convert file type to legacy types encoded in st_mode. | |
446cb3f1 | 48 | switch (in->filetype) { |
320054e8 DG |
49 | case __WASI_FILETYPE_BLOCK_DEVICE: |
50 | out->st_mode |= S_IFBLK; | |
51 | break; | |
52 | case __WASI_FILETYPE_CHARACTER_DEVICE: | |
53 | out->st_mode |= S_IFCHR; | |
54 | break; | |
55 | case __WASI_FILETYPE_DIRECTORY: | |
56 | out->st_mode |= S_IFDIR; | |
57 | break; | |
58 | case __WASI_FILETYPE_REGULAR_FILE: | |
59 | out->st_mode |= S_IFREG; | |
60 | break; | |
61 | case __WASI_FILETYPE_SOCKET_DGRAM: | |
62 | case __WASI_FILETYPE_SOCKET_STREAM: | |
63 | out->st_mode |= S_IFSOCK; | |
64 | break; | |
65 | case __WASI_FILETYPE_SYMBOLIC_LINK: | |
66 | out->st_mode |= S_IFLNK; | |
67 | break; | |
68 | } | |
69 | } | |
70 | ||
71 | static inline bool utimens_get_timestamps(const struct timespec *times, | |
320054e8 DG |
72 | __wasi_timestamp_t *st_atim, |
73 | __wasi_timestamp_t *st_mtim, | |
74 | __wasi_fstflags_t *flags) { | |
320054e8 DG |
75 | if (times == NULL) { |
76 | // Update both timestamps. | |
446cb3f1 | 77 | *flags = __WASI_FSTFLAGS_ATIM_NOW | __WASI_FSTFLAGS_MTIM_NOW; |
225b285a DG |
78 | *st_atim = (__wasi_timestamp_t) { 0 }; |
79 | *st_mtim = (__wasi_timestamp_t) { 0 }; | |
320054e8 DG |
80 | } else { |
81 | // Set individual timestamps. | |
82 | *flags = 0; | |
83 | switch (times[0].tv_nsec) { | |
84 | case UTIME_NOW: | |
446cb3f1 | 85 | *flags |= __WASI_FSTFLAGS_ATIM_NOW; |
225b285a | 86 | *st_atim = (__wasi_timestamp_t) { 0 }; |
320054e8 DG |
87 | break; |
88 | case UTIME_OMIT: | |
225b285a | 89 | *st_atim = (__wasi_timestamp_t) { 0 }; |
320054e8 DG |
90 | break; |
91 | default: | |
446cb3f1 | 92 | *flags |= __WASI_FSTFLAGS_ATIM; |
320054e8 | 93 | if (!timespec_to_timestamp_exact(×[0], st_atim)) |
320054e8 DG |
94 | return false; |
95 | break; | |
96 | } | |
97 | ||
98 | switch (times[1].tv_nsec) { | |
99 | case UTIME_NOW: | |
446cb3f1 | 100 | *flags |= __WASI_FSTFLAGS_MTIM_NOW; |
225b285a | 101 | *st_mtim = (__wasi_timestamp_t) { 0 }; |
320054e8 DG |
102 | break; |
103 | case UTIME_OMIT: | |
225b285a | 104 | *st_mtim = (__wasi_timestamp_t) { 0 }; |
320054e8 DG |
105 | break; |
106 | default: | |
446cb3f1 | 107 | *flags |= __WASI_FSTFLAGS_MTIM; |
320054e8 | 108 | if (!timespec_to_timestamp_exact(×[1], st_mtim)) |
320054e8 DG |
109 | return false; |
110 | break; | |
111 | } | |
112 | } | |
113 | return true; | |
114 | } | |
115 | ||
116 | #endif |