Rune - Fix threading bugs
[rune.git] / libruntime / sys_fstat.c
1 /*
2  * SYS_FSTAT.C
3  */
4
5 #include "defs.h"
6 #include <sys/stat.h>
7
8 /*
9  * FStatStor
10  */
11 typedef struct FStatStor {
12         runeino_t       ino;
13         int64_t         nlink;
14         runeuid_t       uid;
15         runegid_t       gid;
16         runedev_t       dev;
17         uint32_t        gen;
18         int             error;
19         runemode_t      mode;
20         runemode_t      filler02;
21         runetime_t      atime;
22         runetime_t      mtime;
23         runetime_t      ctime;
24         runeoff_t       size;
25 } FStatStor;
26
27 struct stat_path_args {
28         LValueStor      lvs;
29         PointerStor     path;
30 };
31
32 struct stat_fd_args {
33         LValueStor      lvs;
34         int32_t         fd;
35 #if LONG_BITS == 64
36         int32_t         filler01;
37 #endif
38 };
39
40 static __inline
41 void
42 rstfixup(struct stat *st, FStatStor *rst)
43 {
44         /*
45          * Portability fixup - signextend if machine target
46          * uses smaller types.
47          */
48         if (sizeof(st->st_ino) < sizeof(int64_t))
49                 rst->ino = (int64_t)(int)st->st_ino;
50         else
51                 rst->ino = st->st_ino;
52
53         if (sizeof(st->st_nlink) < sizeof(int64_t))
54                 rst->nlink = (int64_t)(int)st->st_nlink;
55         else
56                 rst->nlink = st->st_nlink;
57
58         if (sizeof(st->st_uid) < sizeof(int64_t))
59                 rst->uid = (int64_t)(int)st->st_uid;
60         else
61                 rst->uid = st->st_uid;
62
63         if (sizeof(st->st_gid) < sizeof(int64_t))
64                 rst->gid = (int64_t)(int)st->st_gid;
65         else
66                 rst->gid = st->st_gid;
67
68         rst->dev = st->st_dev;
69         rst->gen = st->st_gen;
70         rst->mode = st->st_mode;
71
72         if (sizeof(st->st_atime) < sizeof(int64_t)) {
73                 rst->atime = (int64_t)(uint32_t)st->st_atime;
74                 rst->mtime = (int64_t)(uint32_t)st->st_mtime;
75                 rst->ctime = (int64_t)(uint32_t)st->st_ctime;
76         } else {
77                 rst->atime = st->st_atime;
78                 rst->mtime = st->st_mtime;
79                 rst->ctime = st->st_ctime;
80         }
81
82         if (sizeof(st->st_size) < sizeof(int64_t))
83                 rst->size = (int64_t)(int)st->st_size;
84         else
85                 rst->size = st->st_size;
86 }
87
88 void
89 RuneSysCall_stat(struct stat_path_args *args, int *resp)
90 {
91         FStatStor *rst = args->lvs.s_Addr;
92         const char *path = args->path.s_Addr;
93         struct stat st;
94
95         STRBOUNDSCHECK(&args->path, PATH_MAX);
96         if (stat(path, &st) == 0) {
97                 rstfixup(&st, rst);
98                 rst->error = 0;
99                 *resp = 0;
100         } else {
101                 rst->error = errno;
102                 *resp = -1;
103         }
104 }
105
106 void
107 RuneSysCall_lstat(struct stat_path_args *args, int *resp)
108 {
109         FStatStor *rst = args->lvs.s_Addr;
110         const char *path = args->path.s_Addr;
111         struct stat st;
112
113         STRBOUNDSCHECK(&args->path, PATH_MAX);
114         if (lstat(path, &st) == 0) {
115                 rstfixup(&st, rst);
116                 rst->error = 0;
117                 *resp = 0;
118         } else {
119                 rst->error = errno;
120                 *resp = -1;
121         }
122 }
123
124 void
125 RuneSysCall_fstat(struct stat_fd_args *args, int *resp)
126 {
127         FStatStor *rst = args->lvs.s_Addr;
128         struct stat st;
129
130         if (fstat(args->fd, &st) == 0) {
131                 rstfixup(&st, rst);
132                 rst->error = 0;
133                 *resp = 0;
134         } else {
135                 rst->error = errno;
136                 *resp = -1;
137         }
138 }
139
140 void
141 RuneSysCall_chmod(struct stat_path_args *args, int *resp)
142 {
143         FStatStor *rst = args->lvs.s_Addr;
144         const char *path = args->path.s_Addr;
145
146         STRBOUNDSCHECK(&args->path, PATH_MAX);
147         if (chmod(path, rst->mode) == 0) {
148                 rst->error = 0;
149                 *resp = 0;
150         } else {
151                 rst->error = errno;
152                 *resp = -1;
153         }
154 }
155
156 void
157 RuneSysCall_lchmod(struct stat_path_args *args, int *resp)
158 {
159         FStatStor *rst = args->lvs.s_Addr;
160         const char *path = args->path.s_Addr;
161
162         STRBOUNDSCHECK(&args->path, PATH_MAX);
163         if (lchmod(path, rst->mode) == 0) {
164                 rst->error = 0;
165                 *resp = 0;
166         } else {
167                 rst->error = errno;
168                 *resp = -1;
169         }
170 }
171
172 void
173 RuneSysCall_fchmod(struct stat_fd_args *args, int *resp)
174 {
175         FStatStor *rst = args->lvs.s_Addr;
176
177         if (fchmod(args->fd, rst->mode) == 0) {
178                 rst->error = 0;
179                 *resp = 0;
180         } else {
181                 rst->error = errno;
182                 *resp = -1;
183         }
184 }
185
186 void
187 RuneSysCall_chown(struct stat_path_args *args, int *resp)
188 {
189         FStatStor *rst = args->lvs.s_Addr;
190         const char *path = args->path.s_Addr;
191
192         STRBOUNDSCHECK(&args->path, PATH_MAX);
193         if (chown(path, rst->uid, rst->gid) == 0) {
194                 rst->error = 0;
195                 *resp = 0;
196         } else {
197                 rst->error = errno;
198                 *resp = -1;
199         }
200 }
201
202 void
203 RuneSysCall_lchown(struct stat_path_args *args, int *resp)
204 {
205         FStatStor *rst = args->lvs.s_Addr;
206         const char *path = args->path.s_Addr;
207
208         STRBOUNDSCHECK(&args->path, PATH_MAX);
209         if (lchown(path, rst->uid, rst->gid) == 0) {
210                 rst->error = 0;
211                 *resp = 0;
212         } else {
213                 rst->error = errno;
214                 *resp = -1;
215         }
216 }
217
218 void
219 RuneSysCall_fchown(struct stat_fd_args *args, int *resp)
220 {
221         FStatStor *rst = args->lvs.s_Addr;
222
223         if (fchown(args->fd, rst->uid, rst->gid) == 0) {
224                 rst->error = 0;
225                 *resp = 0;
226         } else {
227                 rst->error = errno;
228                 *resp = -1;
229         }
230 }
231
232 void
233 RuneSysCall_utimes(struct stat_path_args *args, int *resp)
234 {
235         FStatStor *rst = args->lvs.s_Addr;
236         const char *path = args->path.s_Addr;
237         struct timeval times[2];
238
239         STRBOUNDSCHECK(&args->path, PATH_MAX);
240         times[0].tv_sec = rst->atime;
241         times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0);
242         times[1].tv_sec = rst->mtime;
243         times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0);
244
245         if (utimes(path, times) == 0) {
246                 rst->error = 0;
247                 *resp = 0;
248         } else {
249                 rst->error = errno;
250                 *resp = -1;
251         }
252 }
253
254 void
255 RuneSysCall_lutimes(struct stat_path_args *args, int *resp)
256 {
257         FStatStor *rst = args->lvs.s_Addr;
258         const char *path = args->path.s_Addr;
259         struct timeval times[2];
260
261         STRBOUNDSCHECK(&args->path, PATH_MAX);
262         times[0].tv_sec = rst->atime;
263         times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0);
264         times[1].tv_sec = rst->mtime;
265         times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0);
266
267         if (lutimes(path, times) == 0) {
268                 rst->error = 0;
269                 *resp = 0;
270         } else {
271                 rst->error = errno;
272                 *resp = -1;
273         }
274 }
275
276 void
277 RuneSysCall_futimes(struct stat_fd_args *args, int *resp)
278 {
279         FStatStor *rst = args->lvs.s_Addr;
280         struct timeval times[2];
281
282         times[0].tv_sec = rst->atime;
283         times[0].tv_usec = (rst->atime == (runetime_t)-1 ? -1 : 0);
284         times[1].tv_sec = rst->mtime;
285         times[1].tv_usec = (rst->mtime == (runetime_t)-1 ? -1 : 0);
286
287         if (futimes(args->fd, times) == 0) {
288                 rst->error = 0;
289                 *resp = 0;
290         } else {
291                 rst->error = errno;
292                 *resp = -1;
293         }
294 }