1 1.95 reinoud /* $NetBSD: netbsd32_fs.c,v 1.95 2022/04/23 17:46:23 reinoud Exp $ */ 2 1.1 mrg 3 1.1 mrg /* 4 1.1 mrg * Copyright (c) 1998, 2001 Matthew R. Green 5 1.1 mrg * All rights reserved. 6 1.1 mrg * 7 1.1 mrg * Redistribution and use in source and binary forms, with or without 8 1.1 mrg * modification, are permitted provided that the following conditions 9 1.1 mrg * are met: 10 1.1 mrg * 1. Redistributions of source code must retain the above copyright 11 1.1 mrg * notice, this list of conditions and the following disclaimer. 12 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 mrg * notice, this list of conditions and the following disclaimer in the 14 1.1 mrg * documentation and/or other materials provided with the distribution. 15 1.1 mrg * 16 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 mrg * SUCH DAMAGE. 27 1.1 mrg */ 28 1.7 lukem 29 1.7 lukem #include <sys/cdefs.h> 30 1.95 reinoud __KERNEL_RCSID(0, "$NetBSD: netbsd32_fs.c,v 1.95 2022/04/23 17:46:23 reinoud Exp $"); 31 1.1 mrg 32 1.1 mrg #include <sys/param.h> 33 1.1 mrg #include <sys/systm.h> 34 1.1 mrg #include <sys/mount.h> 35 1.1 mrg #include <sys/socket.h> 36 1.1 mrg #include <sys/socketvar.h> 37 1.1 mrg #include <sys/stat.h> 38 1.1 mrg #include <sys/time.h> 39 1.1 mrg #include <sys/ktrace.h> 40 1.1 mrg #include <sys/resourcevar.h> 41 1.1 mrg #include <sys/vnode.h> 42 1.1 mrg #include <sys/file.h> 43 1.1 mrg #include <sys/filedesc.h> 44 1.1 mrg #include <sys/namei.h> 45 1.18 cube #include <sys/statvfs.h> 46 1.1 mrg #include <sys/syscallargs.h> 47 1.1 mrg #include <sys/proc.h> 48 1.22 christos #include <sys/dirent.h> 49 1.27 elad #include <sys/kauth.h> 50 1.37 dsl #include <sys/vfs_syscalls.h> 51 1.1 mrg 52 1.58 matt #include <fs/cd9660/cd9660_mount.h> 53 1.72 christos #include <fs/tmpfs/tmpfs_args.h> 54 1.63 macallan #include <fs/msdosfs/bpb.h> 55 1.63 macallan #include <fs/msdosfs/msdosfsmount.h> 56 1.95 reinoud #include <fs/udf/udf_mount.h> 57 1.58 matt #include <ufs/ufs/ufsmount.h> 58 1.81 mrg #include <miscfs/nullfs/null.h> 59 1.58 matt 60 1.60 matt #define NFS_ARGS_ONLY 61 1.60 matt #include <nfs/nfsmount.h> 62 1.60 matt 63 1.1 mrg #include <compat/netbsd32/netbsd32.h> 64 1.1 mrg #include <compat/netbsd32/netbsd32_syscallargs.h> 65 1.1 mrg #include <compat/netbsd32/netbsd32_conv.h> 66 1.28 martin #include <compat/sys/mount.h> 67 1.1 mrg 68 1.1 mrg 69 1.51 ad static int dofilereadv32(int, struct file *, struct netbsd32_iovec *, 70 1.47 dsl int, off_t *, int, register_t *); 71 1.51 ad static int dofilewritev32(int, struct file *, struct netbsd32_iovec *, 72 1.47 dsl int, off_t *, int, register_t *); 73 1.1 mrg 74 1.45 dsl struct iovec * 75 1.45 dsl netbsd32_get_iov(struct netbsd32_iovec *iov32, int iovlen, struct iovec *aiov, 76 1.45 dsl int aiov_len) 77 1.45 dsl { 78 1.45 dsl #define N_IOV32 8 79 1.45 dsl struct netbsd32_iovec aiov32[N_IOV32]; 80 1.45 dsl struct iovec *iov = aiov; 81 1.45 dsl struct iovec *iovp; 82 1.45 dsl int i, n, j; 83 1.45 dsl int error; 84 1.45 dsl 85 1.45 dsl if (iovlen < 0 || iovlen > IOV_MAX) 86 1.45 dsl return NULL; 87 1.45 dsl 88 1.45 dsl if (iovlen > aiov_len) 89 1.59 rmind iov = kmem_alloc(iovlen * sizeof(*iov), KM_SLEEP); 90 1.45 dsl 91 1.45 dsl iovp = iov; 92 1.45 dsl for (i = 0; i < iovlen; iov32 += N_IOV32, i += N_IOV32) { 93 1.45 dsl n = iovlen - i; 94 1.45 dsl if (n > N_IOV32) 95 1.45 dsl n = N_IOV32; 96 1.45 dsl error = copyin(iov32, aiov32, n * sizeof (*iov32)); 97 1.45 dsl if (error != 0) { 98 1.45 dsl if (iov != aiov) 99 1.59 rmind kmem_free(iov, iovlen * sizeof(*iov)); 100 1.45 dsl return NULL; 101 1.45 dsl } 102 1.45 dsl for (j = 0; j < n; iovp++, j++) { 103 1.45 dsl iovp->iov_base = NETBSD32PTR64(aiov32[j].iov_base); 104 1.45 dsl iovp->iov_len = aiov32[j].iov_len; 105 1.45 dsl } 106 1.45 dsl } 107 1.45 dsl return iov; 108 1.45 dsl #undef N_IOV32 109 1.45 dsl } 110 1.45 dsl 111 1.1 mrg int 112 1.49 dsl netbsd32_readv(struct lwp *l, const struct netbsd32_readv_args *uap, register_t *retval) 113 1.1 mrg { 114 1.49 dsl /* { 115 1.1 mrg syscallarg(int) fd; 116 1.1 mrg syscallarg(const netbsd32_iovecp_t) iovp; 117 1.1 mrg syscallarg(int) iovcnt; 118 1.49 dsl } */ 119 1.1 mrg int fd = SCARG(uap, fd); 120 1.51 ad file_t *fp; 121 1.1 mrg 122 1.51 ad if ((fp = fd_getfile(fd)) == NULL) 123 1.91 simonb return EBADF; 124 1.6 thorpej 125 1.50 dsl if ((fp->f_flag & FREAD) == 0) { 126 1.51 ad fd_putfile(fd); 127 1.91 simonb return EBADF; 128 1.50 dsl } 129 1.1 mrg 130 1.91 simonb return dofilereadv32(fd, fp, 131 1.39 dsl (struct netbsd32_iovec *)SCARG_P32(uap, iovp), 132 1.91 simonb SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval); 133 1.1 mrg } 134 1.1 mrg 135 1.1 mrg /* Damn thing copies in the iovec! */ 136 1.1 mrg int 137 1.51 ad dofilereadv32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, off_t *offset, int flags, register_t *retval) 138 1.1 mrg { 139 1.1 mrg struct uio auio; 140 1.1 mrg struct iovec *iov; 141 1.1 mrg struct iovec *needfree; 142 1.1 mrg struct iovec aiov[UIO_SMALLIOV]; 143 1.85 christos long i, error = 0; 144 1.85 christos size_t cnt; 145 1.1 mrg u_int iovlen; 146 1.1 mrg struct iovec *ktriov = NULL; 147 1.1 mrg 148 1.1 mrg /* note: can't use iovlen until iovcnt is validated */ 149 1.1 mrg iovlen = iovcnt * sizeof(struct iovec); 150 1.1 mrg if ((u_int)iovcnt > UIO_SMALLIOV) { 151 1.9 jdolecek if ((u_int)iovcnt > IOV_MAX) { 152 1.9 jdolecek error = EINVAL; 153 1.9 jdolecek goto out; 154 1.9 jdolecek } 155 1.59 rmind iov = kmem_alloc(iovlen, KM_SLEEP); 156 1.1 mrg needfree = iov; 157 1.1 mrg } else if ((u_int)iovcnt > 0) { 158 1.1 mrg iov = aiov; 159 1.1 mrg needfree = NULL; 160 1.9 jdolecek } else { 161 1.9 jdolecek error = EINVAL; 162 1.9 jdolecek goto out; 163 1.9 jdolecek } 164 1.1 mrg 165 1.1 mrg auio.uio_iov = iov; 166 1.1 mrg auio.uio_iovcnt = iovcnt; 167 1.1 mrg auio.uio_rw = UIO_READ; 168 1.51 ad auio.uio_vmspace = curproc->p_vmspace; 169 1.1 mrg error = netbsd32_to_iovecin(iovp, iov, iovcnt); 170 1.1 mrg if (error) 171 1.1 mrg goto done; 172 1.1 mrg auio.uio_resid = 0; 173 1.1 mrg for (i = 0; i < iovcnt; i++) { 174 1.1 mrg auio.uio_resid += iov->iov_len; 175 1.1 mrg /* 176 1.1 mrg * Reads return ssize_t because -1 is returned on error. 177 1.1 mrg * Therefore we must restrict the length to SSIZE_MAX to 178 1.1 mrg * avoid garbage return values. 179 1.1 mrg */ 180 1.92 simonb if (iov->iov_len > NETBSD32_SSIZE_MAX || 181 1.92 simonb auio.uio_resid > NETBSD32_SSIZE_MAX) { 182 1.1 mrg error = EINVAL; 183 1.1 mrg goto done; 184 1.1 mrg } 185 1.1 mrg iov++; 186 1.1 mrg } 187 1.46 ad 188 1.1 mrg /* 189 1.1 mrg * if tracing, save a copy of iovec 190 1.1 mrg */ 191 1.46 ad if (ktrpoint(KTR_GENIO)) { 192 1.59 rmind ktriov = kmem_alloc(iovlen, KM_SLEEP); 193 1.36 christos memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen); 194 1.1 mrg } 195 1.46 ad 196 1.1 mrg cnt = auio.uio_resid; 197 1.1 mrg error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 198 1.1 mrg if (error) 199 1.1 mrg if (auio.uio_resid != cnt && (error == ERESTART || 200 1.1 mrg error == EINTR || error == EWOULDBLOCK)) 201 1.1 mrg error = 0; 202 1.1 mrg cnt -= auio.uio_resid; 203 1.46 ad 204 1.46 ad if (ktriov != NULL) { 205 1.46 ad ktrgeniov(fd, UIO_READ, ktriov, cnt, error); 206 1.59 rmind kmem_free(ktriov, iovlen); 207 1.1 mrg } 208 1.46 ad 209 1.1 mrg *retval = cnt; 210 1.1 mrg done: 211 1.1 mrg if (needfree) 212 1.59 rmind kmem_free(needfree, iovlen); 213 1.9 jdolecek out: 214 1.51 ad fd_putfile(fd); 215 1.91 simonb return error; 216 1.1 mrg } 217 1.1 mrg 218 1.1 mrg int 219 1.49 dsl netbsd32_writev(struct lwp *l, const struct netbsd32_writev_args *uap, register_t *retval) 220 1.1 mrg { 221 1.49 dsl /* { 222 1.1 mrg syscallarg(int) fd; 223 1.1 mrg syscallarg(const netbsd32_iovecp_t) iovp; 224 1.1 mrg syscallarg(int) iovcnt; 225 1.49 dsl } */ 226 1.1 mrg int fd = SCARG(uap, fd); 227 1.51 ad file_t *fp; 228 1.1 mrg 229 1.51 ad if ((fp = fd_getfile(fd)) == NULL) 230 1.91 simonb return EBADF; 231 1.6 thorpej 232 1.50 dsl if ((fp->f_flag & FWRITE) == 0) { 233 1.51 ad fd_putfile(fd); 234 1.91 simonb return EBADF; 235 1.50 dsl } 236 1.1 mrg 237 1.91 simonb return dofilewritev32(fd, fp, 238 1.39 dsl (struct netbsd32_iovec *)SCARG_P32(uap, iovp), 239 1.91 simonb SCARG(uap, iovcnt), &fp->f_offset, FOF_UPDATE_OFFSET, retval); 240 1.1 mrg } 241 1.1 mrg 242 1.1 mrg int 243 1.51 ad dofilewritev32(int fd, struct file *fp, struct netbsd32_iovec *iovp, int iovcnt, off_t *offset, int flags, register_t *retval) 244 1.1 mrg { 245 1.1 mrg struct uio auio; 246 1.1 mrg struct iovec *iov; 247 1.1 mrg struct iovec *needfree; 248 1.1 mrg struct iovec aiov[UIO_SMALLIOV]; 249 1.85 christos long i, error = 0; 250 1.85 christos size_t cnt; 251 1.1 mrg u_int iovlen; 252 1.1 mrg struct iovec *ktriov = NULL; 253 1.1 mrg 254 1.1 mrg /* note: can't use iovlen until iovcnt is validated */ 255 1.1 mrg iovlen = iovcnt * sizeof(struct iovec); 256 1.1 mrg if ((u_int)iovcnt > UIO_SMALLIOV) { 257 1.9 jdolecek if ((u_int)iovcnt > IOV_MAX) { 258 1.9 jdolecek error = EINVAL; 259 1.9 jdolecek goto out; 260 1.9 jdolecek } 261 1.59 rmind iov = kmem_alloc(iovlen, KM_SLEEP); 262 1.1 mrg needfree = iov; 263 1.1 mrg } else if ((u_int)iovcnt > 0) { 264 1.1 mrg iov = aiov; 265 1.1 mrg needfree = NULL; 266 1.9 jdolecek } else { 267 1.9 jdolecek error = EINVAL; 268 1.9 jdolecek goto out; 269 1.9 jdolecek } 270 1.1 mrg 271 1.1 mrg auio.uio_iov = iov; 272 1.1 mrg auio.uio_iovcnt = iovcnt; 273 1.1 mrg auio.uio_rw = UIO_WRITE; 274 1.51 ad auio.uio_vmspace = curproc->p_vmspace; 275 1.1 mrg error = netbsd32_to_iovecin(iovp, iov, iovcnt); 276 1.1 mrg if (error) 277 1.1 mrg goto done; 278 1.1 mrg auio.uio_resid = 0; 279 1.1 mrg for (i = 0; i < iovcnt; i++) { 280 1.1 mrg auio.uio_resid += iov->iov_len; 281 1.1 mrg /* 282 1.1 mrg * Writes return ssize_t because -1 is returned on error. 283 1.1 mrg * Therefore we must restrict the length to SSIZE_MAX to 284 1.1 mrg * avoid garbage return values. 285 1.1 mrg */ 286 1.92 simonb if (iov->iov_len > NETBSD32_SSIZE_MAX || 287 1.92 simonb auio.uio_resid > NETBSD32_SSIZE_MAX) { 288 1.1 mrg error = EINVAL; 289 1.1 mrg goto done; 290 1.1 mrg } 291 1.1 mrg iov++; 292 1.1 mrg } 293 1.46 ad 294 1.1 mrg /* 295 1.1 mrg * if tracing, save a copy of iovec 296 1.1 mrg */ 297 1.46 ad if (ktrpoint(KTR_GENIO)) { 298 1.59 rmind ktriov = kmem_alloc(iovlen, KM_SLEEP); 299 1.36 christos memcpy((void *)ktriov, (void *)auio.uio_iov, iovlen); 300 1.1 mrg } 301 1.46 ad 302 1.1 mrg cnt = auio.uio_resid; 303 1.1 mrg error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 304 1.1 mrg if (error) { 305 1.1 mrg if (auio.uio_resid != cnt && (error == ERESTART || 306 1.1 mrg error == EINTR || error == EWOULDBLOCK)) 307 1.1 mrg error = 0; 308 1.62 christos if (error == EPIPE && (fp->f_flag & FNOSIGPIPE) == 0) { 309 1.90 ad mutex_enter(&proc_lock); 310 1.51 ad psignal(curproc, SIGPIPE); 311 1.90 ad mutex_exit(&proc_lock); 312 1.44 ad } 313 1.1 mrg } 314 1.1 mrg cnt -= auio.uio_resid; 315 1.46 ad if (ktriov != NULL) { 316 1.75 dholland ktrgeniov(fd, UIO_WRITE, ktriov, cnt, error); 317 1.59 rmind kmem_free(ktriov, iovlen); 318 1.1 mrg } 319 1.1 mrg *retval = cnt; 320 1.1 mrg done: 321 1.1 mrg if (needfree) 322 1.59 rmind kmem_free(needfree, iovlen); 323 1.9 jdolecek out: 324 1.51 ad fd_putfile(fd); 325 1.91 simonb return error; 326 1.1 mrg } 327 1.1 mrg 328 1.43 dsl /* 329 1.68 njoly * Common routines to set access and modification times given a vnode. 330 1.43 dsl */ 331 1.43 dsl static int 332 1.43 dsl get_utimes32(const netbsd32_timevalp_t *tptr, struct timeval *tv, 333 1.43 dsl struct timeval **tvp) 334 1.43 dsl { 335 1.43 dsl int error; 336 1.43 dsl struct netbsd32_timeval tv32[2]; 337 1.43 dsl 338 1.43 dsl if (tptr == NULL) { 339 1.43 dsl *tvp = NULL; 340 1.43 dsl return 0; 341 1.43 dsl } 342 1.43 dsl 343 1.43 dsl error = copyin(tptr, tv32, sizeof(tv32)); 344 1.43 dsl if (error) 345 1.43 dsl return error; 346 1.43 dsl netbsd32_to_timeval(&tv32[0], &tv[0]); 347 1.43 dsl netbsd32_to_timeval(&tv32[1], &tv[1]); 348 1.43 dsl 349 1.43 dsl *tvp = tv; 350 1.43 dsl return 0; 351 1.43 dsl } 352 1.43 dsl 353 1.68 njoly static int 354 1.68 njoly get_utimens32(const netbsd32_timespecp_t *tptr, struct timespec *ts, 355 1.68 njoly struct timespec **tsp) 356 1.68 njoly { 357 1.68 njoly int error; 358 1.68 njoly struct netbsd32_timespec ts32[2]; 359 1.68 njoly 360 1.68 njoly if (tptr == NULL) { 361 1.68 njoly *tsp = NULL; 362 1.68 njoly return 0; 363 1.68 njoly } 364 1.68 njoly 365 1.68 njoly error = copyin(tptr, ts32, sizeof(ts32)); 366 1.68 njoly if (error) 367 1.68 njoly return error; 368 1.68 njoly netbsd32_to_timespec(&ts32[0], &ts[0]); 369 1.68 njoly netbsd32_to_timespec(&ts32[1], &ts[1]); 370 1.68 njoly 371 1.68 njoly *tsp = ts; 372 1.68 njoly return 0; 373 1.68 njoly } 374 1.68 njoly 375 1.1 mrg int 376 1.56 christos netbsd32___utimes50(struct lwp *l, const struct netbsd32___utimes50_args *uap, register_t *retval) 377 1.1 mrg { 378 1.49 dsl /* { 379 1.1 mrg syscallarg(const netbsd32_charp) path; 380 1.1 mrg syscallarg(const netbsd32_timevalp_t) tptr; 381 1.49 dsl } */ 382 1.1 mrg int error; 383 1.43 dsl struct timeval tv[2], *tvp; 384 1.1 mrg 385 1.43 dsl error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 386 1.43 dsl if (error != 0) 387 1.43 dsl return error; 388 1.1 mrg 389 1.43 dsl return do_sys_utimes(l, NULL, SCARG_P32(uap, path), FOLLOW, 390 1.43 dsl tvp, UIO_SYSSPACE); 391 1.1 mrg } 392 1.1 mrg 393 1.42 dsl static int 394 1.79 mrg netbsd32_copyout_statvfs(const void *kp, void *up, size_t len) 395 1.42 dsl { 396 1.42 dsl struct netbsd32_statvfs *sbuf_32; 397 1.42 dsl int error; 398 1.42 dsl 399 1.59 rmind sbuf_32 = kmem_alloc(sizeof(*sbuf_32), KM_SLEEP); 400 1.42 dsl netbsd32_from_statvfs(kp, sbuf_32); 401 1.42 dsl error = copyout(sbuf_32, up, sizeof(*sbuf_32)); 402 1.59 rmind kmem_free(sbuf_32, sizeof(*sbuf_32)); 403 1.42 dsl 404 1.42 dsl return error; 405 1.42 dsl } 406 1.42 dsl 407 1.1 mrg int 408 1.84 christos netbsd32___statvfs190(struct lwp *l, 409 1.84 christos const struct netbsd32___statvfs190_args *uap, register_t *retval) 410 1.1 mrg { 411 1.49 dsl /* { 412 1.1 mrg syscallarg(const netbsd32_charp) path; 413 1.18 cube syscallarg(netbsd32_statvfsp_t) buf; 414 1.18 cube syscallarg(int) flags; 415 1.49 dsl } */ 416 1.42 dsl struct statvfs *sb; 417 1.1 mrg int error; 418 1.1 mrg 419 1.42 dsl sb = STATVFSBUF_GET(); 420 1.42 dsl error = do_sys_pstatvfs(l, SCARG_P32(uap, path), SCARG(uap, flags), sb); 421 1.42 dsl if (error == 0) 422 1.79 mrg error = netbsd32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0); 423 1.42 dsl STATVFSBUF_PUT(sb); 424 1.42 dsl return error; 425 1.1 mrg } 426 1.1 mrg 427 1.1 mrg int 428 1.84 christos netbsd32___fstatvfs190(struct lwp *l, 429 1.84 christos const struct netbsd32___fstatvfs190_args *uap, register_t *retval) 430 1.1 mrg { 431 1.49 dsl /* { 432 1.1 mrg syscallarg(int) fd; 433 1.18 cube syscallarg(netbsd32_statvfsp_t) buf; 434 1.18 cube syscallarg(int) flags; 435 1.49 dsl } */ 436 1.42 dsl struct statvfs *sb; 437 1.1 mrg int error; 438 1.1 mrg 439 1.42 dsl sb = STATVFSBUF_GET(); 440 1.42 dsl error = do_sys_fstatvfs(l, SCARG(uap, fd), SCARG(uap, flags), sb); 441 1.42 dsl if (error == 0) 442 1.79 mrg error = netbsd32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0); 443 1.42 dsl STATVFSBUF_PUT(sb); 444 1.18 cube return error; 445 1.18 cube } 446 1.18 cube 447 1.18 cube int 448 1.84 christos netbsd32___getvfsstat90(struct lwp *l, 449 1.84 christos const struct netbsd32___getvfsstat90_args *uap, register_t *retval) 450 1.18 cube { 451 1.49 dsl /* { 452 1.18 cube syscallarg(netbsd32_statvfsp_t) buf; 453 1.18 cube syscallarg(netbsd32_size_t) bufsize; 454 1.18 cube syscallarg(int) flags; 455 1.49 dsl } */ 456 1.18 cube 457 1.42 dsl return do_sys_getvfsstat(l, SCARG_P32(uap, buf), SCARG(uap, bufsize), 458 1.79 mrg SCARG(uap, flags), netbsd32_copyout_statvfs, 459 1.42 dsl sizeof (struct netbsd32_statvfs), retval); 460 1.18 cube } 461 1.18 cube 462 1.18 cube int 463 1.84 christos netbsd32___fhstatvfs190(struct lwp *l, 464 1.84 christos const struct netbsd32___fhstatvfs190_args *uap, register_t *retval) 465 1.18 cube { 466 1.49 dsl /* { 467 1.32 martin syscallarg(const netbsd32_pointer_t) fhp; 468 1.32 martin syscallarg(netbsd32_size_t) fh_size; 469 1.18 cube syscallarg(netbsd32_statvfsp_t) buf; 470 1.18 cube syscallarg(int) flags; 471 1.49 dsl } */ 472 1.42 dsl struct statvfs *sb; 473 1.18 cube int error; 474 1.18 cube 475 1.42 dsl sb = STATVFSBUF_GET(); 476 1.42 dsl error = do_fhstatvfs(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), sb, 477 1.42 dsl SCARG(uap, flags)); 478 1.42 dsl 479 1.42 dsl if (error == 0) 480 1.79 mrg error = netbsd32_copyout_statvfs(sb, SCARG_P32(uap, buf), 0); 481 1.42 dsl STATVFSBUF_PUT(sb); 482 1.18 cube 483 1.42 dsl return error; 484 1.1 mrg } 485 1.1 mrg 486 1.1 mrg int 487 1.56 christos netbsd32___futimes50(struct lwp *l, const struct netbsd32___futimes50_args *uap, register_t *retval) 488 1.1 mrg { 489 1.49 dsl /* { 490 1.1 mrg syscallarg(int) fd; 491 1.1 mrg syscallarg(const netbsd32_timevalp_t) tptr; 492 1.49 dsl } */ 493 1.1 mrg int error; 494 1.51 ad file_t *fp; 495 1.43 dsl struct timeval tv[2], *tvp; 496 1.43 dsl 497 1.43 dsl error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 498 1.43 dsl if (error != 0) 499 1.43 dsl return error; 500 1.1 mrg 501 1.55 ad /* fd_getvnode() will use the descriptor for us */ 502 1.51 ad if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 503 1.91 simonb return error; 504 1.1 mrg 505 1.71 matt error = do_sys_utimes(l, fp->f_vnode, NULL, 0, tvp, UIO_SYSSPACE); 506 1.43 dsl 507 1.51 ad fd_putfile(SCARG(uap, fd)); 508 1.91 simonb return error; 509 1.1 mrg } 510 1.1 mrg 511 1.1 mrg int 512 1.56 christos netbsd32___getdents30(struct lwp *l, 513 1.56 christos const struct netbsd32___getdents30_args *uap, register_t *retval) 514 1.1 mrg { 515 1.49 dsl /* { 516 1.1 mrg syscallarg(int) fd; 517 1.1 mrg syscallarg(netbsd32_charp) buf; 518 1.1 mrg syscallarg(netbsd32_size_t) count; 519 1.49 dsl } */ 520 1.51 ad file_t *fp; 521 1.1 mrg int error, done; 522 1.1 mrg 523 1.55 ad /* fd_getvnode() will use the descriptor for us */ 524 1.51 ad if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 525 1.91 simonb return error; 526 1.1 mrg if ((fp->f_flag & FREAD) == 0) { 527 1.1 mrg error = EBADF; 528 1.1 mrg goto out; 529 1.1 mrg } 530 1.39 dsl error = vn_readdir(fp, SCARG_P32(uap, buf), 531 1.23 christos UIO_USERSPACE, SCARG(uap, count), &done, l, 0, 0); 532 1.78 mrg ktrgenio(SCARG(uap, fd), UIO_READ, SCARG_P32(uap, buf), done, error); 533 1.1 mrg *retval = done; 534 1.1 mrg out: 535 1.51 ad fd_putfile(SCARG(uap, fd)); 536 1.91 simonb return error; 537 1.1 mrg } 538 1.1 mrg 539 1.1 mrg int 540 1.56 christos netbsd32___lutimes50(struct lwp *l, 541 1.56 christos const struct netbsd32___lutimes50_args *uap, register_t *retval) 542 1.1 mrg { 543 1.49 dsl /* { 544 1.1 mrg syscallarg(const netbsd32_charp) path; 545 1.1 mrg syscallarg(const netbsd32_timevalp_t) tptr; 546 1.49 dsl } */ 547 1.1 mrg int error; 548 1.43 dsl struct timeval tv[2], *tvp; 549 1.1 mrg 550 1.43 dsl error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp); 551 1.43 dsl if (error != 0) 552 1.43 dsl return error; 553 1.1 mrg 554 1.43 dsl return do_sys_utimes(l, NULL, SCARG_P32(uap, path), NOFOLLOW, 555 1.43 dsl tvp, UIO_SYSSPACE); 556 1.1 mrg } 557 1.1 mrg 558 1.1 mrg int 559 1.56 christos netbsd32___stat50(struct lwp *l, const struct netbsd32___stat50_args *uap, register_t *retval) 560 1.1 mrg { 561 1.49 dsl /* { 562 1.1 mrg syscallarg(const netbsd32_charp) path; 563 1.1 mrg syscallarg(netbsd32_statp_t) ub; 564 1.49 dsl } */ 565 1.1 mrg struct netbsd32_stat sb32; 566 1.1 mrg struct stat sb; 567 1.1 mrg int error; 568 1.1 mrg const char *path; 569 1.1 mrg 570 1.39 dsl path = SCARG_P32(uap, path); 571 1.1 mrg 572 1.51 ad error = do_sys_stat(path, FOLLOW, &sb); 573 1.41 dsl if (error) 574 1.91 simonb return error; 575 1.56 christos netbsd32_from_stat(&sb, &sb32); 576 1.39 dsl error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 577 1.91 simonb return error; 578 1.1 mrg } 579 1.1 mrg 580 1.1 mrg int 581 1.56 christos netbsd32___fstat50(struct lwp *l, const struct netbsd32___fstat50_args *uap, register_t *retval) 582 1.1 mrg { 583 1.49 dsl /* { 584 1.1 mrg syscallarg(int) fd; 585 1.1 mrg syscallarg(netbsd32_statp_t) sb; 586 1.49 dsl } */ 587 1.1 mrg struct netbsd32_stat sb32; 588 1.1 mrg struct stat ub; 589 1.57 njoly int error; 590 1.1 mrg 591 1.57 njoly error = do_sys_fstat(SCARG(uap, fd), &ub); 592 1.1 mrg if (error == 0) { 593 1.56 christos netbsd32_from_stat(&ub, &sb32); 594 1.39 dsl error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 595 1.1 mrg } 596 1.91 simonb return error; 597 1.1 mrg } 598 1.1 mrg 599 1.1 mrg int 600 1.56 christos netbsd32___lstat50(struct lwp *l, const struct netbsd32___lstat50_args *uap, register_t *retval) 601 1.1 mrg { 602 1.49 dsl /* { 603 1.1 mrg syscallarg(const netbsd32_charp) path; 604 1.1 mrg syscallarg(netbsd32_statp_t) ub; 605 1.49 dsl } */ 606 1.1 mrg struct netbsd32_stat sb32; 607 1.1 mrg struct stat sb; 608 1.1 mrg int error; 609 1.1 mrg const char *path; 610 1.1 mrg 611 1.39 dsl path = SCARG_P32(uap, path); 612 1.1 mrg 613 1.51 ad error = do_sys_stat(path, NOFOLLOW, &sb); 614 1.1 mrg if (error) 615 1.91 simonb return error; 616 1.56 christos netbsd32_from_stat(&sb, &sb32); 617 1.39 dsl error = copyout(&sb32, SCARG_P32(uap, ub), sizeof(sb32)); 618 1.91 simonb return error; 619 1.1 mrg } 620 1.1 mrg 621 1.49 dsl int 622 1.56 christos netbsd32___fhstat50(struct lwp *l, const struct netbsd32___fhstat50_args *uap, register_t *retval) 623 1.26 cube { 624 1.49 dsl /* { 625 1.32 martin syscallarg(const netbsd32_pointer_t) fhp; 626 1.32 martin syscallarg(netbsd32_size_t) fh_size; 627 1.26 cube syscallarg(netbsd32_statp_t) sb; 628 1.49 dsl } */ 629 1.26 cube struct stat sb; 630 1.26 cube struct netbsd32_stat sb32; 631 1.26 cube int error; 632 1.26 cube 633 1.42 dsl error = do_fhstat(l, SCARG_P32(uap, fhp), SCARG(uap, fh_size), &sb); 634 1.64 matt if (error == 0) { 635 1.56 christos netbsd32_from_stat(&sb, &sb32); 636 1.86 maxv error = copyout(&sb32, SCARG_P32(uap, sb), sizeof(sb32)); 637 1.42 dsl } 638 1.29 martin return error; 639 1.26 cube } 640 1.26 cube 641 1.1 mrg int 642 1.49 dsl netbsd32_preadv(struct lwp *l, const struct netbsd32_preadv_args *uap, register_t *retval) 643 1.1 mrg { 644 1.49 dsl /* { 645 1.1 mrg syscallarg(int) fd; 646 1.1 mrg syscallarg(const netbsd32_iovecp_t) iovp; 647 1.1 mrg syscallarg(int) iovcnt; 648 1.1 mrg syscallarg(int) pad; 649 1.70 njoly syscallarg(netbsd32_off_t) offset; 650 1.49 dsl } */ 651 1.51 ad file_t *fp; 652 1.1 mrg off_t offset; 653 1.1 mrg int error, fd = SCARG(uap, fd); 654 1.1 mrg 655 1.51 ad if ((fp = fd_getfile(fd)) == NULL) 656 1.91 simonb return EBADF; 657 1.6 thorpej 658 1.50 dsl if ((fp->f_flag & FREAD) == 0) { 659 1.51 ad fd_putfile(fd); 660 1.91 simonb return EBADF; 661 1.50 dsl } 662 1.1 mrg 663 1.94 riastrad if (fp->f_ops->fo_seek == NULL) { 664 1.9 jdolecek error = ESPIPE; 665 1.9 jdolecek goto out; 666 1.9 jdolecek } 667 1.1 mrg 668 1.1 mrg offset = SCARG(uap, offset); 669 1.94 riastrad error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0); 670 1.94 riastrad if (error) 671 1.9 jdolecek goto out; 672 1.1 mrg 673 1.91 simonb return dofilereadv32(fd, fp, SCARG_P32(uap, iovp), 674 1.91 simonb SCARG(uap, iovcnt), &offset, 0, retval); 675 1.9 jdolecek 676 1.9 jdolecek out: 677 1.51 ad fd_putfile(fd); 678 1.91 simonb return error; 679 1.1 mrg } 680 1.1 mrg 681 1.1 mrg int 682 1.49 dsl netbsd32_pwritev(struct lwp *l, const struct netbsd32_pwritev_args *uap, register_t *retval) 683 1.1 mrg { 684 1.49 dsl /* { 685 1.1 mrg syscallarg(int) fd; 686 1.1 mrg syscallarg(const netbsd32_iovecp_t) iovp; 687 1.1 mrg syscallarg(int) iovcnt; 688 1.1 mrg syscallarg(int) pad; 689 1.70 njoly syscallarg(netbsd32_off_t) offset; 690 1.49 dsl } */ 691 1.51 ad file_t *fp; 692 1.1 mrg off_t offset; 693 1.1 mrg int error, fd = SCARG(uap, fd); 694 1.1 mrg 695 1.51 ad if ((fp = fd_getfile(fd)) == NULL) 696 1.91 simonb return EBADF; 697 1.6 thorpej 698 1.50 dsl if ((fp->f_flag & FWRITE) == 0) { 699 1.51 ad fd_putfile(fd); 700 1.91 simonb return EBADF; 701 1.50 dsl } 702 1.1 mrg 703 1.94 riastrad if (fp->f_ops->fo_seek == NULL) { 704 1.9 jdolecek error = ESPIPE; 705 1.9 jdolecek goto out; 706 1.9 jdolecek } 707 1.1 mrg 708 1.1 mrg offset = SCARG(uap, offset); 709 1.94 riastrad error = (*fp->f_ops->fo_seek)(fp, offset, SEEK_SET, &offset, 0); 710 1.94 riastrad if (error) 711 1.9 jdolecek goto out; 712 1.1 mrg 713 1.91 simonb return dofilewritev32(fd, fp, SCARG_P32(uap, iovp), 714 1.91 simonb SCARG(uap, iovcnt), &offset, 0, retval); 715 1.9 jdolecek 716 1.9 jdolecek out: 717 1.51 ad fd_putfile(fd); 718 1.91 simonb return error; 719 1.1 mrg } 720 1.1 mrg 721 1.1 mrg /* 722 1.1 mrg * Find pathname of process's current directory. 723 1.1 mrg * 724 1.1 mrg * Use vfs vnode-to-name reverse cache; if that fails, fall back 725 1.1 mrg * to reading directory contents. 726 1.1 mrg */ 727 1.49 dsl int 728 1.49 dsl netbsd32___getcwd(struct lwp *l, const struct netbsd32___getcwd_args *uap, register_t *retval) 729 1.1 mrg { 730 1.49 dsl /* { 731 1.1 mrg syscallarg(char *) bufp; 732 1.1 mrg syscallarg(size_t) length; 733 1.49 dsl } */ 734 1.88 ad struct proc *p = l->l_proc; 735 1.1 mrg int error; 736 1.1 mrg char *path; 737 1.1 mrg char *bp, *bend; 738 1.1 mrg int len = (int)SCARG(uap, length); 739 1.1 mrg int lenused; 740 1.88 ad struct cwdinfo *cwdi; 741 1.1 mrg 742 1.1 mrg if (len > MAXPATHLEN*4) 743 1.1 mrg len = MAXPATHLEN*4; 744 1.1 mrg else if (len < 2) 745 1.1 mrg return ERANGE; 746 1.1 mrg 747 1.59 rmind path = kmem_alloc(len, KM_SLEEP); 748 1.1 mrg bp = &path[len]; 749 1.1 mrg bend = bp; 750 1.1 mrg *(--bp) = '\0'; 751 1.1 mrg 752 1.1 mrg /* 753 1.1 mrg * 5th argument here is "max number of vnodes to traverse". 754 1.1 mrg * Since each entry takes up at least 2 bytes in the output buffer, 755 1.1 mrg * limit it to N/2 vnodes for an N byte buffer. 756 1.1 mrg */ 757 1.1 mrg #define GETCWD_CHECK_ACCESS 0x0001 758 1.88 ad cwdi = p->p_cwdi; 759 1.88 ad rw_enter(&cwdi->cwdi_lock, RW_READER); 760 1.88 ad error = getcwd_common (cwdi->cwdi_cdir, NULL, &bp, path, len/2, 761 1.23 christos GETCWD_CHECK_ACCESS, l); 762 1.88 ad rw_exit(&cwdi->cwdi_lock); 763 1.1 mrg 764 1.1 mrg if (error) 765 1.1 mrg goto out; 766 1.1 mrg lenused = bend - bp; 767 1.1 mrg *retval = lenused; 768 1.1 mrg /* put the result into user buffer */ 769 1.39 dsl error = copyout(bp, SCARG_P32(uap, bufp), lenused); 770 1.1 mrg 771 1.1 mrg out: 772 1.59 rmind kmem_free(path, len); 773 1.1 mrg return error; 774 1.1 mrg } 775 1.58 matt 776 1.58 matt int 777 1.58 matt netbsd32___mount50(struct lwp *l, const struct netbsd32___mount50_args *uap, 778 1.61 dsl register_t *retval) 779 1.58 matt { 780 1.58 matt /* { 781 1.58 matt syscallarg(netbsd32_charp) type; 782 1.58 matt syscallarg(netbsd32_charp) path; 783 1.58 matt syscallarg(int) flags; 784 1.58 matt syscallarg(netbsd32_voidp) data; 785 1.58 matt syscallarg(netbsd32_size_t) data_len; 786 1.58 matt } */ 787 1.58 matt char mtype[MNAMELEN]; 788 1.58 matt union { 789 1.58 matt struct netbsd32_ufs_args ufs_args; 790 1.58 matt struct netbsd32_mfs_args mfs_args; 791 1.58 matt struct netbsd32_iso_args iso_args; 792 1.60 matt struct netbsd32_nfs_args nfs_args; 793 1.63 macallan struct netbsd32_msdosfs_args msdosfs_args; 794 1.95 reinoud struct netbsd32_udf_args udf_args; 795 1.72 christos struct netbsd32_tmpfs_args tmpfs_args; 796 1.81 mrg struct netbsd32_null_args null_args; 797 1.58 matt } fs_args32; 798 1.58 matt union { 799 1.58 matt struct ufs_args ufs_args; 800 1.58 matt struct mfs_args mfs_args; 801 1.58 matt struct iso_args iso_args; 802 1.60 matt struct nfs_args nfs_args; 803 1.63 macallan struct msdosfs_args msdosfs_args; 804 1.95 reinoud struct udf_args udf_args; 805 1.72 christos struct tmpfs_args tmpfs_args; 806 1.81 mrg struct null_args null_args; 807 1.58 matt } fs_args; 808 1.58 matt const char *type = SCARG_P32(uap, type); 809 1.58 matt const char *path = SCARG_P32(uap, path); 810 1.58 matt int flags = SCARG(uap, flags); 811 1.83 maxv void *data, *udata; 812 1.58 matt size_t data_len = SCARG(uap, data_len); 813 1.58 matt enum uio_seg data_seg; 814 1.58 matt size_t len; 815 1.58 matt int error; 816 1.58 matt 817 1.83 maxv udata = data = SCARG_P32(uap, data); 818 1.83 maxv memset(&fs_args32, 0, sizeof(fs_args32)); 819 1.93 simonb memset(&fs_args, 0, sizeof(fs_args)); 820 1.83 maxv 821 1.58 matt error = copyinstr(type, mtype, sizeof(mtype), &len); 822 1.58 matt if (error) 823 1.58 matt return error; 824 1.83 maxv 825 1.72 christos if (strcmp(mtype, MOUNT_TMPFS) == 0) { 826 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.tmpfs_args)) 827 1.72 christos return EINVAL; 828 1.72 christos if ((flags & MNT_GETARGS) == 0) { 829 1.72 christos error = copyin(data, &fs_args32.tmpfs_args, 830 1.72 christos sizeof(fs_args32.tmpfs_args)); 831 1.72 christos if (error) 832 1.72 christos return error; 833 1.72 christos fs_args.tmpfs_args.ta_version = 834 1.72 christos fs_args32.tmpfs_args.ta_version; 835 1.72 christos fs_args.tmpfs_args.ta_nodes_max = 836 1.72 christos fs_args32.tmpfs_args.ta_nodes_max; 837 1.72 christos fs_args.tmpfs_args.ta_size_max = 838 1.72 christos fs_args32.tmpfs_args.ta_size_max; 839 1.72 christos fs_args.tmpfs_args.ta_root_uid = 840 1.72 christos fs_args32.tmpfs_args.ta_root_uid; 841 1.72 christos fs_args.tmpfs_args.ta_root_gid = 842 1.72 christos fs_args32.tmpfs_args.ta_root_gid; 843 1.72 christos fs_args.tmpfs_args.ta_root_mode = 844 1.72 christos fs_args32.tmpfs_args.ta_root_mode; 845 1.72 christos } 846 1.72 christos data_seg = UIO_SYSSPACE; 847 1.72 christos data = &fs_args.tmpfs_args; 848 1.72 christos data_len = sizeof(fs_args.tmpfs_args); 849 1.72 christos } else if (strcmp(mtype, MOUNT_MFS) == 0) { 850 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.mfs_args)) 851 1.58 matt return EINVAL; 852 1.58 matt if ((flags & MNT_GETARGS) == 0) { 853 1.58 matt error = copyin(data, &fs_args32.mfs_args, 854 1.58 matt sizeof(fs_args32.mfs_args)); 855 1.58 matt if (error) 856 1.58 matt return error; 857 1.58 matt fs_args.mfs_args.fspec = 858 1.58 matt NETBSD32PTR64(fs_args32.mfs_args.fspec); 859 1.58 matt memset(&fs_args.mfs_args._pad1, 0, 860 1.58 matt sizeof(fs_args.mfs_args._pad1)); 861 1.58 matt fs_args.mfs_args.base = 862 1.58 matt NETBSD32PTR64(fs_args32.mfs_args.base); 863 1.58 matt fs_args.mfs_args.size = fs_args32.mfs_args.size; 864 1.58 matt } 865 1.58 matt data_seg = UIO_SYSSPACE; 866 1.58 matt data = &fs_args.mfs_args; 867 1.58 matt data_len = sizeof(fs_args.mfs_args); 868 1.63 macallan } else if ((strcmp(mtype, MOUNT_UFS) == 0) || 869 1.63 macallan (strcmp(mtype, MOUNT_EXT2FS) == 0) || 870 1.63 macallan (strcmp(mtype, MOUNT_LFS) == 0)) { 871 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.ufs_args)) 872 1.58 matt return EINVAL; 873 1.58 matt if ((flags & MNT_GETARGS) == 0) { 874 1.58 matt error = copyin(data, &fs_args32.ufs_args, 875 1.58 matt sizeof(fs_args32.ufs_args)); 876 1.58 matt if (error) 877 1.58 matt return error; 878 1.58 matt fs_args.ufs_args.fspec = 879 1.58 matt NETBSD32PTR64(fs_args32.ufs_args.fspec); 880 1.58 matt } 881 1.58 matt data_seg = UIO_SYSSPACE; 882 1.58 matt data = &fs_args.ufs_args; 883 1.58 matt data_len = sizeof(fs_args.ufs_args); 884 1.58 matt } else if (strcmp(mtype, MOUNT_CD9660) == 0) { 885 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.iso_args)) 886 1.58 matt return EINVAL; 887 1.58 matt if ((flags & MNT_GETARGS) == 0) { 888 1.58 matt error = copyin(data, &fs_args32.iso_args, 889 1.58 matt sizeof(fs_args32.iso_args)); 890 1.58 matt if (error) 891 1.58 matt return error; 892 1.58 matt fs_args.iso_args.fspec = 893 1.58 matt NETBSD32PTR64(fs_args32.iso_args.fspec); 894 1.58 matt memset(&fs_args.iso_args._pad1, 0, 895 1.58 matt sizeof(fs_args.iso_args._pad1)); 896 1.58 matt fs_args.iso_args.flags = fs_args32.iso_args.flags; 897 1.58 matt } 898 1.58 matt data_seg = UIO_SYSSPACE; 899 1.58 matt data = &fs_args.iso_args; 900 1.58 matt data_len = sizeof(fs_args.iso_args); 901 1.63 macallan } else if (strcmp(mtype, MOUNT_MSDOS) == 0) { 902 1.83 maxv if (data_len < sizeof(fs_args32.msdosfs_args)) 903 1.63 macallan return EINVAL; 904 1.63 macallan if ((flags & MNT_GETARGS) == 0) { 905 1.63 macallan error = copyin(data, &fs_args32.msdosfs_args, 906 1.63 macallan sizeof(fs_args32.msdosfs_args)); 907 1.63 macallan if (error) 908 1.63 macallan return error; 909 1.63 macallan fs_args.msdosfs_args.fspec = 910 1.63 macallan NETBSD32PTR64(fs_args32.msdosfs_args.fspec); 911 1.63 macallan memset(&fs_args.msdosfs_args._pad1, 0, 912 1.63 macallan sizeof(fs_args.msdosfs_args._pad1)); 913 1.63 macallan fs_args.msdosfs_args.uid = 914 1.63 macallan fs_args32.msdosfs_args.uid; 915 1.63 macallan fs_args.msdosfs_args.gid = 916 1.63 macallan fs_args32.msdosfs_args.gid; 917 1.63 macallan fs_args.msdosfs_args.mask = 918 1.63 macallan fs_args32.msdosfs_args.mask; 919 1.63 macallan fs_args.msdosfs_args.flags = 920 1.63 macallan fs_args32.msdosfs_args.flags; 921 1.63 macallan fs_args.msdosfs_args.version = 922 1.63 macallan fs_args32.msdosfs_args.version; 923 1.63 macallan fs_args.msdosfs_args.dirmask = 924 1.63 macallan fs_args32.msdosfs_args.dirmask; 925 1.63 macallan fs_args.msdosfs_args.gmtoff = 926 1.63 macallan fs_args32.msdosfs_args.gmtoff; 927 1.63 macallan } 928 1.63 macallan data_seg = UIO_SYSSPACE; 929 1.63 macallan data = &fs_args.msdosfs_args; 930 1.63 macallan data_len = sizeof(fs_args.msdosfs_args); 931 1.95 reinoud } else if (strcmp(mtype, MOUNT_UDF) == 0) { 932 1.95 reinoud if (data_len != 0 && data_len < sizeof(fs_args32.udf_args)) 933 1.95 reinoud return EINVAL; 934 1.95 reinoud if ((flags & MNT_GETARGS) == 0) { 935 1.95 reinoud error = copyin(data, &fs_args32.udf_args, 936 1.95 reinoud sizeof(fs_args32.udf_args)); 937 1.95 reinoud if (error) 938 1.95 reinoud return error; 939 1.95 reinoud fs_args.udf_args.version = 940 1.95 reinoud fs_args32.udf_args.version; 941 1.95 reinoud fs_args.udf_args.fspec = 942 1.95 reinoud NETBSD32PTR64(fs_args32.udf_args.fspec); 943 1.95 reinoud fs_args.udf_args.sessionnr = 944 1.95 reinoud fs_args32.udf_args.sessionnr; 945 1.95 reinoud fs_args.udf_args.udfmflags = 946 1.95 reinoud fs_args32.udf_args.udfmflags; 947 1.95 reinoud fs_args.udf_args.gmtoff = 948 1.95 reinoud fs_args32.udf_args.gmtoff; 949 1.95 reinoud fs_args.udf_args.anon_uid = 950 1.95 reinoud fs_args32.udf_args.anon_uid; 951 1.95 reinoud fs_args.udf_args.anon_gid = 952 1.95 reinoud fs_args32.udf_args.anon_gid; 953 1.95 reinoud fs_args.udf_args.nobody_uid = 954 1.95 reinoud fs_args32.udf_args.nobody_uid; 955 1.95 reinoud fs_args.udf_args.nobody_gid = 956 1.95 reinoud fs_args32.udf_args.nobody_gid; 957 1.95 reinoud fs_args.udf_args.sector_size = 958 1.95 reinoud fs_args32.udf_args.sector_size; 959 1.95 reinoud memset(fs_args.udf_args.reserved, 0, 960 1.95 reinoud sizeof(fs_args.udf_args.reserved)); 961 1.95 reinoud } 962 1.95 reinoud data_seg = UIO_SYSSPACE; 963 1.95 reinoud data = &fs_args.udf_args; 964 1.95 reinoud data_len = sizeof(fs_args.udf_args); 965 1.60 matt } else if (strcmp(mtype, MOUNT_NFS) == 0) { 966 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.nfs_args)) 967 1.60 matt return EINVAL; 968 1.83 maxv /* XXX: NFS requires copyin even with MNT_GETARGS */ 969 1.60 matt if ((flags & MNT_GETARGS) == 0) { 970 1.60 matt error = copyin(data, &fs_args32.nfs_args, 971 1.60 matt sizeof(fs_args32.nfs_args)); 972 1.60 matt if (error) 973 1.60 matt return error; 974 1.60 matt fs_args.nfs_args.version = fs_args32.nfs_args.version; 975 1.60 matt fs_args.nfs_args.addr = 976 1.60 matt NETBSD32PTR64(fs_args32.nfs_args.addr); 977 1.60 matt memcpy(&fs_args.nfs_args.addrlen, 978 1.60 matt &fs_args32.nfs_args.addrlen, 979 1.60 matt offsetof(struct nfs_args, fh) 980 1.60 matt - offsetof(struct nfs_args, addrlen)); 981 1.60 matt fs_args.nfs_args.fh = 982 1.60 matt NETBSD32PTR64(fs_args32.nfs_args.fh); 983 1.60 matt memcpy(&fs_args.nfs_args.fhsize, 984 1.60 matt &fs_args32.nfs_args.fhsize, 985 1.60 matt offsetof(struct nfs_args, hostname) 986 1.60 matt - offsetof(struct nfs_args, fhsize)); 987 1.60 matt fs_args.nfs_args.hostname = 988 1.60 matt NETBSD32PTR64(fs_args32.nfs_args.hostname); 989 1.60 matt } 990 1.60 matt data_seg = UIO_SYSSPACE; 991 1.60 matt data = &fs_args.nfs_args; 992 1.60 matt data_len = sizeof(fs_args.nfs_args); 993 1.81 mrg } else if (strcmp(mtype, MOUNT_NULL) == 0) { 994 1.89 christos if (data_len != 0 && data_len < sizeof(fs_args32.null_args)) 995 1.81 mrg return EINVAL; 996 1.81 mrg if ((flags & MNT_GETARGS) == 0) { 997 1.81 mrg error = copyin(data, &fs_args32.null_args, 998 1.81 mrg sizeof(fs_args32.null_args)); 999 1.81 mrg if (error) 1000 1.81 mrg return error; 1001 1.81 mrg fs_args.null_args.la.target = 1002 1.81 mrg NETBSD32PTR64(fs_args32.null_args.la.target); 1003 1.81 mrg } 1004 1.81 mrg data_seg = UIO_SYSSPACE; 1005 1.81 mrg data = &fs_args.null_args; 1006 1.81 mrg data_len = sizeof(fs_args.null_args); 1007 1.58 matt } else { 1008 1.58 matt data_seg = UIO_USERSPACE; 1009 1.58 matt } 1010 1.83 maxv 1011 1.73 maxv error = do_sys_mount(l, mtype, UIO_SYSSPACE, path, flags, data, data_seg, 1012 1.58 matt data_len, retval); 1013 1.58 matt if (error) 1014 1.58 matt return error; 1015 1.83 maxv 1016 1.58 matt if (flags & MNT_GETARGS) { 1017 1.58 matt data_len = *retval; 1018 1.72 christos if (strcmp(mtype, MOUNT_TMPFS) == 0) { 1019 1.89 christos if (data_len != 0 && 1020 1.89 christos data_len != sizeof(fs_args.tmpfs_args)) 1021 1.72 christos return EINVAL; 1022 1.72 christos fs_args32.tmpfs_args.ta_version = 1023 1.72 christos fs_args.tmpfs_args.ta_version; 1024 1.72 christos fs_args32.tmpfs_args.ta_nodes_max = 1025 1.72 christos fs_args.tmpfs_args.ta_nodes_max; 1026 1.72 christos fs_args32.tmpfs_args.ta_size_max = 1027 1.72 christos fs_args.tmpfs_args.ta_size_max; 1028 1.72 christos fs_args32.tmpfs_args.ta_root_uid = 1029 1.72 christos fs_args.tmpfs_args.ta_root_uid; 1030 1.72 christos fs_args32.tmpfs_args.ta_root_gid = 1031 1.72 christos fs_args.tmpfs_args.ta_root_gid; 1032 1.72 christos fs_args32.tmpfs_args.ta_root_mode = 1033 1.72 christos fs_args.tmpfs_args.ta_root_mode; 1034 1.83 maxv error = copyout(&fs_args32.tmpfs_args, udata, 1035 1.72 christos sizeof(fs_args32.tmpfs_args)); 1036 1.83 maxv *retval = sizeof(fs_args32.tmpfs_args); 1037 1.72 christos } else if (strcmp(mtype, MOUNT_MFS) == 0) { 1038 1.89 christos if (data_len != 0 && 1039 1.89 christos data_len != sizeof(fs_args.mfs_args)) 1040 1.58 matt return EINVAL; 1041 1.58 matt NETBSD32PTR32(fs_args32.mfs_args.fspec, 1042 1.58 matt fs_args.mfs_args.fspec); 1043 1.58 matt memset(&fs_args32.mfs_args._pad1, 0, 1044 1.58 matt sizeof(fs_args32.mfs_args._pad1)); 1045 1.58 matt NETBSD32PTR32(fs_args32.mfs_args.base, 1046 1.58 matt fs_args.mfs_args.base); 1047 1.58 matt fs_args32.mfs_args.size = fs_args.mfs_args.size; 1048 1.83 maxv error = copyout(&fs_args32.mfs_args, udata, 1049 1.58 matt sizeof(fs_args32.mfs_args)); 1050 1.83 maxv *retval = sizeof(fs_args32.mfs_args); 1051 1.58 matt } else if (strcmp(mtype, MOUNT_UFS) == 0) { 1052 1.89 christos if (data_len != 0 && 1053 1.89 christos data_len != sizeof(fs_args.ufs_args)) 1054 1.58 matt return EINVAL; 1055 1.58 matt NETBSD32PTR32(fs_args32.ufs_args.fspec, 1056 1.58 matt fs_args.ufs_args.fspec); 1057 1.83 maxv error = copyout(&fs_args32.ufs_args, udata, 1058 1.58 matt sizeof(fs_args32.ufs_args)); 1059 1.83 maxv *retval = sizeof(fs_args32.ufs_args); 1060 1.58 matt } else if (strcmp(mtype, MOUNT_CD9660) == 0) { 1061 1.89 christos if (data_len != 0 && 1062 1.89 christos data_len != sizeof(fs_args.iso_args)) 1063 1.58 matt return EINVAL; 1064 1.58 matt NETBSD32PTR32(fs_args32.iso_args.fspec, 1065 1.58 matt fs_args.iso_args.fspec); 1066 1.58 matt memset(&fs_args32.iso_args._pad1, 0, 1067 1.58 matt sizeof(fs_args32.iso_args._pad1)); 1068 1.58 matt fs_args32.iso_args.flags = fs_args.iso_args.flags; 1069 1.83 maxv error = copyout(&fs_args32.iso_args, udata, 1070 1.58 matt sizeof(fs_args32.iso_args)); 1071 1.83 maxv *retval = sizeof(fs_args32.iso_args); 1072 1.95 reinoud } else if (strcmp(mtype, MOUNT_UDF) == 0) { 1073 1.95 reinoud if (data_len != 0 && 1074 1.95 reinoud data_len != sizeof(fs_args.udf_args)) 1075 1.95 reinoud return EINVAL; 1076 1.95 reinoud fs_args32.udf_args.version = 1077 1.95 reinoud fs_args.udf_args.version; 1078 1.95 reinoud NETBSD32PTR32(fs_args32.udf_args.fspec, 1079 1.95 reinoud fs_args.udf_args.fspec); 1080 1.95 reinoud fs_args32.udf_args.sessionnr = 1081 1.95 reinoud fs_args.udf_args.sessionnr; 1082 1.95 reinoud fs_args32.udf_args.udfmflags = 1083 1.95 reinoud fs_args.udf_args.udfmflags; 1084 1.95 reinoud fs_args32.udf_args.gmtoff = 1085 1.95 reinoud fs_args.udf_args.gmtoff; 1086 1.95 reinoud fs_args32.udf_args.anon_uid = 1087 1.95 reinoud fs_args.udf_args.anon_uid; 1088 1.95 reinoud fs_args32.udf_args.anon_gid = 1089 1.95 reinoud fs_args.udf_args.anon_gid; 1090 1.95 reinoud fs_args32.udf_args.nobody_uid = 1091 1.95 reinoud fs_args.udf_args.nobody_uid; 1092 1.95 reinoud fs_args32.udf_args.nobody_gid = 1093 1.95 reinoud fs_args.udf_args.nobody_gid; 1094 1.95 reinoud fs_args32.udf_args.sector_size = 1095 1.95 reinoud fs_args.udf_args.sector_size; 1096 1.95 reinoud memset(fs_args32.udf_args.reserved, 0, 1097 1.95 reinoud sizeof(fs_args32.udf_args.reserved)); 1098 1.95 reinoud error = copyout(&fs_args32.udf_args, udata, 1099 1.95 reinoud sizeof(fs_args32.udf_args)); 1100 1.95 reinoud *retval = sizeof(fs_args32.udf_args); 1101 1.60 matt } else if (strcmp(mtype, MOUNT_NFS) == 0) { 1102 1.89 christos if (data_len != 0 && 1103 1.89 christos data_len != sizeof(fs_args.nfs_args)) 1104 1.60 matt return EINVAL; 1105 1.60 matt NETBSD32PTR32(fs_args32.nfs_args.addr, 1106 1.60 matt fs_args.nfs_args.addr); 1107 1.60 matt memcpy(&fs_args32.nfs_args.addrlen, 1108 1.60 matt &fs_args.nfs_args.addrlen, 1109 1.60 matt offsetof(struct nfs_args, fh) 1110 1.60 matt - offsetof(struct nfs_args, addrlen)); 1111 1.60 matt NETBSD32PTR32(fs_args32.nfs_args.fh, 1112 1.60 matt fs_args.nfs_args.fh); 1113 1.60 matt memcpy(&fs_args32.nfs_args.fhsize, 1114 1.60 matt &fs_args.nfs_args.fhsize, 1115 1.60 matt offsetof(struct nfs_args, hostname) 1116 1.60 matt - offsetof(struct nfs_args, fhsize)); 1117 1.60 matt NETBSD32PTR32(fs_args32.nfs_args.hostname, 1118 1.60 matt fs_args.nfs_args.hostname); 1119 1.83 maxv error = copyout(&fs_args32.nfs_args, udata, 1120 1.60 matt sizeof(fs_args32.nfs_args)); 1121 1.83 maxv *retval = sizeof(fs_args32.nfs_args); 1122 1.81 mrg } else if (strcmp(mtype, MOUNT_NULL) == 0) { 1123 1.89 christos if (data_len != 0 && 1124 1.89 christos data_len != sizeof(fs_args.null_args)) 1125 1.81 mrg return EINVAL; 1126 1.81 mrg NETBSD32PTR32(fs_args32.null_args.la.target, 1127 1.81 mrg fs_args.null_args.la.target); 1128 1.83 maxv error = copyout(&fs_args32.null_args, udata, 1129 1.81 mrg sizeof(fs_args32.null_args)); 1130 1.83 maxv *retval = sizeof(fs_args32.null_args); 1131 1.58 matt } 1132 1.58 matt } 1133 1.58 matt return error; 1134 1.58 matt } 1135 1.65 matt 1136 1.65 matt int 1137 1.65 matt netbsd32_linkat(struct lwp *l, const struct netbsd32_linkat_args *uap, 1138 1.65 matt register_t *retval) 1139 1.65 matt { 1140 1.65 matt /* { 1141 1.65 matt syscallarg(int) fd1; 1142 1.65 matt syscallarg(const netbsd32_charp) name1; 1143 1.65 matt syscallarg(int) fd2; 1144 1.65 matt syscallarg(const netbsd32_charp) name2; 1145 1.65 matt syscallarg(int) flags; 1146 1.65 matt } */ 1147 1.65 matt struct sys_linkat_args ua; 1148 1.65 matt 1149 1.65 matt NETBSD32TO64_UAP(fd1); 1150 1.65 matt NETBSD32TOP_UAP(name1, const char); 1151 1.65 matt NETBSD32TO64_UAP(fd2); 1152 1.65 matt NETBSD32TOP_UAP(name2, const char); 1153 1.65 matt NETBSD32TO64_UAP(flags); 1154 1.65 matt 1155 1.65 matt return sys_linkat(l, &ua, retval); 1156 1.65 matt } 1157 1.65 matt 1158 1.65 matt int 1159 1.65 matt netbsd32_renameat(struct lwp *l, const struct netbsd32_renameat_args *uap, 1160 1.65 matt register_t *retval) 1161 1.65 matt { 1162 1.65 matt /* { 1163 1.65 matt syscallarg(int) fromfd; 1164 1.65 matt syscallarg(const netbsd32_charp) from; 1165 1.65 matt syscallarg(int) tofd; 1166 1.65 matt syscallarg(const netbsd32_charp) to; 1167 1.65 matt } */ 1168 1.65 matt struct sys_renameat_args ua; 1169 1.65 matt 1170 1.65 matt NETBSD32TO64_UAP(fromfd); 1171 1.65 matt NETBSD32TOP_UAP(from, const char); 1172 1.65 matt NETBSD32TO64_UAP(tofd); 1173 1.65 matt NETBSD32TOP_UAP(to, const char); 1174 1.65 matt 1175 1.65 matt return sys_renameat(l, &ua, retval); 1176 1.65 matt } 1177 1.65 matt 1178 1.65 matt int 1179 1.65 matt netbsd32_mkfifoat(struct lwp *l, const struct netbsd32_mkfifoat_args *uap, 1180 1.65 matt register_t *retval) 1181 1.65 matt { 1182 1.65 matt /* { 1183 1.65 matt syscallarg(int) fd; 1184 1.65 matt syscallarg(const netbsd32_charp) path; 1185 1.65 matt syscallarg(mode_t) mode; 1186 1.65 matt } */ 1187 1.65 matt struct sys_mkfifoat_args ua; 1188 1.65 matt 1189 1.65 matt NETBSD32TO64_UAP(fd); 1190 1.65 matt NETBSD32TOP_UAP(path, const char); 1191 1.65 matt NETBSD32TO64_UAP(mode); 1192 1.65 matt 1193 1.65 matt return sys_mkfifoat(l, &ua, retval); 1194 1.65 matt } 1195 1.65 matt 1196 1.65 matt int 1197 1.65 matt netbsd32_mknodat(struct lwp *l, const struct netbsd32_mknodat_args *uap, 1198 1.65 matt register_t *retval) 1199 1.65 matt { 1200 1.65 matt /* { 1201 1.65 matt syscallarg(int) fd; 1202 1.65 matt syscallarg(netbsd32_charp) path; 1203 1.65 matt syscallarg(mode_t) mode; 1204 1.69 njoly syscallarg(int) pad; 1205 1.69 njoly syscallarg(netbsd32_dev_t) dev; 1206 1.65 matt } */ 1207 1.65 matt struct sys_mknodat_args ua; 1208 1.65 matt 1209 1.65 matt NETBSD32TO64_UAP(fd); 1210 1.65 matt NETBSD32TOP_UAP(path, const char); 1211 1.65 matt NETBSD32TO64_UAP(mode); 1212 1.69 njoly NETBSD32TO64_UAP(PAD); 1213 1.65 matt NETBSD32TO64_UAP(dev); 1214 1.65 matt 1215 1.65 matt return sys_mknodat(l, &ua, retval); 1216 1.65 matt } 1217 1.65 matt 1218 1.65 matt int 1219 1.65 matt netbsd32_mkdirat(struct lwp *l, const struct netbsd32_mkdirat_args *uap, 1220 1.65 matt register_t *retval) 1221 1.65 matt { 1222 1.65 matt /* { 1223 1.65 matt syscallarg(int) fd; 1224 1.65 matt syscallarg(netbsd32_charp) path; 1225 1.65 matt syscallarg(mode_t) mode; 1226 1.65 matt } */ 1227 1.65 matt struct sys_mkdirat_args ua; 1228 1.65 matt 1229 1.65 matt NETBSD32TO64_UAP(fd); 1230 1.65 matt NETBSD32TOP_UAP(path, const char); 1231 1.65 matt NETBSD32TO64_UAP(mode); 1232 1.65 matt 1233 1.65 matt return sys_mkdirat(l, &ua, retval); 1234 1.65 matt } 1235 1.65 matt 1236 1.65 matt int 1237 1.65 matt netbsd32_faccessat(struct lwp *l, const struct netbsd32_faccessat_args *uap, 1238 1.65 matt register_t *retval) 1239 1.65 matt { 1240 1.65 matt /* { 1241 1.65 matt syscallarg(int) fd; 1242 1.65 matt syscallarg(netbsd32_charp) path; 1243 1.65 matt syscallarg(int) amode; 1244 1.65 matt syscallarg(int) flag; 1245 1.65 matt } */ 1246 1.65 matt struct sys_faccessat_args ua; 1247 1.65 matt 1248 1.65 matt NETBSD32TO64_UAP(fd); 1249 1.65 matt NETBSD32TOP_UAP(path, const char); 1250 1.65 matt NETBSD32TO64_UAP(amode); 1251 1.65 matt NETBSD32TO64_UAP(flag); 1252 1.65 matt 1253 1.65 matt return sys_faccessat(l, &ua, retval); 1254 1.65 matt } 1255 1.65 matt 1256 1.65 matt int 1257 1.65 matt netbsd32_fchmodat(struct lwp *l, const struct netbsd32_fchmodat_args *uap, 1258 1.65 matt register_t *retval) 1259 1.65 matt { 1260 1.65 matt /* { 1261 1.65 matt syscallarg(int) fd; 1262 1.65 matt syscallarg(netbsd32_charp) path; 1263 1.65 matt syscallarg(mode_t) mode; 1264 1.65 matt syscallarg(int) flag; 1265 1.65 matt } */ 1266 1.65 matt struct sys_fchmodat_args ua; 1267 1.65 matt 1268 1.65 matt NETBSD32TO64_UAP(fd); 1269 1.65 matt NETBSD32TOP_UAP(path, const char); 1270 1.65 matt NETBSD32TO64_UAP(mode); 1271 1.65 matt NETBSD32TO64_UAP(flag); 1272 1.65 matt 1273 1.65 matt return sys_fchmodat(l, &ua, retval); 1274 1.65 matt } 1275 1.65 matt 1276 1.65 matt int 1277 1.65 matt netbsd32_fchownat(struct lwp *l, const struct netbsd32_fchownat_args *uap, 1278 1.65 matt register_t *retval) 1279 1.65 matt { 1280 1.65 matt /* { 1281 1.65 matt syscallarg(int) fd; 1282 1.65 matt syscallarg(netbsd32_charp) path; 1283 1.65 matt syscallarg(uid_t) owner; 1284 1.65 matt syscallarg(gid_t) group; 1285 1.65 matt syscallarg(int) flag; 1286 1.65 matt } */ 1287 1.65 matt struct sys_fchownat_args ua; 1288 1.65 matt 1289 1.65 matt NETBSD32TO64_UAP(fd); 1290 1.65 matt NETBSD32TOP_UAP(path, const char); 1291 1.65 matt NETBSD32TO64_UAP(owner); 1292 1.65 matt NETBSD32TO64_UAP(group); 1293 1.65 matt NETBSD32TO64_UAP(flag); 1294 1.65 matt 1295 1.65 matt return sys_fchownat(l, &ua, retval); 1296 1.65 matt } 1297 1.65 matt 1298 1.65 matt int 1299 1.65 matt netbsd32_fstatat(struct lwp *l, const struct netbsd32_fstatat_args *uap, 1300 1.65 matt register_t *retval) 1301 1.65 matt { 1302 1.65 matt /* { 1303 1.65 matt syscallarg(int) fd; 1304 1.65 matt syscallarg(netbsd32_charp) path; 1305 1.65 matt syscallarg(netbsd32_statp_t) buf; 1306 1.65 matt syscallarg(int) flag; 1307 1.65 matt } */ 1308 1.65 matt struct netbsd32_stat sb32; 1309 1.65 matt struct stat sb; 1310 1.66 matt int follow; 1311 1.65 matt int error; 1312 1.65 matt 1313 1.66 matt follow = (SCARG(uap, flag) & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 1314 1.65 matt 1315 1.65 matt error = do_sys_statat(l, SCARG(uap, fd), SCARG_P32(uap, path), 1316 1.66 matt follow, &sb); 1317 1.65 matt if (error) 1318 1.65 matt return error; 1319 1.65 matt netbsd32_from_stat(&sb, &sb32); 1320 1.65 matt return copyout(&sb32, SCARG_P32(uap, buf), sizeof(sb32)); 1321 1.65 matt } 1322 1.65 matt 1323 1.65 matt int 1324 1.65 matt netbsd32_utimensat(struct lwp *l, const struct netbsd32_utimensat_args *uap, 1325 1.65 matt register_t *retval) 1326 1.65 matt { 1327 1.65 matt /* { 1328 1.65 matt syscallarg(int) fd; 1329 1.65 matt syscallarg(netbsd32_charp) path; 1330 1.65 matt syscallarg(netbsd32_timespecp_t) tptr; 1331 1.65 matt syscallarg(int) flag; 1332 1.65 matt } */ 1333 1.82 mrg struct timespec ts[2], *tsp; 1334 1.66 matt int follow; 1335 1.66 matt int error; 1336 1.66 matt 1337 1.68 njoly error = get_utimens32(SCARG_P32(uap, tptr), ts, &tsp); 1338 1.68 njoly if (error != 0) 1339 1.68 njoly return error; 1340 1.66 matt 1341 1.66 matt follow = (SCARG(uap, flag) & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; 1342 1.65 matt 1343 1.68 njoly return do_sys_utimensat(l, SCARG(uap, fd), NULL, 1344 1.68 njoly SCARG_P32(uap, path), follow, tsp, UIO_SYSSPACE); 1345 1.65 matt } 1346 1.65 matt 1347 1.65 matt int 1348 1.65 matt netbsd32_openat(struct lwp *l, const struct netbsd32_openat_args *uap, 1349 1.65 matt register_t *retval) 1350 1.65 matt { 1351 1.65 matt /* { 1352 1.65 matt syscallarg(int) fd; 1353 1.65 matt syscallarg(netbsd32_charp) path; 1354 1.65 matt syscallarg(int) oflags; 1355 1.65 matt syscallarg(mode_t) mode; 1356 1.65 matt } */ 1357 1.65 matt struct sys_openat_args ua; 1358 1.65 matt 1359 1.65 matt NETBSD32TO64_UAP(fd); 1360 1.65 matt NETBSD32TOP_UAP(path, const char); 1361 1.65 matt NETBSD32TO64_UAP(oflags); 1362 1.65 matt NETBSD32TO64_UAP(mode); 1363 1.65 matt 1364 1.65 matt return sys_openat(l, &ua, retval); 1365 1.65 matt } 1366 1.65 matt 1367 1.65 matt int 1368 1.65 matt netbsd32_readlinkat(struct lwp *l, const struct netbsd32_readlinkat_args *uap, 1369 1.65 matt register_t *retval) 1370 1.65 matt { 1371 1.65 matt /* { 1372 1.65 matt syscallarg(int) fd; 1373 1.65 matt syscallarg(netbsd32_charp) path; 1374 1.65 matt syscallarg(netbsd32_charp) buf; 1375 1.65 matt syscallarg(netbsd32_size_t) bufsize; 1376 1.65 matt } */ 1377 1.65 matt struct sys_readlinkat_args ua; 1378 1.65 matt 1379 1.65 matt NETBSD32TO64_UAP(fd); 1380 1.65 matt NETBSD32TOP_UAP(path, const char *); 1381 1.65 matt NETBSD32TOP_UAP(buf, char *); 1382 1.65 matt NETBSD32TOX_UAP(bufsize, size_t); 1383 1.65 matt 1384 1.65 matt return sys_readlinkat(l, &ua, retval); 1385 1.65 matt } 1386 1.65 matt 1387 1.65 matt int 1388 1.65 matt netbsd32_symlinkat(struct lwp *l, const struct netbsd32_symlinkat_args *uap, 1389 1.65 matt register_t *retval) 1390 1.65 matt { 1391 1.65 matt /* { 1392 1.65 matt syscallarg(netbsd32_charp) path1; 1393 1.65 matt syscallarg(int) fd; 1394 1.65 matt syscallarg(netbsd32_charp) path2; 1395 1.65 matt } */ 1396 1.65 matt struct sys_symlinkat_args ua; 1397 1.65 matt 1398 1.65 matt NETBSD32TOP_UAP(path1, const char *); 1399 1.65 matt NETBSD32TO64_UAP(fd); 1400 1.65 matt NETBSD32TOP_UAP(path2, const char *); 1401 1.65 matt 1402 1.65 matt return sys_symlinkat(l, &ua, retval); 1403 1.65 matt } 1404 1.65 matt 1405 1.65 matt int 1406 1.65 matt netbsd32_unlinkat(struct lwp *l, const struct netbsd32_unlinkat_args *uap, 1407 1.65 matt register_t *retval) 1408 1.65 matt { 1409 1.65 matt /* { 1410 1.65 matt syscallarg(int) fd; 1411 1.65 matt syscallarg(netbsd32_charp) path; 1412 1.65 matt syscallarg(int) flag; 1413 1.65 matt } */ 1414 1.65 matt struct sys_unlinkat_args ua; 1415 1.65 matt 1416 1.65 matt NETBSD32TO64_UAP(fd); 1417 1.65 matt NETBSD32TOP_UAP(path, const char *); 1418 1.65 matt NETBSD32TO64_UAP(flag); 1419 1.65 matt 1420 1.65 matt return sys_unlinkat(l, &ua, retval); 1421 1.65 matt } 1422 1.65 matt 1423 1.65 matt int 1424 1.65 matt netbsd32_futimens(struct lwp *l, const struct netbsd32_futimens_args *uap, 1425 1.65 matt register_t *retval) 1426 1.65 matt { 1427 1.65 matt /* { 1428 1.65 matt syscallarg(int) fd; 1429 1.65 matt syscallarg(netbsd32_timespecp_t) tptr; 1430 1.65 matt } */ 1431 1.82 mrg struct timespec ts[2], *tsp; 1432 1.66 matt file_t *fp; 1433 1.66 matt int error; 1434 1.66 matt 1435 1.68 njoly error = get_utimens32(SCARG_P32(uap, tptr), ts, &tsp); 1436 1.68 njoly if (error != 0) 1437 1.68 njoly return error; 1438 1.65 matt 1439 1.66 matt /* fd_getvnode() will use the descriptor for us */ 1440 1.66 matt if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 1441 1.91 simonb return error; 1442 1.71 matt error = do_sys_utimensat(l, AT_FDCWD, fp->f_vnode, NULL, 0, 1443 1.68 njoly tsp, UIO_SYSSPACE); 1444 1.66 matt fd_putfile(SCARG(uap, fd)); 1445 1.91 simonb return error; 1446 1.65 matt } 1447