1 /* $NetBSD: sys_generic.c,v 1.132 2020/05/23 23:42:43 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 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 /* 33 * Copyright (c) 1982, 1986, 1989, 1993 34 * The Regents of the University of California. All rights reserved. 35 * (c) UNIX System Laboratories, Inc. 36 * All or some portions of this file are derived from material licensed 37 * to the University of California by American Telephone and Telegraph 38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 39 * the permission of UNIX System Laboratories, Inc. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95 66 */ 67 68 /* 69 * System calls relating to files. 70 */ 71 72 #include <sys/cdefs.h> 73 __KERNEL_RCSID(0, "$NetBSD: sys_generic.c,v 1.132 2020/05/23 23:42:43 ad Exp $"); 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/filedesc.h> 78 #include <sys/ioctl.h> 79 #include <sys/file.h> 80 #include <sys/proc.h> 81 #include <sys/socketvar.h> 82 #include <sys/signalvar.h> 83 #include <sys/uio.h> 84 #include <sys/kernel.h> 85 #include <sys/stat.h> 86 #include <sys/kmem.h> 87 #include <sys/poll.h> 88 #include <sys/vnode.h> 89 #include <sys/mount.h> 90 #include <sys/syscallargs.h> 91 #include <sys/ktrace.h> 92 #include <sys/atomic.h> 93 #include <sys/disklabel.h> 94 95 /* 96 * Read system call. 97 */ 98 /* ARGSUSED */ 99 int 100 sys_read(struct lwp *l, const struct sys_read_args *uap, register_t *retval) 101 { 102 /* { 103 syscallarg(int) fd; 104 syscallarg(void *) buf; 105 syscallarg(size_t) nbyte; 106 } */ 107 file_t *fp; 108 int fd; 109 110 fd = SCARG(uap, fd); 111 112 if ((fp = fd_getfile(fd)) == NULL) 113 return (EBADF); 114 115 if ((fp->f_flag & FREAD) == 0) { 116 fd_putfile(fd); 117 return (EBADF); 118 } 119 120 /* dofileread() will unuse the descriptor for us */ 121 return (dofileread(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 122 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 123 } 124 125 int 126 dofileread(int fd, struct file *fp, void *buf, size_t nbyte, 127 off_t *offset, int flags, register_t *retval) 128 { 129 struct iovec aiov; 130 struct uio auio; 131 size_t cnt; 132 int error; 133 lwp_t *l; 134 135 l = curlwp; 136 137 aiov.iov_base = (void *)buf; 138 aiov.iov_len = nbyte; 139 auio.uio_iov = &aiov; 140 auio.uio_iovcnt = 1; 141 auio.uio_resid = nbyte; 142 auio.uio_rw = UIO_READ; 143 auio.uio_vmspace = l->l_proc->p_vmspace; 144 145 /* 146 * Reads return ssize_t because -1 is returned on error. Therefore 147 * we must restrict the length to SSIZE_MAX to avoid garbage return 148 * values. 149 */ 150 if (auio.uio_resid > SSIZE_MAX) { 151 error = EINVAL; 152 goto out; 153 } 154 155 cnt = auio.uio_resid; 156 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 157 if (error) 158 if (auio.uio_resid != cnt && (error == ERESTART || 159 error == EINTR || error == EWOULDBLOCK)) 160 error = 0; 161 cnt -= auio.uio_resid; 162 ktrgenio(fd, UIO_READ, buf, cnt, error); 163 *retval = cnt; 164 out: 165 fd_putfile(fd); 166 return (error); 167 } 168 169 /* 170 * Scatter read system call. 171 */ 172 int 173 sys_readv(struct lwp *l, const struct sys_readv_args *uap, register_t *retval) 174 { 175 /* { 176 syscallarg(int) fd; 177 syscallarg(const struct iovec *) iovp; 178 syscallarg(int) iovcnt; 179 } */ 180 181 return do_filereadv(SCARG(uap, fd), SCARG(uap, iovp), 182 SCARG(uap, iovcnt), NULL, FOF_UPDATE_OFFSET, retval); 183 } 184 185 int 186 do_filereadv(int fd, const struct iovec *iovp, int iovcnt, 187 off_t *offset, int flags, register_t *retval) 188 { 189 struct uio auio; 190 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 191 int i, error; 192 size_t cnt; 193 u_int iovlen; 194 struct file *fp; 195 struct iovec *ktriov = NULL; 196 197 if (iovcnt == 0) 198 return EINVAL; 199 200 if ((fp = fd_getfile(fd)) == NULL) 201 return EBADF; 202 203 if ((fp->f_flag & FREAD) == 0) { 204 fd_putfile(fd); 205 return EBADF; 206 } 207 208 if (offset == NULL) 209 offset = &fp->f_offset; 210 else { 211 struct vnode *vp = fp->f_vnode; 212 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 213 error = ESPIPE; 214 goto out; 215 } 216 /* 217 * Test that the device is seekable ? 218 * XXX This works because no file systems actually 219 * XXX take any action on the seek operation. 220 */ 221 error = VOP_SEEK(vp, fp->f_offset, *offset, fp->f_cred); 222 if (error != 0) 223 goto out; 224 } 225 226 iovlen = iovcnt * sizeof(struct iovec); 227 if (flags & FOF_IOV_SYSSPACE) 228 iov = __UNCONST(iovp); 229 else { 230 iov = aiov; 231 if ((u_int)iovcnt > UIO_SMALLIOV) { 232 if ((u_int)iovcnt > IOV_MAX) { 233 error = EINVAL; 234 goto out; 235 } 236 iov = kmem_alloc(iovlen, KM_SLEEP); 237 needfree = iov; 238 } 239 error = copyin(iovp, iov, iovlen); 240 if (error) 241 goto done; 242 } 243 244 auio.uio_iov = iov; 245 auio.uio_iovcnt = iovcnt; 246 auio.uio_rw = UIO_READ; 247 auio.uio_vmspace = curproc->p_vmspace; 248 249 auio.uio_resid = 0; 250 for (i = 0; i < iovcnt; i++, iov++) { 251 auio.uio_resid += iov->iov_len; 252 /* 253 * Reads return ssize_t because -1 is returned on error. 254 * Therefore we must restrict the length to SSIZE_MAX to 255 * avoid garbage return values. 256 */ 257 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 258 error = EINVAL; 259 goto done; 260 } 261 } 262 263 /* 264 * if tracing, save a copy of iovec 265 */ 266 if (ktrpoint(KTR_GENIO)) { 267 ktriov = kmem_alloc(iovlen, KM_SLEEP); 268 memcpy(ktriov, auio.uio_iov, iovlen); 269 } 270 271 cnt = auio.uio_resid; 272 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 273 if (error) 274 if (auio.uio_resid != cnt && (error == ERESTART || 275 error == EINTR || error == EWOULDBLOCK)) 276 error = 0; 277 cnt -= auio.uio_resid; 278 *retval = cnt; 279 280 if (ktriov != NULL) { 281 ktrgeniov(fd, UIO_READ, ktriov, cnt, error); 282 kmem_free(ktriov, iovlen); 283 } 284 285 done: 286 if (needfree) 287 kmem_free(needfree, iovlen); 288 out: 289 fd_putfile(fd); 290 return (error); 291 } 292 293 /* 294 * Write system call 295 */ 296 int 297 sys_write(struct lwp *l, const struct sys_write_args *uap, register_t *retval) 298 { 299 /* { 300 syscallarg(int) fd; 301 syscallarg(const void *) buf; 302 syscallarg(size_t) nbyte; 303 } */ 304 file_t *fp; 305 int fd; 306 307 fd = SCARG(uap, fd); 308 309 if ((fp = fd_getfile(fd)) == NULL) 310 return (EBADF); 311 312 if ((fp->f_flag & FWRITE) == 0) { 313 fd_putfile(fd); 314 return (EBADF); 315 } 316 317 /* dofilewrite() will unuse the descriptor for us */ 318 return (dofilewrite(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 319 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 320 } 321 322 int 323 dofilewrite(int fd, struct file *fp, const void *buf, 324 size_t nbyte, off_t *offset, int flags, register_t *retval) 325 { 326 struct iovec aiov; 327 struct uio auio; 328 size_t cnt; 329 int error; 330 331 aiov.iov_base = __UNCONST(buf); /* XXXUNCONST kills const */ 332 aiov.iov_len = nbyte; 333 auio.uio_iov = &aiov; 334 auio.uio_iovcnt = 1; 335 auio.uio_resid = nbyte; 336 auio.uio_rw = UIO_WRITE; 337 auio.uio_vmspace = curproc->p_vmspace; 338 339 /* 340 * Writes return ssize_t because -1 is returned on error. Therefore 341 * we must restrict the length to SSIZE_MAX to avoid garbage return 342 * values. 343 */ 344 if (auio.uio_resid > SSIZE_MAX) { 345 error = EINVAL; 346 goto out; 347 } 348 349 cnt = auio.uio_resid; 350 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 351 if (error) { 352 if (auio.uio_resid != cnt && (error == ERESTART || 353 error == EINTR || error == EWOULDBLOCK)) 354 error = 0; 355 if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) { 356 mutex_enter(&proc_lock); 357 psignal(curproc, SIGPIPE); 358 mutex_exit(&proc_lock); 359 } 360 } 361 cnt -= auio.uio_resid; 362 ktrgenio(fd, UIO_WRITE, buf, cnt, error); 363 *retval = cnt; 364 out: 365 fd_putfile(fd); 366 return (error); 367 } 368 369 /* 370 * Gather write system call 371 */ 372 int 373 sys_writev(struct lwp *l, const struct sys_writev_args *uap, register_t *retval) 374 { 375 /* { 376 syscallarg(int) fd; 377 syscallarg(const struct iovec *) iovp; 378 syscallarg(int) iovcnt; 379 } */ 380 381 return do_filewritev(SCARG(uap, fd), SCARG(uap, iovp), 382 SCARG(uap, iovcnt), NULL, FOF_UPDATE_OFFSET, retval); 383 } 384 385 int 386 do_filewritev(int fd, const struct iovec *iovp, int iovcnt, 387 off_t *offset, int flags, register_t *retval) 388 { 389 struct uio auio; 390 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 391 int i, error; 392 size_t cnt; 393 u_int iovlen; 394 struct file *fp; 395 struct iovec *ktriov = NULL; 396 397 if (iovcnt == 0) 398 return EINVAL; 399 400 if ((fp = fd_getfile(fd)) == NULL) 401 return EBADF; 402 403 if ((fp->f_flag & FWRITE) == 0) { 404 fd_putfile(fd); 405 return EBADF; 406 } 407 408 if (offset == NULL) 409 offset = &fp->f_offset; 410 else { 411 struct vnode *vp = fp->f_vnode; 412 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 413 error = ESPIPE; 414 goto out; 415 } 416 /* 417 * Test that the device is seekable ? 418 * XXX This works because no file systems actually 419 * XXX take any action on the seek operation. 420 */ 421 error = VOP_SEEK(vp, fp->f_offset, *offset, fp->f_cred); 422 if (error != 0) 423 goto out; 424 } 425 426 iovlen = iovcnt * sizeof(struct iovec); 427 if (flags & FOF_IOV_SYSSPACE) 428 iov = __UNCONST(iovp); 429 else { 430 iov = aiov; 431 if ((u_int)iovcnt > UIO_SMALLIOV) { 432 if ((u_int)iovcnt > IOV_MAX) { 433 error = EINVAL; 434 goto out; 435 } 436 iov = kmem_alloc(iovlen, KM_SLEEP); 437 needfree = iov; 438 } 439 error = copyin(iovp, iov, iovlen); 440 if (error) 441 goto done; 442 } 443 444 auio.uio_iov = iov; 445 auio.uio_iovcnt = iovcnt; 446 auio.uio_rw = UIO_WRITE; 447 auio.uio_vmspace = curproc->p_vmspace; 448 449 auio.uio_resid = 0; 450 for (i = 0; i < iovcnt; i++, iov++) { 451 auio.uio_resid += iov->iov_len; 452 /* 453 * Writes return ssize_t because -1 is returned on error. 454 * Therefore we must restrict the length to SSIZE_MAX to 455 * avoid garbage return values. 456 */ 457 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 458 error = EINVAL; 459 goto done; 460 } 461 } 462 463 /* 464 * if tracing, save a copy of iovec 465 */ 466 if (ktrpoint(KTR_GENIO)) { 467 ktriov = kmem_alloc(iovlen, KM_SLEEP); 468 memcpy(ktriov, auio.uio_iov, iovlen); 469 } 470 471 cnt = auio.uio_resid; 472 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 473 if (error) { 474 if (auio.uio_resid != cnt && (error == ERESTART || 475 error == EINTR || error == EWOULDBLOCK)) 476 error = 0; 477 if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) { 478 mutex_enter(&proc_lock); 479 psignal(curproc, SIGPIPE); 480 mutex_exit(&proc_lock); 481 } 482 } 483 cnt -= auio.uio_resid; 484 *retval = cnt; 485 486 if (ktriov != NULL) { 487 ktrgeniov(fd, UIO_WRITE, ktriov, cnt, error); 488 kmem_free(ktriov, iovlen); 489 } 490 491 done: 492 if (needfree) 493 kmem_free(needfree, iovlen); 494 out: 495 fd_putfile(fd); 496 return (error); 497 } 498 499 /* 500 * Ioctl system call 501 */ 502 /* ARGSUSED */ 503 int 504 sys_ioctl(struct lwp *l, const struct sys_ioctl_args *uap, register_t *retval) 505 { 506 /* { 507 syscallarg(int) fd; 508 syscallarg(u_long) com; 509 syscallarg(void *) data; 510 } */ 511 struct file *fp; 512 proc_t *p; 513 u_long com; 514 int error; 515 size_t size, alloc_size; 516 void *data, *memp; 517 #define STK_PARAMS 128 518 u_long stkbuf[STK_PARAMS/sizeof(u_long)]; 519 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 520 size_t zero_last = 0; 521 #define zero_size(SZ) ((SZ)+zero_last) 522 #else 523 #define zero_size(SZ) (SZ) 524 #endif 525 526 memp = NULL; 527 alloc_size = 0; 528 error = 0; 529 p = l->l_proc; 530 531 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) 532 return (EBADF); 533 534 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 535 error = EBADF; 536 com = 0; 537 goto out; 538 } 539 540 switch (com = SCARG(uap, com)) { 541 case FIONCLEX: 542 case FIOCLEX: 543 fd_set_exclose(l, SCARG(uap, fd), com == FIOCLEX); 544 goto out; 545 } 546 547 /* 548 * Interpret high order word to find amount of data to be 549 * copied to/from the user's address space. 550 */ 551 size = IOCPARM_LEN(com); 552 alloc_size = size; 553 554 /* 555 * The disklabel is now padded to a multiple of 8 bytes however the old 556 * disklabel on 32bit platforms wasn't. This leaves a difference in 557 * size of 4 bytes between the two but are otherwise identical. 558 * To deal with this, we allocate enough space for the new disklabel 559 * but only copyin/out the smaller amount. 560 */ 561 if (IOCGROUP(com) == 'd') { 562 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 563 u_long ocom = com; 564 #endif 565 u_long ncom = com ^ (DIOCGDINFO ^ DIOCGDINFO32); 566 567 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 568 /* 569 * Userland might use struct disklabel that is bigger than the 570 * the kernel version (historic accident) - alloc userland 571 * size and zero unused part on copyout. 572 */ 573 #define DISKLABELLENDIFF (sizeof(struct partition) \ 574 *(__TMPBIGMAXPARTITIONS-MAXPARTITIONS)) 575 #define IOCFIXUP(NIOC) ((NIOC&~(IOCPARM_MASK<<IOCPARM_SHIFT)) | \ 576 (IOCPARM_LEN(NIOC)-DISKLABELLENDIFF)<<IOCPARM_SHIFT) 577 578 switch (IOCFIXUP(ocom)) { 579 case DIOCGDINFO: 580 case DIOCWDINFO: 581 case DIOCSDINFO: 582 case DIOCGDEFLABEL: 583 com = ncom = IOCFIXUP(ocom); 584 zero_last = DISKLABELLENDIFF; 585 size -= DISKLABELLENDIFF; 586 goto done; 587 } 588 #endif 589 590 switch (ncom) { 591 case DIOCGDINFO: 592 case DIOCWDINFO: 593 case DIOCSDINFO: 594 case DIOCGDEFLABEL: 595 com = ncom; 596 if (IOCPARM_LEN(DIOCGDINFO32) < IOCPARM_LEN(DIOCGDINFO)) 597 alloc_size = IOCPARM_LEN(DIOCGDINFO); 598 break; 599 } 600 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 601 done: ; 602 #endif 603 } 604 if (size > IOCPARM_MAX) { 605 error = ENOTTY; 606 goto out; 607 } 608 memp = NULL; 609 if ((com >> IOCPARM_SHIFT) == 0) { 610 /* UNIX-style ioctl. */ 611 data = SCARG(uap, data); 612 } else { 613 if (alloc_size > sizeof(stkbuf)) { 614 memp = kmem_alloc(alloc_size, KM_SLEEP); 615 data = memp; 616 } else { 617 data = (void *)stkbuf; 618 } 619 if (com&IOC_IN) { 620 if (size) { 621 error = copyin(SCARG(uap, data), data, size); 622 if (error) { 623 goto out; 624 } 625 /* 626 * The data between size and alloc_size has 627 * not been overwritten. It shouldn't matter 628 * but let's clear that anyway. 629 */ 630 if (__predict_false(size < alloc_size)) { 631 memset((char *)data+size, 0, 632 alloc_size - size); 633 } 634 ktrgenio(SCARG(uap, fd), UIO_WRITE, 635 SCARG(uap, data), size, 0); 636 } else { 637 *(void **)data = SCARG(uap, data); 638 } 639 } else if ((com&IOC_OUT) && size) { 640 /* 641 * Zero the buffer so the user always 642 * gets back something deterministic. 643 */ 644 memset(data, 0, zero_size(size)); 645 } else if (com&IOC_VOID) { 646 *(void **)data = SCARG(uap, data); 647 } 648 } 649 650 switch (com) { 651 652 case FIONBIO: 653 /* XXX Code block is not atomic */ 654 if (*(int *)data != 0) 655 atomic_or_uint(&fp->f_flag, FNONBLOCK); 656 else 657 atomic_and_uint(&fp->f_flag, ~FNONBLOCK); 658 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, data); 659 break; 660 661 case FIOASYNC: 662 /* XXX Code block is not atomic */ 663 if (*(int *)data != 0) 664 atomic_or_uint(&fp->f_flag, FASYNC); 665 else 666 atomic_and_uint(&fp->f_flag, ~FASYNC); 667 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, data); 668 break; 669 670 default: 671 error = (*fp->f_ops->fo_ioctl)(fp, com, data); 672 /* 673 * Copy any data to user, size was 674 * already set and checked above. 675 */ 676 if (error == 0 && (com&IOC_OUT) && size) { 677 error = copyout(data, SCARG(uap, data), 678 zero_size(size)); 679 ktrgenio(SCARG(uap, fd), UIO_READ, SCARG(uap, data), 680 size, error); 681 } 682 break; 683 } 684 out: 685 if (memp) 686 kmem_free(memp, alloc_size); 687 fd_putfile(SCARG(uap, fd)); 688 switch (error) { 689 case -1: 690 printf("sys_ioctl: _IO%s%s('%c', %lu, %lu) returned -1: " 691 "pid=%d comm=%s\n", 692 (com & IOC_IN) ? "W" : "", (com & IOC_OUT) ? "R" : "", 693 (char)IOCGROUP(com), (com & 0xff), IOCPARM_LEN(com), 694 p->p_pid, p->p_comm); 695 /* FALLTHROUGH */ 696 case EPASSTHROUGH: 697 error = ENOTTY; 698 /* FALLTHROUGH */ 699 default: 700 return (error); 701 } 702 } 703