]> git.proxmox.com Git - wasi-libc.git/blame - libc-bottom-half/cloudlibc/src/libc/sys/stat/stat_impl.h
Remove __wasilibc_unmodified_upstream markers from libc-bottom-half.
[wasi-libc.git] / libc-bottom-half / cloudlibc / src / libc / sys / stat / stat_impl.h
CommitLineData
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
16static_assert(S_ISBLK(S_IFBLK), "Value mismatch");
17static_assert(S_ISCHR(S_IFCHR), "Value mismatch");
18static_assert(S_ISDIR(S_IFDIR), "Value mismatch");
19static_assert(S_ISFIFO(S_IFIFO), "Value mismatch");
20static_assert(S_ISLNK(S_IFLNK), "Value mismatch");
21static_assert(S_ISREG(S_IFREG), "Value mismatch");
22static_assert(S_ISSOCK(S_IFSOCK), "Value mismatch");
23
24static 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
71static 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;
320054e8
DG
78 } else {
79 // Set individual timestamps.
80 *flags = 0;
81 switch (times[0].tv_nsec) {
82 case UTIME_NOW:
446cb3f1 83 *flags |= __WASI_FSTFLAGS_ATIM_NOW;
320054e8
DG
84 break;
85 case UTIME_OMIT:
86 break;
87 default:
446cb3f1 88 *flags |= __WASI_FSTFLAGS_ATIM;
320054e8 89 if (!timespec_to_timestamp_exact(&times[0], st_atim))
320054e8
DG
90 return false;
91 break;
92 }
93
94 switch (times[1].tv_nsec) {
95 case UTIME_NOW:
446cb3f1 96 *flags |= __WASI_FSTFLAGS_MTIM_NOW;
320054e8
DG
97 break;
98 case UTIME_OMIT:
99 break;
100 default:
446cb3f1 101 *flags |= __WASI_FSTFLAGS_MTIM;
320054e8 102 if (!timespec_to_timestamp_exact(&times[1], st_mtim))
320054e8
DG
103 return false;
104 break;
105 }
106 }
107 return true;
108}
109
110#endif