1 1.4 pgoyette /* $NetBSD: rump_sunos_compat.c,v 1.4 2019/01/27 02:08:49 pgoyette Exp $ */ 2 1.1 pooka 3 1.1 pooka /* 4 1.1 pooka * Copyright (c) 2013 Antti Kantee. All Rights Reserved. 5 1.1 pooka * 6 1.1 pooka * Redistribution and use in source and binary forms, with or without 7 1.1 pooka * modification, are permitted provided that the following conditions 8 1.1 pooka * are met: 9 1.1 pooka * 1. Redistributions of source code must retain the above copyright 10 1.1 pooka * notice, this list of conditions and the following disclaimer. 11 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 pooka * notice, this list of conditions and the following disclaimer in the 13 1.1 pooka * documentation and/or other materials provided with the distribution. 14 1.1 pooka * 15 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 1.1 pooka * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 pooka * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 pooka * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 pooka * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 1.1 pooka * SUCH DAMAGE. 26 1.1 pooka */ 27 1.1 pooka 28 1.3 alnsn #include <sys/cdefs.h> 29 1.3 alnsn __KERNEL_RCSID(0, "$NetBSD: rump_sunos_compat.c,v 1.4 2019/01/27 02:08:49 pgoyette Exp $"); 30 1.3 alnsn 31 1.1 pooka #include <sys/param.h> 32 1.1 pooka #include <sys/dirent.h> 33 1.1 pooka #include <sys/fcntl.h> 34 1.1 pooka #include <sys/file.h> 35 1.1 pooka #include <sys/filedesc.h> 36 1.1 pooka #include <sys/malloc.h> 37 1.1 pooka #include <sys/namei.h> 38 1.1 pooka #include <sys/stat.h> 39 1.1 pooka #include <sys/syscallargs.h> 40 1.1 pooka #include <sys/vnode.h> 41 1.1 pooka #include <sys/vfs_syscalls.h> 42 1.1 pooka 43 1.1 pooka #include <compat/sys/time_types.h> 44 1.1 pooka 45 1.1 pooka #include "rump_sunos_syscallargs.h" 46 1.1 pooka 47 1.1 pooka #define SUNOS_MAXNAMLEN 255 48 1.1 pooka 49 1.1 pooka struct sunos_dirent { 50 1.1 pooka uint64_t d_fileno; 51 1.1 pooka int64_t d_off; 52 1.1 pooka unsigned short d_reclen; 53 1.1 pooka char d_name[SUNOS_MAXNAMLEN + 1]; 54 1.1 pooka }; 55 1.1 pooka 56 1.1 pooka #define SUNOS_NAMEOFF(dp) ((char *)&(dp)->d_name - (char *)dp) 57 1.1 pooka #define SUNOS_RECLEN(de,namlen) ALIGN((SUNOS_NAMEOFF(de) + (namlen) + 1)) 58 1.1 pooka 59 1.1 pooka /* 60 1.1 pooka * Rump kernels always use the _FILE_OFFSET_BITS=64 API. 61 1.1 pooka */ 62 1.1 pooka #ifdef __LP64__ 63 1.1 pooka struct sunos_stat { 64 1.1 pooka unsigned long st_dev; 65 1.1 pooka uint64_t st_ino; 66 1.1 pooka unsigned int st_mode; 67 1.1 pooka unsigned int st_nlink; 68 1.1 pooka unsigned int st_uid; 69 1.1 pooka unsigned int st_gid; 70 1.1 pooka unsigned long st_rdev; 71 1.1 pooka off_t st_size; 72 1.1 pooka 73 1.1 pooka struct timespec st_atim; 74 1.1 pooka struct timespec st_mtim; 75 1.1 pooka struct timespec st_ctim; 76 1.1 pooka int st_blksize; 77 1.1 pooka uint64_t st_blocks; 78 1.1 pooka char st_fstype[16]; 79 1.1 pooka }; 80 1.1 pooka #else 81 1.1 pooka struct sunos_stat { 82 1.1 pooka unsigned long st_dev; 83 1.1 pooka long st_pad1[3]; 84 1.1 pooka uint64_t st_ino; 85 1.1 pooka unsigned int st_mode; 86 1.1 pooka unsigned int st_nlink; 87 1.1 pooka unsigned int st_uid; 88 1.1 pooka unsigned int st_gid; 89 1.1 pooka unsigned long st_rdev; 90 1.1 pooka long st_pad2[2]; 91 1.1 pooka off_t st_size; 92 1.1 pooka 93 1.1 pooka struct timespec50 st_atim; 94 1.1 pooka struct timespec50 st_mtim; 95 1.1 pooka struct timespec50 st_ctim; 96 1.1 pooka 97 1.1 pooka int st_blksize; 98 1.1 pooka uint64_t st_blocks; 99 1.1 pooka char st_fstype[16]; 100 1.1 pooka long st_pad4[8]; 101 1.1 pooka }; 102 1.1 pooka #endif 103 1.1 pooka 104 1.1 pooka #define PARCOPY(a) ssb->a = sb->a 105 1.1 pooka static void 106 1.1 pooka bsd_to_sunos_stat(const struct stat *sb, struct sunos_stat *ssb) 107 1.1 pooka { 108 1.1 pooka 109 1.1 pooka memset(ssb, 0, sizeof(*ssb)); 110 1.1 pooka PARCOPY(st_dev); 111 1.1 pooka PARCOPY(st_ino); 112 1.1 pooka PARCOPY(st_mode); 113 1.1 pooka PARCOPY(st_nlink); 114 1.1 pooka PARCOPY(st_uid); 115 1.1 pooka PARCOPY(st_gid); 116 1.1 pooka PARCOPY(st_rdev); 117 1.1 pooka PARCOPY(st_size); 118 1.1 pooka PARCOPY(st_blksize); 119 1.1 pooka PARCOPY(st_blocks); 120 1.1 pooka 121 1.1 pooka #ifdef __LP64__ 122 1.1 pooka ssb->st_atim = sb->st_atimespec; 123 1.1 pooka ssb->st_mtim = sb->st_mtimespec; 124 1.1 pooka ssb->st_ctim = sb->st_ctimespec; 125 1.1 pooka #else 126 1.1 pooka timespec_to_timespec50(&sb->st_atimespec, &ssb->st_atim); 127 1.1 pooka timespec_to_timespec50(&sb->st_mtimespec, &ssb->st_mtim); 128 1.1 pooka timespec_to_timespec50(&sb->st_ctimespec, &ssb->st_ctim); 129 1.1 pooka #endif 130 1.1 pooka } 131 1.1 pooka 132 1.1 pooka int 133 1.1 pooka rump_sunos_sys_stat(struct lwp *l, const struct rump_sunos_sys_stat_args *uap, 134 1.1 pooka register_t *retval) 135 1.1 pooka { 136 1.1 pooka struct sunos_stat ssb; 137 1.1 pooka struct stat sb; 138 1.1 pooka int error; 139 1.1 pooka 140 1.1 pooka error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 141 1.1 pooka if (error) 142 1.1 pooka return error; 143 1.1 pooka 144 1.1 pooka bsd_to_sunos_stat(&sb, &ssb); 145 1.1 pooka 146 1.1 pooka return copyout(&ssb, SCARG(uap, sp), sizeof(ssb)); 147 1.1 pooka } 148 1.1 pooka 149 1.1 pooka int 150 1.1 pooka rump_sunos_sys_fstat(struct lwp *l, const struct rump_sunos_sys_fstat_args *uap, 151 1.1 pooka register_t *retval) 152 1.1 pooka { 153 1.1 pooka struct sunos_stat ssb; 154 1.1 pooka struct stat sb; 155 1.1 pooka int error; 156 1.1 pooka 157 1.1 pooka error = do_sys_fstat(SCARG(uap, fd), &sb); 158 1.1 pooka if (error) 159 1.1 pooka return error; 160 1.1 pooka 161 1.1 pooka bsd_to_sunos_stat(&sb, &ssb); 162 1.1 pooka 163 1.1 pooka return copyout(&ssb, SCARG(uap, sp), sizeof(ssb)); 164 1.1 pooka } 165 1.1 pooka 166 1.1 pooka int 167 1.1 pooka rump_sunos_sys_lstat(struct lwp *l, const struct rump_sunos_sys_lstat_args *uap, 168 1.1 pooka register_t *retval) 169 1.1 pooka { 170 1.1 pooka struct sunos_stat ssb; 171 1.1 pooka struct stat sb; 172 1.1 pooka int error; 173 1.1 pooka 174 1.1 pooka error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 175 1.1 pooka if (error) 176 1.1 pooka return error; 177 1.1 pooka 178 1.1 pooka bsd_to_sunos_stat(&sb, &ssb); 179 1.1 pooka 180 1.1 pooka return copyout(&ssb, SCARG(uap, sp), sizeof(ssb)); 181 1.1 pooka } 182 1.1 pooka 183 1.1 pooka int 184 1.1 pooka rump_sunos_sys_open(struct lwp *l, const struct rump_sunos_sys_open_args *uap, 185 1.1 pooka register_t *retval) 186 1.1 pooka { 187 1.1 pooka /* { 188 1.1 pooka syscallarg(const char *) path; 189 1.1 pooka syscallarg(int) flags; 190 1.1 pooka syscallarg(int) mode; 191 1.1 pooka } */ 192 1.1 pooka struct sys_open_args ua; 193 1.1 pooka int sflags, flags; 194 1.1 pooka 195 1.1 pooka sflags = SCARG(uap, flags); 196 1.1 pooka flags = (sflags & (0x8 | 0x4 | 0x3)); /* nonblock/append/rw */ 197 1.1 pooka flags |= (sflags & 0x10) ? O_SYNC : 0; 198 1.1 pooka flags |= (sflags & 0x40) ? O_DSYNC : 0; 199 1.1 pooka flags |= (sflags & 0x8000) ? O_RSYNC : 0; 200 1.1 pooka flags |= (sflags & 0x80) ? O_NONBLOCK : 0; 201 1.1 pooka flags |= (sflags & 0x100) ? O_CREAT : 0; 202 1.1 pooka flags |= (sflags & 0x200) ? O_TRUNC : 0; 203 1.1 pooka flags |= (sflags & 0x400) ? O_EXCL : 0; 204 1.1 pooka flags |= (sflags & 0x20000) ? O_NOFOLLOW : 0; 205 1.1 pooka 206 1.1 pooka SCARG(&ua, path) = SCARG(uap, path); 207 1.1 pooka SCARG(&ua, flags) = flags; 208 1.1 pooka SCARG(&ua, mode) = SCARG(uap, mode); 209 1.1 pooka 210 1.1 pooka return sys_open(l, &ua, retval); 211 1.1 pooka } 212 1.1 pooka 213 1.1 pooka /*- 214 1.1 pooka * Copyright (c) 1992, 1993 215 1.1 pooka * The Regents of the University of California. All rights reserved. 216 1.1 pooka * 217 1.1 pooka * This software was developed by the Computer Systems Engineering group 218 1.1 pooka * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 219 1.1 pooka * contributed to Berkeley. 220 1.1 pooka * 221 1.1 pooka * All advertising materials mentioning features or use of this software 222 1.1 pooka * must display the following acknowledgement: 223 1.1 pooka * This product includes software developed by the University of 224 1.1 pooka * California, Lawrence Berkeley Laboratory. 225 1.1 pooka * 226 1.1 pooka * Redistribution and use in source and binary forms, with or without 227 1.1 pooka * modification, are permitted provided that the following conditions 228 1.1 pooka * are met: 229 1.1 pooka * 1. Redistributions of source code must retain the above copyright 230 1.1 pooka * notice, this list of conditions and the following disclaimer. 231 1.1 pooka * 2. Redistributions in binary form must reproduce the above copyright 232 1.1 pooka * notice, this list of conditions and the following disclaimer in the 233 1.1 pooka * documentation and/or other materials provided with the distribution. 234 1.1 pooka * 3. Neither the name of the University nor the names of its contributors 235 1.1 pooka * may be used to endorse or promote products derived from this software 236 1.1 pooka * without specific prior written permission. 237 1.1 pooka * 238 1.1 pooka * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 239 1.1 pooka * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 240 1.1 pooka * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241 1.1 pooka * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 242 1.1 pooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 243 1.1 pooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 244 1.1 pooka * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 245 1.1 pooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 246 1.1 pooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 247 1.1 pooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 248 1.1 pooka * SUCH DAMAGE. 249 1.1 pooka * 250 1.1 pooka * @(#)sunos_misc.c 8.1 (Berkeley) 6/18/93 251 1.1 pooka * 252 1.1 pooka * Header: sunos_misc.c,v 1.16 93/04/07 02:46:27 torek Exp 253 1.1 pooka */ 254 1.1 pooka 255 1.1 pooka int 256 1.1 pooka rump_sunos_sys_getdents(struct lwp *l, 257 1.1 pooka const struct rump_sunos_sys_getdents_args *uap, register_t *retval) 258 1.1 pooka { 259 1.1 pooka struct dirent *bdp; 260 1.1 pooka struct vnode *vp; 261 1.1 pooka char *inp, *buf; /* BSD-format */ 262 1.1 pooka int len, reclen; /* BSD-format */ 263 1.1 pooka char *outp; /* Sun-format */ 264 1.1 pooka int resid, sunos_reclen;/* Sun-format */ 265 1.1 pooka struct file *fp; 266 1.1 pooka struct uio auio; 267 1.1 pooka struct iovec aiov; 268 1.1 pooka struct sunos_dirent idb; 269 1.1 pooka off_t off; /* true file offset */ 270 1.1 pooka int buflen, error, eofflag; 271 1.1 pooka off_t *cookiebuf, *cookie; 272 1.1 pooka int ncookies; 273 1.1 pooka 274 1.1 pooka if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 275 1.1 pooka return (error); 276 1.1 pooka 277 1.1 pooka if ((fp->f_flag & FREAD) == 0) { 278 1.1 pooka error = EBADF; 279 1.1 pooka goto out1; 280 1.1 pooka } 281 1.1 pooka 282 1.1 pooka vp = fp->f_data; 283 1.1 pooka if (vp->v_type != VDIR) { 284 1.1 pooka error = EINVAL; 285 1.1 pooka goto out1; 286 1.1 pooka } 287 1.1 pooka 288 1.1 pooka buflen = min(MAXBSIZE, SCARG(uap, nbytes)); 289 1.1 pooka buf = malloc(buflen, M_TEMP, M_WAITOK); 290 1.1 pooka vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 291 1.1 pooka off = fp->f_offset; 292 1.1 pooka again: 293 1.1 pooka aiov.iov_base = buf; 294 1.1 pooka aiov.iov_len = buflen; 295 1.1 pooka auio.uio_iov = &aiov; 296 1.1 pooka auio.uio_iovcnt = 1; 297 1.1 pooka auio.uio_rw = UIO_READ; 298 1.1 pooka auio.uio_resid = buflen; 299 1.1 pooka auio.uio_offset = off; 300 1.1 pooka UIO_SETUP_SYSSPACE(&auio); 301 1.1 pooka /* 302 1.1 pooka * First we read into the malloc'ed buffer, then 303 1.1 pooka * we massage it into user space, one record at a time. 304 1.1 pooka */ 305 1.1 pooka error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &cookiebuf, 306 1.1 pooka &ncookies); 307 1.1 pooka if (error) 308 1.1 pooka goto out; 309 1.1 pooka 310 1.1 pooka inp = buf; 311 1.1 pooka outp = SCARG(uap, buf); 312 1.1 pooka resid = SCARG(uap, nbytes); 313 1.1 pooka if ((len = buflen - auio.uio_resid) == 0) 314 1.1 pooka goto eof; 315 1.1 pooka 316 1.1 pooka for (cookie = cookiebuf; len > 0; len -= reclen) { 317 1.1 pooka bdp = (struct dirent *)inp; 318 1.1 pooka reclen = bdp->d_reclen; 319 1.2 riastrad if (reclen & 3) { 320 1.2 riastrad error = EIO; 321 1.2 riastrad goto out; 322 1.2 riastrad } 323 1.1 pooka if ((*cookie >> 32) != 0) { 324 1.1 pooka printf("rump_sunos_sys_getdents: offset too large\n"); 325 1.1 pooka error = EINVAL; 326 1.1 pooka goto out; 327 1.1 pooka } 328 1.1 pooka if (bdp->d_fileno == 0) { 329 1.1 pooka inp += reclen; /* it is a hole; squish it out */ 330 1.1 pooka if (cookie) 331 1.1 pooka off = *cookie++; 332 1.1 pooka else 333 1.1 pooka off += reclen; 334 1.1 pooka continue; 335 1.1 pooka } 336 1.1 pooka sunos_reclen = SUNOS_RECLEN(&idb, bdp->d_namlen); 337 1.1 pooka if (reclen > len || resid < sunos_reclen) { 338 1.1 pooka /* entry too big for buffer, so just stop */ 339 1.1 pooka outp++; 340 1.1 pooka break; 341 1.1 pooka } 342 1.1 pooka if (cookie) 343 1.1 pooka off = *cookie++; /* each entry points to next */ 344 1.1 pooka else 345 1.1 pooka off += reclen; 346 1.1 pooka /* 347 1.1 pooka * Massage in place to make a Sun-shaped dirent (otherwise 348 1.1 pooka * we have to worry about touching user memory outside of 349 1.1 pooka * the copyout() call). 350 1.1 pooka */ 351 1.1 pooka idb.d_fileno = bdp->d_fileno; 352 1.1 pooka idb.d_off = off; 353 1.1 pooka idb.d_reclen = sunos_reclen; 354 1.1 pooka strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name)); 355 1.1 pooka if ((error = copyout((void *)&idb, outp, sunos_reclen)) != 0) 356 1.1 pooka goto out; 357 1.1 pooka /* advance past this real entry */ 358 1.1 pooka inp += reclen; 359 1.1 pooka /* advance output past Sun-shaped entry */ 360 1.1 pooka outp += sunos_reclen; 361 1.1 pooka resid -= sunos_reclen; 362 1.1 pooka } 363 1.1 pooka 364 1.1 pooka /* if we squished out the whole block, try again */ 365 1.1 pooka if (outp == SCARG(uap, buf)) { 366 1.1 pooka if (cookiebuf) 367 1.1 pooka free(cookiebuf, M_TEMP); 368 1.1 pooka cookiebuf = NULL; 369 1.1 pooka goto again; 370 1.1 pooka } 371 1.1 pooka fp->f_offset = off; /* update the vnode offset */ 372 1.1 pooka 373 1.1 pooka eof: 374 1.1 pooka *retval = SCARG(uap, nbytes) - resid; 375 1.1 pooka out: 376 1.1 pooka VOP_UNLOCK(vp); 377 1.1 pooka free(cookiebuf, M_TEMP); 378 1.1 pooka free(buf, M_TEMP); 379 1.1 pooka out1: 380 1.1 pooka fd_putfile(SCARG(uap, fd)); 381 1.1 pooka return (error); 382 1.1 pooka } 383