1 /* $NetBSD: aoutm68k_stat.c,v 1.24 2008/04/28 20:23:41 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Steve C. Woodford. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: aoutm68k_stat.c,v 1.24 2008/04/28 20:23:41 martin Exp $"); 34 35 #if defined(_KERNEL_OPT) 36 #include "opt_compat_netbsd.h" 37 #include "opt_compat_43.h" 38 #endif 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/filedesc.h> 43 #include <sys/mount.h> 44 #include <sys/namei.h> 45 #include <sys/proc.h> 46 #include <sys/stat.h> 47 #include <sys/vfs_syscalls.h> 48 49 #include <sys/syscall.h> 50 #include <sys/syscallargs.h> 51 52 #include <compat/sys/stat.h> 53 54 #include <compat/aoutm68k/aoutm68k_util.h> 55 #include <compat/aoutm68k/aoutm68k_stat.h> 56 #include <compat/aoutm68k/aoutm68k_syscall.h> 57 #include <compat/aoutm68k/aoutm68k_syscallargs.h> 58 59 #ifdef COMPAT_43 60 static void aoutm68k_stat43_convert(struct stat *, struct aoutm68k_stat43 *); 61 #endif 62 #ifdef COMPAT_12 63 static void aoutm68k_stat12_convert(struct stat *, struct aoutm68k_stat12 *); 64 #endif 65 static void aoutm68k_stat13_convert(struct stat *, struct aoutm68k_stat *); 66 67 68 #ifdef COMPAT_43 69 int 70 aoutm68k_compat_43_sys_stat(struct lwp *l, const struct aoutm68k_compat_43_sys_stat_args *uap, register_t *retval) 71 { 72 struct aoutm68k_stat43 ast; 73 struct stat sb; 74 int error; 75 76 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 77 if (error) 78 return error; 79 80 aoutm68k_stat43_convert(&sb, &ast); 81 82 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 83 } 84 85 int 86 aoutm68k_compat_43_sys_fstat(struct lwp *l, const struct aoutm68k_compat_43_sys_fstat_args *uap, register_t *retval) 87 { 88 struct aoutm68k_stat43 ast; 89 struct stat sb; 90 int error; 91 92 error = do_sys_fstat(SCARG(uap, fd), &sb); 93 if (error != 0) 94 return error; 95 96 aoutm68k_stat43_convert(&sb, &ast); 97 98 return copyout(&ast, SCARG(uap, sb), sizeof(ast)); 99 } 100 101 int 102 aoutm68k_compat_43_sys_lstat(struct lwp *l, const struct aoutm68k_compat_43_sys_lstat_args *uap, register_t *retval) 103 { 104 struct aoutm68k_stat43 ast; 105 struct stat sb; 106 int error; 107 108 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 109 if (error) 110 return error; 111 112 aoutm68k_stat43_convert(&sb, &ast); 113 114 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 115 } 116 #endif /* COMPAT_43 */ 117 118 #ifdef COMPAT_12 119 int 120 aoutm68k_compat_12_sys_stat(struct lwp *l, const struct aoutm68k_compat_12_sys_stat_args *uap, register_t *retval) 121 { 122 struct aoutm68k_stat12 ast; 123 struct stat sb; 124 int error; 125 126 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 127 if (error) 128 return error; 129 130 aoutm68k_stat12_convert(&sb, &ast); 131 132 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 133 } 134 135 int 136 aoutm68k_compat_12_sys_fstat(struct lwp *l, const struct aoutm68k_compat_12_sys_fstat_args *uap, register_t *retval) 137 { 138 struct aoutm68k_stat12 ast; 139 struct stat sb; 140 int error; 141 142 error = do_sys_fstat(SCARG(uap, fd), &sb); 143 if (error != 0) 144 return error; 145 146 aoutm68k_stat12_convert(&sb, &ast); 147 148 return copyout(&ast, SCARG(uap, sb), sizeof(ast)); 149 } 150 151 int 152 aoutm68k_compat_12_sys_lstat(struct lwp *l, const struct aoutm68k_compat_12_sys_lstat_args *uap, register_t *retval) 153 { 154 struct aoutm68k_stat12 ast; 155 struct stat sb; 156 int error; 157 158 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 159 if (error) 160 return error; 161 162 aoutm68k_stat12_convert(&sb, &ast); 163 164 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 165 } 166 #endif /* COMPAT_12 */ 167 168 int 169 aoutm68k_sys___stat13(struct lwp *l, const struct aoutm68k_sys___stat13_args *uap, register_t *retval) 170 { 171 struct aoutm68k_stat ast; 172 struct stat sb; 173 int error; 174 175 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 176 if (error) 177 return error; 178 179 aoutm68k_stat13_convert(&sb, &ast); 180 181 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 182 } 183 184 int 185 aoutm68k_sys___fstat13(struct lwp *l, const struct aoutm68k_sys___fstat13_args *uap, register_t *retval) 186 { 187 struct aoutm68k_stat ast; 188 struct stat sb; 189 int error; 190 191 error = do_sys_fstat(SCARG(uap, fd), &sb); 192 if (error != 0) 193 return error; 194 195 aoutm68k_stat13_convert(&sb, &ast); 196 197 return copyout(&ast, SCARG(uap, sb), sizeof(ast)); 198 199 } 200 201 int 202 aoutm68k_sys___lstat13(struct lwp *l, const struct aoutm68k_sys___lstat13_args *uap, register_t *retval) 203 { 204 struct aoutm68k_stat ast; 205 struct stat sb; 206 int error; 207 208 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 209 if (error) 210 return error; 211 212 aoutm68k_stat13_convert(&sb, &ast); 213 214 return copyout(&ast, SCARG(uap, ub), sizeof(ast)); 215 } 216 217 int 218 aoutm68k_sys_fhstat(struct lwp *l, const struct aoutm68k_sys_fhstat_args *uap, register_t *retval) 219 { 220 struct aoutm68k_stat ast; 221 struct stat sb; 222 int error; 223 224 error = do_fhstat(l, SCARG(uap, fhp), FHANDLE_SIZE_COMPAT, &sb); 225 if (error) 226 return error; 227 228 aoutm68k_stat13_convert(&sb, &ast); 229 return copyout(&sb, SCARG(uap, sb), sizeof(sb)); 230 } 231 232 #ifdef COMPAT_43 233 static void 234 aoutm68k_stat43_convert(struct stat *st, struct aoutm68k_stat43 *ast) 235 { 236 237 memset(ast, 0, sizeof(*ast)); 238 ast->st_dev = st->st_dev; 239 ast->st_ino = st->st_ino; 240 ast->st_mode = st->st_mode; 241 ast->st_nlink = st->st_nlink; 242 ast->st_uid = st->st_uid; 243 ast->st_gid = st->st_gid; 244 ast->st_rdev = st->st_rdev; 245 if (st->st_size < (off_t)1 << 32) 246 ast->st_size = st->st_size; 247 else 248 ast->st_size = -2; 249 ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec; 250 ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec; 251 ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec; 252 ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec; 253 ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec; 254 ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec; 255 ast->st_blksize = st->st_blksize; 256 ast->st_blocks = st->st_blocks; 257 ast->st_flags = st->st_flags; 258 ast->st_gen = st->st_gen; 259 } 260 #endif /* COMPAT_43 */ 261 262 #ifdef COMPAT_12 263 static void 264 aoutm68k_stat12_convert(struct stat *st, struct aoutm68k_stat12 *ast) 265 { 266 267 memset(ast, 0, sizeof(*ast)); 268 ast->st_dev = st->st_dev; 269 ast->st_ino = st->st_ino; 270 ast->st_mode = st->st_mode; 271 ast->st_nlink = st->st_nlink; 272 ast->st_uid = st->st_uid; 273 ast->st_gid = st->st_gid; 274 ast->st_rdev = st->st_rdev; 275 ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec; 276 ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec; 277 ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec; 278 ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec; 279 ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec; 280 ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec; 281 if (st->st_size < (off_t)1 << 32) 282 ast->st_size = st->st_size; 283 else 284 ast->st_size = -2; 285 ast->st_blocks = st->st_blocks; 286 ast->st_blksize = st->st_blksize; 287 ast->st_flags = st->st_flags; 288 ast->st_gen = st->st_gen; 289 } 290 #endif /* COMPAT_12 */ 291 292 static void 293 aoutm68k_stat13_convert(struct stat *st, struct aoutm68k_stat *ast) 294 { 295 296 memset(ast, 0, sizeof(*ast)); 297 ast->st_dev = st->st_dev; 298 ast->st_ino = st->st_ino; 299 ast->st_mode = st->st_mode; 300 ast->st_nlink = st->st_nlink; 301 ast->st_uid = st->st_uid; 302 ast->st_gid = st->st_gid; 303 ast->st_rdev = st->st_rdev; 304 ast->st_atimespec.tv_sec = st->st_atimespec.tv_sec; 305 ast->st_atimespec.tv_nsec = st->st_atimespec.tv_nsec; 306 ast->st_mtimespec.tv_sec = st->st_mtimespec.tv_sec; 307 ast->st_mtimespec.tv_nsec = st->st_mtimespec.tv_nsec; 308 ast->st_ctimespec.tv_sec = st->st_ctimespec.tv_sec; 309 ast->st_ctimespec.tv_nsec = st->st_ctimespec.tv_nsec; 310 if (st->st_size < (off_t)1 << 32) 311 ast->st_size = st->st_size; 312 else 313 ast->st_size = -2; 314 ast->st_blocks = st->st_blocks; 315 ast->st_blksize = st->st_blksize; 316 ast->st_flags = st->st_flags; 317 ast->st_gen = st->st_gen; 318 ast->st_qspare[0] = 0; 319 ast->st_qspare[1] = 0; 320 } 321