]> git.proxmox.com Git - mirror_qemu.git/blob - bsd-user/freebsd/os-stat.h
bsd-user: Implement statfs related syscalls
[mirror_qemu.git] / bsd-user / freebsd / os-stat.h
1 /*
2 * stat related system call shims and definitions
3 *
4 * Copyright (c) 2013 Stacey D. Son
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef BSD_USER_FREEBSD_OS_STAT_H
21 #define BSD_USER_FREEBSD_OS_STAT_H
22
23 /* stat(2) */
24 static inline abi_long do_freebsd11_stat(abi_long arg1, abi_long arg2)
25 {
26 abi_long ret;
27 void *p;
28 struct freebsd11_stat st;
29
30 LOCK_PATH(p, arg1);
31 ret = get_errno(freebsd11_stat(path(p), &st));
32 UNLOCK_PATH(p, arg1);
33 if (!is_error(ret)) {
34 ret = h2t_freebsd11_stat(arg2, &st);
35 }
36 return ret;
37 }
38
39 /* lstat(2) */
40 static inline abi_long do_freebsd11_lstat(abi_long arg1, abi_long arg2)
41 {
42 abi_long ret;
43 void *p;
44 struct freebsd11_stat st;
45
46 LOCK_PATH(p, arg1);
47 ret = get_errno(freebsd11_lstat(path(p), &st));
48 UNLOCK_PATH(p, arg1);
49 if (!is_error(ret)) {
50 ret = h2t_freebsd11_stat(arg2, &st);
51 }
52 return ret;
53 }
54
55 /* fstat(2) */
56 static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2)
57 {
58 abi_long ret;
59 struct stat st;
60
61 ret = get_errno(fstat(arg1, &st));
62 if (!is_error(ret)) {
63 ret = h2t_freebsd_stat(arg2, &st);
64 }
65 return ret;
66 }
67
68 /* fstatat(2) */
69 static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2,
70 abi_long arg3, abi_long arg4)
71 {
72 abi_long ret;
73 void *p;
74 struct stat st;
75
76 LOCK_PATH(p, arg2);
77 ret = get_errno(fstatat(arg1, p, &st, arg4));
78 UNLOCK_PATH(p, arg2);
79 if (!is_error(ret) && arg3) {
80 ret = h2t_freebsd_stat(arg3, &st);
81 }
82 return ret;
83 }
84
85 /* undocummented nstat(char *path, struct nstat *ub) syscall */
86 static abi_long do_freebsd11_nstat(abi_long arg1, abi_long arg2)
87 {
88 abi_long ret;
89 void *p;
90 struct freebsd11_stat st;
91
92 LOCK_PATH(p, arg1);
93 ret = get_errno(freebsd11_nstat(path(p), &st));
94 UNLOCK_PATH(p, arg1);
95 if (!is_error(ret)) {
96 ret = h2t_freebsd11_nstat(arg2, &st);
97 }
98 return ret;
99 }
100
101 /* undocummented nfstat(int fd, struct nstat *sb) syscall */
102 static abi_long do_freebsd11_nfstat(abi_long arg1, abi_long arg2)
103 {
104 abi_long ret;
105 struct freebsd11_stat st;
106
107 ret = get_errno(freebsd11_nfstat(arg1, &st));
108 if (!is_error(ret)) {
109 ret = h2t_freebsd11_nstat(arg2, &st);
110 }
111 return ret;
112 }
113
114 /* undocummented nlstat(char *path, struct nstat *ub) syscall */
115 static abi_long do_freebsd11_nlstat(abi_long arg1, abi_long arg2)
116 {
117 abi_long ret;
118 void *p;
119 struct freebsd11_stat st;
120
121 LOCK_PATH(p, arg1);
122 ret = get_errno(freebsd11_nlstat(path(p), &st));
123 UNLOCK_PATH(p, arg1);
124 if (!is_error(ret)) {
125 ret = h2t_freebsd11_nstat(arg2, &st);
126 }
127 return ret;
128 }
129
130 /* getfh(2) */
131 static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2)
132 {
133 abi_long ret;
134 void *p;
135 fhandle_t host_fh;
136
137 LOCK_PATH(p, arg1);
138 ret = get_errno(getfh(path(p), &host_fh));
139 UNLOCK_PATH(p, arg1);
140 if (is_error(ret)) {
141 return ret;
142 }
143 return h2t_freebsd_fhandle(arg2, &host_fh);
144 }
145
146 /* lgetfh(2) */
147 static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2)
148 {
149 abi_long ret;
150 void *p;
151 fhandle_t host_fh;
152
153 LOCK_PATH(p, arg1);
154 ret = get_errno(lgetfh(path(p), &host_fh));
155 UNLOCK_PATH(p, arg1);
156 if (is_error(ret)) {
157 return ret;
158 }
159 return h2t_freebsd_fhandle(arg2, &host_fh);
160 }
161
162 /* fhopen(2) */
163 static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2)
164 {
165 abi_long ret;
166 fhandle_t host_fh;
167
168 ret = t2h_freebsd_fhandle(&host_fh, arg1);
169 if (is_error(ret)) {
170 return ret;
171 }
172
173 return get_errno(fhopen(&host_fh, arg2));
174 }
175
176 /* fhstat(2) */
177 static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2)
178 {
179 abi_long ret;
180 fhandle_t host_fh;
181 struct stat host_sb;
182
183 ret = t2h_freebsd_fhandle(&host_fh, arg1);
184 if (is_error(ret)) {
185 return ret;
186 }
187 ret = get_errno(fhstat(&host_fh, &host_sb));
188 if (is_error(ret)) {
189 return ret;
190 }
191 return h2t_freebsd_stat(arg2, &host_sb);
192 }
193
194 /* fhstatfs(2) */
195 static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr,
196 abi_ulong target_stfs_addr)
197 {
198 abi_long ret;
199 fhandle_t host_fh;
200 struct statfs host_stfs;
201
202 ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr);
203 if (is_error(ret)) {
204 return ret;
205 }
206 ret = get_errno(fhstatfs(&host_fh, &host_stfs));
207 if (is_error(ret)) {
208 return ret;
209 }
210 return h2t_freebsd_statfs(target_stfs_addr, &host_stfs);
211 }
212
213 /* statfs(2) */
214 static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2)
215 {
216 abi_long ret;
217 void *p;
218 struct statfs host_stfs;
219
220 LOCK_PATH(p, arg1);
221 ret = get_errno(statfs(path(p), &host_stfs));
222 UNLOCK_PATH(p, arg1);
223 if (is_error(ret)) {
224 return ret;
225 }
226
227 return h2t_freebsd_statfs(arg2, &host_stfs);
228 }
229
230 /* fstatfs(2) */
231 static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr)
232 {
233 abi_long ret;
234 struct statfs host_stfs;
235
236 ret = get_errno(fstatfs(fd, &host_stfs));
237 if (is_error(ret)) {
238 return ret;
239 }
240
241 return h2t_freebsd_statfs(target_addr, &host_stfs);
242 }
243
244 /* getfsstat(2) */
245 static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr,
246 abi_long bufsize, abi_long flags)
247 {
248 abi_long ret;
249 struct statfs *host_stfs;
250 int count;
251 long host_bufsize;
252
253 count = bufsize / sizeof(struct target_statfs);
254
255 /* if user buffer is NULL then return number of mounted FS's */
256 if (target_addr == 0 || count == 0) {
257 return get_errno(freebsd11_getfsstat(NULL, 0, flags));
258 }
259
260 /* XXX check count to be reasonable */
261 host_bufsize = sizeof(struct statfs) * count;
262 host_stfs = alloca(host_bufsize);
263 if (!host_stfs) {
264 return -TARGET_EINVAL;
265 }
266
267 ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags));
268 if (is_error(ret)) {
269 return ret;
270 }
271
272 while (count--) {
273 if (h2t_freebsd_statfs((target_addr +
274 (count * sizeof(struct target_statfs))),
275 &host_stfs[count])) {
276 return -TARGET_EFAULT;
277 }
278 }
279 return ret;
280 }
281
282 #endif /* BSD_USER_FREEBSD_OS_STAT_H */