xref: /qemu/bsd-user/freebsd/os-stat.h (revision 9bfba08a)
1bf14f13dSStacey Son /*
2bf14f13dSStacey Son  *  stat related system call shims and definitions
3bf14f13dSStacey Son  *
4bf14f13dSStacey Son  *  Copyright (c) 2013 Stacey D. Son
5bf14f13dSStacey Son  *
6bf14f13dSStacey Son  *  This program is free software; you can redistribute it and/or modify
7bf14f13dSStacey Son  *  it under the terms of the GNU General Public License as published by
8bf14f13dSStacey Son  *  the Free Software Foundation; either version 2 of the License, or
9bf14f13dSStacey Son  *  (at your option) any later version.
10bf14f13dSStacey Son  *
11bf14f13dSStacey Son  *  This program is distributed in the hope that it will be useful,
12bf14f13dSStacey Son  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13bf14f13dSStacey Son  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14bf14f13dSStacey Son  *  GNU General Public License for more details.
15bf14f13dSStacey Son  *
16bf14f13dSStacey Son  *  You should have received a copy of the GNU General Public License
17bf14f13dSStacey Son  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18bf14f13dSStacey Son  */
19bf14f13dSStacey Son 
20bf14f13dSStacey Son #ifndef BSD_USER_FREEBSD_OS_STAT_H
21bf14f13dSStacey Son #define BSD_USER_FREEBSD_OS_STAT_H
22bf14f13dSStacey Son 
23b4432977SMichal Meloun int freebsd11_stat(const char *path, struct freebsd11_stat *stat);
24b4432977SMichal Meloun __sym_compat(stat, freebsd11_stat, FBSD_1.0);
25b4432977SMichal Meloun int freebsd11_lstat(const char *path, struct freebsd11_stat *stat);
26b4432977SMichal Meloun __sym_compat(lstat, freebsd11_lstat, FBSD_1.0);
2733d73068SMichal Meloun int freebsd11_fstat(int fd, struct freebsd11_stat *stat);
2833d73068SMichal Meloun __sym_compat(fstat, freebsd11_fstat, FBSD_1.0);
2933d73068SMichal Meloun int freebsd11_fstatat(int fd, const char *path, struct freebsd11_stat *stat,
3033d73068SMichal Meloun         int flag);
3133d73068SMichal Meloun __sym_compat(fstatat, freebsd11_fstatat, FBSD_1.1);
3233d73068SMichal Meloun 
3333d73068SMichal Meloun int freebsd11_fhstat(const fhandle_t *fhandle, struct freebsd11_stat *stat);
3433d73068SMichal Meloun __sym_compat(fhstat, freebsd11_fhstat, FBSD_1.0);
35196da9d3SMichal Meloun int freebsd11_getfsstat(struct freebsd11_statfs *buf, long bufsize, int mode);
36196da9d3SMichal Meloun __sym_compat(getfsstat, freebsd11_getfsstat, FBSD_1.0);
3733d73068SMichal Meloun int freebsd11_fhstatfs(const fhandle_t *fhandle, struct freebsd11_statfs * buf);
3833d73068SMichal Meloun __sym_compat(fhstatfs, freebsd11_fhstatfs, FBSD_1.0);
3933d73068SMichal Meloun int freebsd11_statfs(const char *path, struct freebsd11_statfs *buf);
40196da9d3SMichal Meloun __sym_compat(statfs, freebsd11_statfs, FBSD_1.0);
41196da9d3SMichal Meloun int freebsd11_fstatfs(int fd, struct freebsd11_statfs *buf);
42196da9d3SMichal Meloun __sym_compat(fstatfs, freebsd11_fstatfs, FBSD_1.0);
43196da9d3SMichal Meloun 
4491a98c9bSMichal Meloun ssize_t freebsd11_getdirentries(int fd, char *buf, size_t nbytes, off_t *basep);
4591a98c9bSMichal Meloun __sym_compat(getdirentries, freebsd11_getdirentries, FBSD_1.0);
4691a98c9bSMichal Meloun ssize_t freebsd11_getdents(int fd, char *buf, size_t nbytes);
4791a98c9bSMichal Meloun __sym_compat(getdents, freebsd11_getdents, FBSD_1.0);
4891a98c9bSMichal Meloun 
49292f00c0SMichal Meloun /* undocumented nstat system calls */
50292f00c0SMichal Meloun int freebsd11_nstat(const char *path, struct freebsd11_stat *sb);
51292f00c0SMichal Meloun __sym_compat(nstat, freebsd11_nstat, FBSD_1.0);
52292f00c0SMichal Meloun int freebsd11_nlstat(const char *path, struct freebsd11_stat *sb);
53292f00c0SMichal Meloun __sym_compat(nlstat, freebsd11_nlstat, FBSD_1.0);
54292f00c0SMichal Meloun int freebsd11_nfstat(int fd, struct freebsd11_stat *sb);
55292f00c0SMichal Meloun __sym_compat(nfstat, freebsd11_nfstat, FBSD_1.0);
56b4432977SMichal Meloun 
57bf14f13dSStacey Son /* stat(2) */
do_freebsd11_stat(abi_long arg1,abi_long arg2)58bf14f13dSStacey Son static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2)
59bf14f13dSStacey Son {
60bf14f13dSStacey Son     abi_long ret;
61bf14f13dSStacey Son     void *p;
62bf14f13dSStacey Son     struct freebsd11_stat st;
63bf14f13dSStacey Son 
64bf14f13dSStacey Son     LOCK_PATH(p, arg1);
65bf14f13dSStacey Son     ret = get_errno(freebsd11_stat(path(p), &st));
66bf14f13dSStacey Son     UNLOCK_PATH(p, arg1);
67bf14f13dSStacey Son     if (!is_error(ret)) {
68bf14f13dSStacey Son         ret = h2t_freebsd11_stat(arg2, &st);
69bf14f13dSStacey Son     }
70bf14f13dSStacey Son     return ret;
71bf14f13dSStacey Son }
72bf14f13dSStacey Son 
73bf14f13dSStacey Son /* lstat(2) */
do_freebsd11_lstat(abi_long arg1,abi_long arg2)74bf14f13dSStacey Son static inline abi_long do_freebsd11_lstat(abi_long arg1, abi_long arg2)
75bf14f13dSStacey Son {
76bf14f13dSStacey Son     abi_long ret;
77bf14f13dSStacey Son     void *p;
78bf14f13dSStacey Son     struct freebsd11_stat st;
79bf14f13dSStacey Son 
80bf14f13dSStacey Son     LOCK_PATH(p, arg1);
81bf14f13dSStacey Son     ret = get_errno(freebsd11_lstat(path(p), &st));
82bf14f13dSStacey Son     UNLOCK_PATH(p, arg1);
83bf14f13dSStacey Son     if (!is_error(ret)) {
84bf14f13dSStacey Son         ret = h2t_freebsd11_stat(arg2, &st);
85bf14f13dSStacey Son     }
86bf14f13dSStacey Son     return ret;
87bf14f13dSStacey Son }
88bf14f13dSStacey Son 
89bf14f13dSStacey Son /* fstat(2) */
do_freebsd11_fstat(abi_long arg1,abi_long arg2)9033d73068SMichal Meloun static inline abi_long do_freebsd11_fstat(abi_long arg1, abi_long arg2)
9133d73068SMichal Meloun {
9233d73068SMichal Meloun     abi_long ret;
9333d73068SMichal Meloun     struct freebsd11_stat st;
9433d73068SMichal Meloun 
9533d73068SMichal Meloun     ret = get_errno(freebsd11_fstat(arg1, &st));
9633d73068SMichal Meloun     if (!is_error(ret))  {
9733d73068SMichal Meloun         ret = h2t_freebsd11_stat(arg2, &st);
9833d73068SMichal Meloun     }
9933d73068SMichal Meloun     return ret;
10033d73068SMichal Meloun }
10133d73068SMichal Meloun 
10233d73068SMichal Meloun /* fstat(2) */
do_freebsd_fstat(abi_long arg1,abi_long arg2)103bf14f13dSStacey Son static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2)
104bf14f13dSStacey Son {
105bf14f13dSStacey Son     abi_long ret;
106bf14f13dSStacey Son     struct stat st;
107bf14f13dSStacey Son 
108bf14f13dSStacey Son     ret = get_errno(fstat(arg1, &st));
109bf14f13dSStacey Son     if (!is_error(ret))  {
110bf14f13dSStacey Son         ret = h2t_freebsd_stat(arg2, &st);
111bf14f13dSStacey Son     }
112bf14f13dSStacey Son     return ret;
113bf14f13dSStacey Son }
114bf14f13dSStacey Son 
115bf14f13dSStacey Son /* fstatat(2) */
do_freebsd11_fstatat(abi_long arg1,abi_long arg2,abi_long arg3,abi_long arg4)11633d73068SMichal Meloun static inline abi_long do_freebsd11_fstatat(abi_long arg1, abi_long arg2,
11733d73068SMichal Meloun         abi_long arg3, abi_long arg4)
11833d73068SMichal Meloun {
11933d73068SMichal Meloun     abi_long ret;
12033d73068SMichal Meloun     void *p;
12133d73068SMichal Meloun     struct freebsd11_stat st;
12233d73068SMichal Meloun 
12333d73068SMichal Meloun     LOCK_PATH(p, arg2);
12433d73068SMichal Meloun     ret = get_errno(freebsd11_fstatat(arg1, p, &st, arg4));
12533d73068SMichal Meloun     UNLOCK_PATH(p, arg2);
12633d73068SMichal Meloun     if (!is_error(ret) && arg3) {
12733d73068SMichal Meloun         ret = h2t_freebsd11_stat(arg3, &st);
12833d73068SMichal Meloun     }
12933d73068SMichal Meloun     return ret;
13033d73068SMichal Meloun }
13133d73068SMichal Meloun 
13233d73068SMichal Meloun /* fstatat(2) */
do_freebsd_fstatat(abi_long arg1,abi_long arg2,abi_long arg3,abi_long arg4)133bf14f13dSStacey Son static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2,
134bf14f13dSStacey Son         abi_long arg3, abi_long arg4)
135bf14f13dSStacey Son {
136bf14f13dSStacey Son     abi_long ret;
137bf14f13dSStacey Son     void *p;
138bf14f13dSStacey Son     struct stat st;
139bf14f13dSStacey Son 
140bf14f13dSStacey Son     LOCK_PATH(p, arg2);
141bf14f13dSStacey Son     ret = get_errno(fstatat(arg1, p, &st, arg4));
142bf14f13dSStacey Son     UNLOCK_PATH(p, arg2);
143bf14f13dSStacey Son     if (!is_error(ret) && arg3) {
144bf14f13dSStacey Son         ret = h2t_freebsd_stat(arg3, &st);
145bf14f13dSStacey Son     }
146bf14f13dSStacey Son     return ret;
147bf14f13dSStacey Son }
148bf14f13dSStacey Son 
1499bfba08aSMichael Tokarev /* undocumented nstat(char *path, struct nstat *ub) syscall */
do_freebsd11_nstat(abi_long arg1,abi_long arg2)150bf14f13dSStacey Son static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2)
151bf14f13dSStacey Son {
152bf14f13dSStacey Son     abi_long ret;
153bf14f13dSStacey Son     void *p;
154bf14f13dSStacey Son     struct freebsd11_stat st;
155bf14f13dSStacey Son 
156bf14f13dSStacey Son     LOCK_PATH(p, arg1);
157bf14f13dSStacey Son     ret = get_errno(freebsd11_nstat(path(p), &st));
158bf14f13dSStacey Son     UNLOCK_PATH(p, arg1);
159bf14f13dSStacey Son     if (!is_error(ret)) {
160bf14f13dSStacey Son         ret = h2t_freebsd11_nstat(arg2, &st);
161bf14f13dSStacey Son     }
162bf14f13dSStacey Son     return ret;
163bf14f13dSStacey Son }
164bf14f13dSStacey Son 
1659bfba08aSMichael Tokarev /* undocumented nfstat(int fd, struct nstat *sb) syscall */
do_freebsd11_nfstat(abi_long arg1,abi_long arg2)166bf14f13dSStacey Son static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2)
167bf14f13dSStacey Son {
168bf14f13dSStacey Son     abi_long ret;
169bf14f13dSStacey Son     struct freebsd11_stat st;
170bf14f13dSStacey Son 
171bf14f13dSStacey Son     ret = get_errno(freebsd11_nfstat(arg1, &st));
172bf14f13dSStacey Son     if (!is_error(ret))  {
173bf14f13dSStacey Son         ret = h2t_freebsd11_nstat(arg2, &st);
174bf14f13dSStacey Son     }
175bf14f13dSStacey Son     return ret;
176bf14f13dSStacey Son }
177bf14f13dSStacey Son 
1789bfba08aSMichael Tokarev /* undocumented nlstat(char *path, struct nstat *ub) syscall */
do_freebsd11_nlstat(abi_long arg1,abi_long arg2)179bf14f13dSStacey Son static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2)
180bf14f13dSStacey Son {
181bf14f13dSStacey Son     abi_long ret;
182bf14f13dSStacey Son     void *p;
183bf14f13dSStacey Son     struct freebsd11_stat st;
184bf14f13dSStacey Son 
185bf14f13dSStacey Son     LOCK_PATH(p, arg1);
186bf14f13dSStacey Son     ret = get_errno(freebsd11_nlstat(path(p), &st));
187bf14f13dSStacey Son     UNLOCK_PATH(p, arg1);
188bf14f13dSStacey Son     if (!is_error(ret)) {
189bf14f13dSStacey Son         ret = h2t_freebsd11_nstat(arg2, &st);
190bf14f13dSStacey Son     }
191bf14f13dSStacey Son     return ret;
192bf14f13dSStacey Son }
193bf14f13dSStacey Son 
194db8ee08fSStacey Son /* getfh(2) */
do_freebsd_getfh(abi_long arg1,abi_long arg2)195db8ee08fSStacey Son static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2)
196db8ee08fSStacey Son {
197db8ee08fSStacey Son     abi_long ret;
198db8ee08fSStacey Son     void *p;
199db8ee08fSStacey Son     fhandle_t host_fh;
200db8ee08fSStacey Son 
201db8ee08fSStacey Son     LOCK_PATH(p, arg1);
202db8ee08fSStacey Son     ret = get_errno(getfh(path(p), &host_fh));
203db8ee08fSStacey Son     UNLOCK_PATH(p, arg1);
204db8ee08fSStacey Son     if (is_error(ret)) {
205db8ee08fSStacey Son         return ret;
206db8ee08fSStacey Son     }
207db8ee08fSStacey Son     return h2t_freebsd_fhandle(arg2, &host_fh);
208db8ee08fSStacey Son }
209db8ee08fSStacey Son 
210db8ee08fSStacey Son /* lgetfh(2) */
do_freebsd_lgetfh(abi_long arg1,abi_long arg2)211db8ee08fSStacey Son static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2)
212db8ee08fSStacey Son {
213db8ee08fSStacey Son     abi_long ret;
214db8ee08fSStacey Son     void *p;
215db8ee08fSStacey Son     fhandle_t host_fh;
216db8ee08fSStacey Son 
217db8ee08fSStacey Son     LOCK_PATH(p, arg1);
218db8ee08fSStacey Son     ret = get_errno(lgetfh(path(p), &host_fh));
219db8ee08fSStacey Son     UNLOCK_PATH(p, arg1);
220db8ee08fSStacey Son     if (is_error(ret)) {
221db8ee08fSStacey Son         return ret;
222db8ee08fSStacey Son     }
223db8ee08fSStacey Son     return h2t_freebsd_fhandle(arg2, &host_fh);
224db8ee08fSStacey Son }
225db8ee08fSStacey Son 
226db8ee08fSStacey Son /* fhopen(2) */
do_freebsd_fhopen(abi_long arg1,abi_long arg2)227db8ee08fSStacey Son static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2)
228db8ee08fSStacey Son {
229db8ee08fSStacey Son     abi_long ret;
230db8ee08fSStacey Son     fhandle_t host_fh;
231db8ee08fSStacey Son 
232db8ee08fSStacey Son     ret = t2h_freebsd_fhandle(&host_fh, arg1);
233db8ee08fSStacey Son     if (is_error(ret)) {
234db8ee08fSStacey Son         return ret;
235db8ee08fSStacey Son     }
236db8ee08fSStacey Son 
237db8ee08fSStacey Son     return get_errno(fhopen(&host_fh, arg2));
238db8ee08fSStacey Son }
239db8ee08fSStacey Son 
240db8ee08fSStacey Son /* fhstat(2) */
do_freebsd11_fhstat(abi_long arg1,abi_long arg2)24133d73068SMichal Meloun static inline abi_long do_freebsd11_fhstat(abi_long arg1, abi_long arg2)
24233d73068SMichal Meloun {
24333d73068SMichal Meloun     abi_long ret;
24433d73068SMichal Meloun     fhandle_t host_fh;
24533d73068SMichal Meloun     struct freebsd11_stat host_sb;
24633d73068SMichal Meloun 
24733d73068SMichal Meloun     ret = t2h_freebsd_fhandle(&host_fh, arg1);
24833d73068SMichal Meloun     if (is_error(ret)) {
24933d73068SMichal Meloun         return ret;
25033d73068SMichal Meloun     }
25133d73068SMichal Meloun     ret = get_errno(freebsd11_fhstat(&host_fh, &host_sb));
25233d73068SMichal Meloun     if (is_error(ret)) {
25333d73068SMichal Meloun         return ret;
25433d73068SMichal Meloun     }
25533d73068SMichal Meloun     return h2t_freebsd11_stat(arg2, &host_sb);
25633d73068SMichal Meloun }
25733d73068SMichal Meloun 
25833d73068SMichal Meloun /* fhstat(2) */
do_freebsd_fhstat(abi_long arg1,abi_long arg2)259db8ee08fSStacey Son static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2)
260db8ee08fSStacey Son {
261db8ee08fSStacey Son     abi_long ret;
262db8ee08fSStacey Son     fhandle_t host_fh;
263db8ee08fSStacey Son     struct stat host_sb;
264db8ee08fSStacey Son 
265db8ee08fSStacey Son     ret = t2h_freebsd_fhandle(&host_fh, arg1);
266db8ee08fSStacey Son     if (is_error(ret)) {
267db8ee08fSStacey Son         return ret;
268db8ee08fSStacey Son     }
269db8ee08fSStacey Son     ret = get_errno(fhstat(&host_fh, &host_sb));
270db8ee08fSStacey Son     if (is_error(ret)) {
271db8ee08fSStacey Son         return ret;
272db8ee08fSStacey Son     }
273db8ee08fSStacey Son     return h2t_freebsd_stat(arg2, &host_sb);
274db8ee08fSStacey Son }
275db8ee08fSStacey Son 
276db8ee08fSStacey Son /* fhstatfs(2) */
do_freebsd11_fhstatfs(abi_ulong target_fhp_addr,abi_ulong target_stfs_addr)27733d73068SMichal Meloun static inline abi_long do_freebsd11_fhstatfs(abi_ulong target_fhp_addr,
27833d73068SMichal Meloun         abi_ulong target_stfs_addr)
27933d73068SMichal Meloun {
28033d73068SMichal Meloun     abi_long ret;
28133d73068SMichal Meloun     fhandle_t host_fh;
28233d73068SMichal Meloun     struct freebsd11_statfs host_stfs;
28333d73068SMichal Meloun 
28433d73068SMichal Meloun     ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr);
28533d73068SMichal Meloun     if (is_error(ret)) {
28633d73068SMichal Meloun         return ret;
28733d73068SMichal Meloun     }
28833d73068SMichal Meloun     ret = get_errno(freebsd11_fhstatfs(&host_fh, &host_stfs));
28933d73068SMichal Meloun     if (is_error(ret)) {
29033d73068SMichal Meloun         return ret;
29133d73068SMichal Meloun     }
29233d73068SMichal Meloun     return h2t_freebsd11_statfs(target_stfs_addr, &host_stfs);
29333d73068SMichal Meloun }
29433d73068SMichal Meloun 
29533d73068SMichal Meloun /* fhstatfs(2) */
do_freebsd_fhstatfs(abi_ulong target_fhp_addr,abi_ulong target_stfs_addr)296db8ee08fSStacey Son static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr,
297db8ee08fSStacey Son         abi_ulong target_stfs_addr)
298db8ee08fSStacey Son {
299db8ee08fSStacey Son     abi_long ret;
300db8ee08fSStacey Son     fhandle_t host_fh;
301db8ee08fSStacey Son     struct statfs host_stfs;
302db8ee08fSStacey Son 
303db8ee08fSStacey Son     ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr);
304db8ee08fSStacey Son     if (is_error(ret)) {
305db8ee08fSStacey Son         return ret;
306db8ee08fSStacey Son     }
307db8ee08fSStacey Son     ret = get_errno(fhstatfs(&host_fh, &host_stfs));
308db8ee08fSStacey Son     if (is_error(ret)) {
309db8ee08fSStacey Son         return ret;
310db8ee08fSStacey Son     }
311db8ee08fSStacey Son     return h2t_freebsd_statfs(target_stfs_addr, &host_stfs);
312db8ee08fSStacey Son }
313db8ee08fSStacey Son 
314191fe50dSStacey Son /* statfs(2) */
do_freebsd11_statfs(abi_long arg1,abi_long arg2)315196da9d3SMichal Meloun static inline abi_long do_freebsd11_statfs(abi_long arg1, abi_long arg2)
316196da9d3SMichal Meloun {
317196da9d3SMichal Meloun     abi_long ret;
318196da9d3SMichal Meloun     void *p;
319196da9d3SMichal Meloun     struct freebsd11_statfs host_stfs;
320196da9d3SMichal Meloun 
321196da9d3SMichal Meloun     LOCK_PATH(p, arg1);
322196da9d3SMichal Meloun     ret = get_errno(freebsd11_statfs(path(p), &host_stfs));
323196da9d3SMichal Meloun     UNLOCK_PATH(p, arg1);
324196da9d3SMichal Meloun     if (is_error(ret)) {
325196da9d3SMichal Meloun         return ret;
326196da9d3SMichal Meloun     }
327196da9d3SMichal Meloun 
328196da9d3SMichal Meloun     return h2t_freebsd11_statfs(arg2, &host_stfs);
329196da9d3SMichal Meloun }
330196da9d3SMichal Meloun 
331196da9d3SMichal Meloun /* statfs(2) */
do_freebsd_statfs(abi_long arg1,abi_long arg2)332191fe50dSStacey Son static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2)
333191fe50dSStacey Son {
334191fe50dSStacey Son     abi_long ret;
335191fe50dSStacey Son     void *p;
336191fe50dSStacey Son     struct statfs host_stfs;
337191fe50dSStacey Son 
338191fe50dSStacey Son     LOCK_PATH(p, arg1);
339191fe50dSStacey Son     ret = get_errno(statfs(path(p), &host_stfs));
340191fe50dSStacey Son     UNLOCK_PATH(p, arg1);
341191fe50dSStacey Son     if (is_error(ret)) {
342191fe50dSStacey Son         return ret;
343191fe50dSStacey Son     }
344191fe50dSStacey Son 
345191fe50dSStacey Son     return h2t_freebsd_statfs(arg2, &host_stfs);
346191fe50dSStacey Son }
347191fe50dSStacey Son 
348191fe50dSStacey Son /* fstatfs(2) */
do_freebsd11_fstatfs(abi_long fd,abi_ulong target_addr)349196da9d3SMichal Meloun static inline abi_long do_freebsd11_fstatfs(abi_long fd, abi_ulong target_addr)
350196da9d3SMichal Meloun {
351196da9d3SMichal Meloun     abi_long ret;
352196da9d3SMichal Meloun     struct freebsd11_statfs host_stfs;
353196da9d3SMichal Meloun 
354196da9d3SMichal Meloun     ret = get_errno(freebsd11_fstatfs(fd, &host_stfs));
355196da9d3SMichal Meloun     if (is_error(ret)) {
356196da9d3SMichal Meloun         return ret;
357196da9d3SMichal Meloun     }
358196da9d3SMichal Meloun 
359196da9d3SMichal Meloun     return h2t_freebsd11_statfs(target_addr, &host_stfs);
360196da9d3SMichal Meloun }
361196da9d3SMichal Meloun 
362196da9d3SMichal Meloun /* fstatfs(2) */
do_freebsd_fstatfs(abi_long fd,abi_ulong target_addr)363191fe50dSStacey Son static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr)
364191fe50dSStacey Son {
365191fe50dSStacey Son     abi_long ret;
366191fe50dSStacey Son     struct statfs host_stfs;
367191fe50dSStacey Son 
368191fe50dSStacey Son     ret = get_errno(fstatfs(fd, &host_stfs));
369191fe50dSStacey Son     if (is_error(ret)) {
370191fe50dSStacey Son         return ret;
371191fe50dSStacey Son     }
372191fe50dSStacey Son 
373191fe50dSStacey Son     return h2t_freebsd_statfs(target_addr, &host_stfs);
374191fe50dSStacey Son }
375191fe50dSStacey Son 
376191fe50dSStacey Son /* getfsstat(2) */
do_freebsd11_getfsstat(abi_ulong target_addr,abi_long bufsize,abi_long flags)377196da9d3SMichal Meloun static inline abi_long do_freebsd11_getfsstat(abi_ulong target_addr,
378196da9d3SMichal Meloun         abi_long bufsize, abi_long flags)
379196da9d3SMichal Meloun {
380196da9d3SMichal Meloun     abi_long ret;
381196da9d3SMichal Meloun     struct freebsd11_statfs *host_stfs;
382196da9d3SMichal Meloun     int count;
383196da9d3SMichal Meloun     long host_bufsize;
384196da9d3SMichal Meloun 
385196da9d3SMichal Meloun     count = bufsize / sizeof(struct target_freebsd11_statfs);
386196da9d3SMichal Meloun 
387196da9d3SMichal Meloun     /* if user buffer is NULL then return number of mounted FS's */
388196da9d3SMichal Meloun     if (target_addr == 0 || count == 0) {
389196da9d3SMichal Meloun         return get_errno(freebsd11_getfsstat(NULL, 0, flags));
390196da9d3SMichal Meloun     }
391196da9d3SMichal Meloun 
392196da9d3SMichal Meloun     /* XXX check count to be reasonable */
393196da9d3SMichal Meloun     host_bufsize = sizeof(struct freebsd11_statfs) * count;
394196da9d3SMichal Meloun     host_stfs = alloca(host_bufsize);
395196da9d3SMichal Meloun     if (!host_stfs) {
396196da9d3SMichal Meloun         return -TARGET_EINVAL;
397196da9d3SMichal Meloun     }
398196da9d3SMichal Meloun 
399196da9d3SMichal Meloun     ret = count = get_errno(freebsd11_getfsstat(host_stfs, host_bufsize, flags));
400196da9d3SMichal Meloun     if (is_error(ret)) {
401196da9d3SMichal Meloun         return ret;
402196da9d3SMichal Meloun     }
403196da9d3SMichal Meloun 
404196da9d3SMichal Meloun     while (count--) {
405196da9d3SMichal Meloun         if (h2t_freebsd11_statfs((target_addr +
406196da9d3SMichal Meloun                         (count * sizeof(struct target_freebsd11_statfs))),
407196da9d3SMichal Meloun                     &host_stfs[count])) {
408196da9d3SMichal Meloun             return -TARGET_EFAULT;
409196da9d3SMichal Meloun         }
410196da9d3SMichal Meloun     }
411196da9d3SMichal Meloun     return ret;
412196da9d3SMichal Meloun }
413196da9d3SMichal Meloun 
414196da9d3SMichal Meloun /* getfsstat(2) */
do_freebsd_getfsstat(abi_ulong target_addr,abi_long bufsize,abi_long flags)415191fe50dSStacey Son static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr,
416191fe50dSStacey Son         abi_long bufsize, abi_long flags)
417191fe50dSStacey Son {
418191fe50dSStacey Son     abi_long ret;
419191fe50dSStacey Son     struct statfs *host_stfs;
420191fe50dSStacey Son     int count;
421191fe50dSStacey Son     long host_bufsize;
422191fe50dSStacey Son 
423191fe50dSStacey Son     count = bufsize / sizeof(struct target_statfs);
424191fe50dSStacey Son 
425191fe50dSStacey Son     /* if user buffer is NULL then return number of mounted FS's */
426191fe50dSStacey Son     if (target_addr == 0 || count == 0) {
427191fe50dSStacey Son         return get_errno(freebsd11_getfsstat(NULL, 0, flags));
428191fe50dSStacey Son     }
429191fe50dSStacey Son 
430191fe50dSStacey Son     /* XXX check count to be reasonable */
431191fe50dSStacey Son     host_bufsize = sizeof(struct statfs) * count;
432191fe50dSStacey Son     host_stfs = alloca(host_bufsize);
433191fe50dSStacey Son     if (!host_stfs) {
434191fe50dSStacey Son         return -TARGET_EINVAL;
435191fe50dSStacey Son     }
436191fe50dSStacey Son 
437191fe50dSStacey Son     ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags));
438191fe50dSStacey Son     if (is_error(ret)) {
439191fe50dSStacey Son         return ret;
440191fe50dSStacey Son     }
441191fe50dSStacey Son 
442191fe50dSStacey Son     while (count--) {
443191fe50dSStacey Son         if (h2t_freebsd_statfs((target_addr +
444191fe50dSStacey Son                         (count * sizeof(struct target_statfs))),
445191fe50dSStacey Son                     &host_stfs[count])) {
446191fe50dSStacey Son             return -TARGET_EFAULT;
447191fe50dSStacey Son         }
448191fe50dSStacey Son     }
449191fe50dSStacey Son     return ret;
450191fe50dSStacey Son }
451191fe50dSStacey Son 
45221344452SStacey Son /* getdents(2) */
do_freebsd11_getdents(abi_long arg1,abi_ulong arg2,abi_long nbytes)45321344452SStacey Son static inline abi_long do_freebsd11_getdents(abi_long arg1,
45421344452SStacey Son         abi_ulong arg2, abi_long nbytes)
45521344452SStacey Son {
45621344452SStacey Son     abi_long ret;
45721344452SStacey Son     struct freebsd11_dirent *dirp;
45821344452SStacey Son 
45921344452SStacey Son     dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
46021344452SStacey Son     if (dirp == NULL) {
46121344452SStacey Son         return -TARGET_EFAULT;
46221344452SStacey Son     }
46321344452SStacey Son     ret = get_errno(freebsd11_getdents(arg1, (char *)dirp, nbytes));
46421344452SStacey Son     if (!is_error(ret)) {
46521344452SStacey Son         struct freebsd11_dirent *de;
46621344452SStacey Son         int len = ret;
46721344452SStacey Son         int reclen;
46821344452SStacey Son 
46921344452SStacey Son         de = dirp;
47021344452SStacey Son         while (len > 0) {
47121344452SStacey Son             reclen = de->d_reclen;
47221344452SStacey Son             if (reclen > len) {
47321344452SStacey Son                 return -TARGET_EFAULT;
47421344452SStacey Son             }
47521344452SStacey Son             de->d_reclen = tswap16(reclen);
47621344452SStacey Son             de->d_fileno = tswap32(de->d_fileno);
47721344452SStacey Son             len -= reclen;
47821344452SStacey Son         }
47921344452SStacey Son     }
48021344452SStacey Son     return ret;
48121344452SStacey Son }
48221344452SStacey Son 
48321344452SStacey Son /* getdirecentries(2) */
do_freebsd11_getdirentries(abi_long arg1,abi_ulong arg2,abi_long nbytes,abi_ulong arg4)48491a98c9bSMichal Meloun static inline abi_long do_freebsd11_getdirentries(abi_long arg1,
48591a98c9bSMichal Meloun         abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
48691a98c9bSMichal Meloun {
48791a98c9bSMichal Meloun     abi_long ret;
48891a98c9bSMichal Meloun     struct freebsd11_dirent *dirp;
48991a98c9bSMichal Meloun     long basep;
49091a98c9bSMichal Meloun 
49191a98c9bSMichal Meloun     dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
49291a98c9bSMichal Meloun     if (dirp == NULL) {
49391a98c9bSMichal Meloun         return -TARGET_EFAULT;
49491a98c9bSMichal Meloun     }
49591a98c9bSMichal Meloun     ret = get_errno(freebsd11_getdirentries(arg1, (char *)dirp, nbytes, &basep));
49691a98c9bSMichal Meloun     if (!is_error(ret)) {
49791a98c9bSMichal Meloun         struct freebsd11_dirent *de;
49891a98c9bSMichal Meloun         int len = ret;
49991a98c9bSMichal Meloun         int reclen;
50091a98c9bSMichal Meloun 
50191a98c9bSMichal Meloun         de = dirp;
50291a98c9bSMichal Meloun         while (len > 0) {
50391a98c9bSMichal Meloun             reclen = de->d_reclen;
50491a98c9bSMichal Meloun             if (reclen > len) {
50591a98c9bSMichal Meloun                 return -TARGET_EFAULT;
50691a98c9bSMichal Meloun             }
50791a98c9bSMichal Meloun             de->d_reclen = tswap16(reclen);
50891a98c9bSMichal Meloun             de->d_fileno = tswap32(de->d_fileno);
50991a98c9bSMichal Meloun             len -= reclen;
51091a98c9bSMichal Meloun             de = (struct freebsd11_dirent *)((void *)de + reclen);
51191a98c9bSMichal Meloun         }
51291a98c9bSMichal Meloun     }
51391a98c9bSMichal Meloun     unlock_user(dirp, arg2, ret);
51491a98c9bSMichal Meloun     if (arg4) {
51591a98c9bSMichal Meloun         if (put_user(basep, arg4, abi_ulong)) {
51691a98c9bSMichal Meloun             return -TARGET_EFAULT;
51791a98c9bSMichal Meloun         }
51891a98c9bSMichal Meloun     }
51991a98c9bSMichal Meloun     return ret;
52091a98c9bSMichal Meloun }
52191a98c9bSMichal Meloun 
52291a98c9bSMichal Meloun /* getdirecentries(2) */
do_freebsd_getdirentries(abi_long arg1,abi_ulong arg2,abi_long nbytes,abi_ulong arg4)52321344452SStacey Son static inline abi_long do_freebsd_getdirentries(abi_long arg1,
52421344452SStacey Son         abi_ulong arg2, abi_long nbytes, abi_ulong arg4)
52521344452SStacey Son {
52621344452SStacey Son     abi_long ret;
52721344452SStacey Son     struct dirent *dirp;
52821344452SStacey Son     long basep;
52921344452SStacey Son 
53021344452SStacey Son     dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0);
53121344452SStacey Son     if (dirp == NULL) {
53221344452SStacey Son         return -TARGET_EFAULT;
53321344452SStacey Son     }
53421344452SStacey Son     ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, &basep));
53521344452SStacey Son     if (!is_error(ret)) {
53621344452SStacey Son         struct dirent *de;
53721344452SStacey Son         int len = ret;
53821344452SStacey Son         int reclen;
53921344452SStacey Son 
54021344452SStacey Son         de = dirp;
54121344452SStacey Son         while (len > 0) {
54221344452SStacey Son             reclen = de->d_reclen;
54321344452SStacey Son             if (reclen > len) {
54421344452SStacey Son                 return -TARGET_EFAULT;
54521344452SStacey Son             }
54621344452SStacey Son             de->d_fileno = tswap64(de->d_fileno);
54721344452SStacey Son             de->d_off = tswap64(de->d_off);
54821344452SStacey Son             de->d_reclen = tswap16(de->d_reclen);
54921344452SStacey Son             de->d_namlen = tswap16(de->d_namlen);
55021344452SStacey Son             len -= reclen;
55121344452SStacey Son             de = (struct dirent *)((void *)de + reclen);
55221344452SStacey Son         }
55321344452SStacey Son     }
55421344452SStacey Son     unlock_user(dirp, arg2, ret);
55521344452SStacey Son     if (arg4) {
55621344452SStacey Son         if (put_user(basep, arg4, abi_ulong)) {
55721344452SStacey Son             return -TARGET_EFAULT;
55821344452SStacey Son         }
55921344452SStacey Son     }
56021344452SStacey Son     return ret;
56121344452SStacey Son }
56221344452SStacey Son 
563c0023204SStacey Son /* fcntl(2) */
do_freebsd_fcntl(abi_long arg1,abi_long arg2,abi_ulong arg3)564c0023204SStacey Son static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2,
565c0023204SStacey Son         abi_ulong arg3)
566c0023204SStacey Son {
567c0023204SStacey Son     abi_long ret;
568c0023204SStacey Son     int host_cmd;
569c0023204SStacey Son     struct flock fl;
570c0023204SStacey Son     struct target_freebsd_flock *target_fl;
571c0023204SStacey Son 
572c0023204SStacey Son     host_cmd = target_to_host_fcntl_cmd(arg2);
573c0023204SStacey Son     if (host_cmd < 0) {
574c0023204SStacey Son         return host_cmd;
575c0023204SStacey Son     }
576c0023204SStacey Son     switch (arg2) {
577c0023204SStacey Son     case TARGET_F_GETLK:
578c0023204SStacey Son         if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
579c0023204SStacey Son             return -TARGET_EFAULT;
580c0023204SStacey Son         }
581c0023204SStacey Son         __get_user(fl.l_type, &target_fl->l_type);
582c0023204SStacey Son         __get_user(fl.l_whence, &target_fl->l_whence);
583c0023204SStacey Son         __get_user(fl.l_start, &target_fl->l_start);
584c0023204SStacey Son         __get_user(fl.l_len, &target_fl->l_len);
585c0023204SStacey Son         __get_user(fl.l_pid, &target_fl->l_pid);
586c0023204SStacey Son         __get_user(fl.l_sysid, &target_fl->l_sysid);
587c0023204SStacey Son         unlock_user_struct(target_fl, arg3, 0);
588c0023204SStacey Son         ret = get_errno(safe_fcntl(arg1, host_cmd, &fl));
589c0023204SStacey Son         if (!is_error(ret)) {
590c0023204SStacey Son             if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) {
591c0023204SStacey Son                 return -TARGET_EFAULT;
592c0023204SStacey Son             }
593c0023204SStacey Son             __put_user(fl.l_type, &target_fl->l_type);
594c0023204SStacey Son             __put_user(fl.l_whence, &target_fl->l_whence);
595c0023204SStacey Son             __put_user(fl.l_start, &target_fl->l_start);
596c0023204SStacey Son             __put_user(fl.l_len, &target_fl->l_len);
597c0023204SStacey Son             __put_user(fl.l_pid, &target_fl->l_pid);
598c0023204SStacey Son             __put_user(fl.l_sysid, &target_fl->l_sysid);
599c0023204SStacey Son             unlock_user_struct(target_fl, arg3, 1);
600c0023204SStacey Son         }
601c0023204SStacey Son         break;
602c0023204SStacey Son 
603c0023204SStacey Son     case TARGET_F_SETLK:
604c0023204SStacey Son     case TARGET_F_SETLKW:
605c0023204SStacey Son         if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) {
606c0023204SStacey Son             return -TARGET_EFAULT;
607c0023204SStacey Son         }
608c0023204SStacey Son         __get_user(fl.l_type, &target_fl->l_type);
609c0023204SStacey Son         __get_user(fl.l_whence, &target_fl->l_whence);
610c0023204SStacey Son         __get_user(fl.l_start, &target_fl->l_start);
611c0023204SStacey Son         __get_user(fl.l_len, &target_fl->l_len);
612c0023204SStacey Son         __get_user(fl.l_pid, &target_fl->l_pid);
613c0023204SStacey Son         __get_user(fl.l_sysid, &target_fl->l_sysid);
614c0023204SStacey Son         unlock_user_struct(target_fl, arg3, 0);
615c0023204SStacey Son         ret = get_errno(safe_fcntl(arg1, host_cmd, &fl));
616c0023204SStacey Son         break;
617c0023204SStacey Son 
618c0023204SStacey Son     case TARGET_F_DUPFD:
619c0023204SStacey Son     case TARGET_F_DUP2FD:
620c0023204SStacey Son     case TARGET_F_GETOWN:
621c0023204SStacey Son     case TARGET_F_SETOWN:
622c0023204SStacey Son     case TARGET_F_GETFD:
623c0023204SStacey Son     case TARGET_F_SETFD:
624c0023204SStacey Son     case TARGET_F_GETFL:
625c0023204SStacey Son     case TARGET_F_SETFL:
626c0023204SStacey Son     case TARGET_F_READAHEAD:
627c0023204SStacey Son     case TARGET_F_RDAHEAD:
628c0023204SStacey Son     case TARGET_F_ADD_SEALS:
629c0023204SStacey Son     case TARGET_F_GET_SEALS:
630c0023204SStacey Son     default:
631c0023204SStacey Son         ret = get_errno(safe_fcntl(arg1, host_cmd, arg3));
632c0023204SStacey Son         break;
633c0023204SStacey Son     }
634c0023204SStacey Son     return ret;
635c0023204SStacey Son }
636c0023204SStacey Son 
637292bfd0fSMikaël Urankar #if defined(__FreeBSD_version) && __FreeBSD_version >= 1300080
638292bfd0fSMikaël Urankar extern int __realpathat(int fd, const char *path, char *buf, size_t size,
639292bfd0fSMikaël Urankar         int flags);
640292bfd0fSMikaël Urankar /* https://svnweb.freebsd.org/base?view=revision&revision=358172 */
641292bfd0fSMikaël Urankar /* no man page */
do_freebsd_realpathat(abi_long arg1,abi_long arg2,abi_long arg3,abi_long arg4,abi_long arg5)642292bfd0fSMikaël Urankar static inline abi_long do_freebsd_realpathat(abi_long arg1, abi_long arg2,
643292bfd0fSMikaël Urankar         abi_long arg3, abi_long arg4, abi_long arg5)
644292bfd0fSMikaël Urankar {
645292bfd0fSMikaël Urankar     abi_long ret;
646292bfd0fSMikaël Urankar     void *p, *b;
647292bfd0fSMikaël Urankar 
648292bfd0fSMikaël Urankar     LOCK_PATH(p, arg2);
649292bfd0fSMikaël Urankar     b = lock_user(VERIFY_WRITE, arg3, arg4, 0);
650292bfd0fSMikaël Urankar     if (b == NULL) {
651292bfd0fSMikaël Urankar         UNLOCK_PATH(p, arg2);
652292bfd0fSMikaël Urankar         return -TARGET_EFAULT;
653292bfd0fSMikaël Urankar     }
654292bfd0fSMikaël Urankar 
655292bfd0fSMikaël Urankar     ret = get_errno(__realpathat(arg1, p, b, arg4, arg5));
656292bfd0fSMikaël Urankar     UNLOCK_PATH(p, arg2);
657292bfd0fSMikaël Urankar     unlock_user(b, arg3, ret);
658292bfd0fSMikaël Urankar 
659292bfd0fSMikaël Urankar     return ret;
660292bfd0fSMikaël Urankar }
661292bfd0fSMikaël Urankar #endif
662292bfd0fSMikaël Urankar 
663bf14f13dSStacey Son #endif /* BSD_USER_FREEBSD_OS_STAT_H */
664