1 /* $NetBSD: sys_generic.c,v 1.130 2014/09/05 09:20:59 matt 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.130 2014/09/05 09:20:59 matt 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 if (iov == NULL) { 238 error = ENOMEM; 239 goto out; 240 } 241 needfree = iov; 242 } 243 error = copyin(iovp, iov, iovlen); 244 if (error) 245 goto done; 246 } 247 248 auio.uio_iov = iov; 249 auio.uio_iovcnt = iovcnt; 250 auio.uio_rw = UIO_READ; 251 auio.uio_vmspace = curproc->p_vmspace; 252 253 auio.uio_resid = 0; 254 for (i = 0; i < iovcnt; i++, iov++) { 255 auio.uio_resid += iov->iov_len; 256 /* 257 * Reads return ssize_t because -1 is returned on error. 258 * Therefore we must restrict the length to SSIZE_MAX to 259 * avoid garbage return values. 260 */ 261 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 262 error = EINVAL; 263 goto done; 264 } 265 } 266 267 /* 268 * if tracing, save a copy of iovec 269 */ 270 if (ktrpoint(KTR_GENIO)) { 271 ktriov = kmem_alloc(iovlen, KM_SLEEP); 272 if (ktriov != NULL) 273 memcpy(ktriov, auio.uio_iov, iovlen); 274 } 275 276 cnt = auio.uio_resid; 277 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 278 if (error) 279 if (auio.uio_resid != cnt && (error == ERESTART || 280 error == EINTR || error == EWOULDBLOCK)) 281 error = 0; 282 cnt -= auio.uio_resid; 283 *retval = cnt; 284 285 if (ktriov != NULL) { 286 ktrgeniov(fd, UIO_READ, ktriov, cnt, error); 287 kmem_free(ktriov, iovlen); 288 } 289 290 done: 291 if (needfree) 292 kmem_free(needfree, iovlen); 293 out: 294 fd_putfile(fd); 295 return (error); 296 } 297 298 /* 299 * Write system call 300 */ 301 int 302 sys_write(struct lwp *l, const struct sys_write_args *uap, register_t *retval) 303 { 304 /* { 305 syscallarg(int) fd; 306 syscallarg(const void *) buf; 307 syscallarg(size_t) nbyte; 308 } */ 309 file_t *fp; 310 int fd; 311 312 fd = SCARG(uap, fd); 313 314 if ((fp = fd_getfile(fd)) == NULL) 315 return (EBADF); 316 317 if ((fp->f_flag & FWRITE) == 0) { 318 fd_putfile(fd); 319 return (EBADF); 320 } 321 322 /* dofilewrite() will unuse the descriptor for us */ 323 return (dofilewrite(fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 324 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 325 } 326 327 int 328 dofilewrite(int fd, struct file *fp, const void *buf, 329 size_t nbyte, off_t *offset, int flags, register_t *retval) 330 { 331 struct iovec aiov; 332 struct uio auio; 333 size_t cnt; 334 int error; 335 336 aiov.iov_base = __UNCONST(buf); /* XXXUNCONST kills const */ 337 aiov.iov_len = nbyte; 338 auio.uio_iov = &aiov; 339 auio.uio_iovcnt = 1; 340 auio.uio_resid = nbyte; 341 auio.uio_rw = UIO_WRITE; 342 auio.uio_vmspace = curproc->p_vmspace; 343 344 /* 345 * Writes return ssize_t because -1 is returned on error. Therefore 346 * we must restrict the length to SSIZE_MAX to avoid garbage return 347 * values. 348 */ 349 if (auio.uio_resid > SSIZE_MAX) { 350 error = EINVAL; 351 goto out; 352 } 353 354 cnt = auio.uio_resid; 355 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 356 if (error) { 357 if (auio.uio_resid != cnt && (error == ERESTART || 358 error == EINTR || error == EWOULDBLOCK)) 359 error = 0; 360 if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) { 361 mutex_enter(proc_lock); 362 psignal(curproc, SIGPIPE); 363 mutex_exit(proc_lock); 364 } 365 } 366 cnt -= auio.uio_resid; 367 ktrgenio(fd, UIO_WRITE, buf, cnt, error); 368 *retval = cnt; 369 out: 370 fd_putfile(fd); 371 return (error); 372 } 373 374 /* 375 * Gather write system call 376 */ 377 int 378 sys_writev(struct lwp *l, const struct sys_writev_args *uap, register_t *retval) 379 { 380 /* { 381 syscallarg(int) fd; 382 syscallarg(const struct iovec *) iovp; 383 syscallarg(int) iovcnt; 384 } */ 385 386 return do_filewritev(SCARG(uap, fd), SCARG(uap, iovp), 387 SCARG(uap, iovcnt), NULL, FOF_UPDATE_OFFSET, retval); 388 } 389 390 int 391 do_filewritev(int fd, const struct iovec *iovp, int iovcnt, 392 off_t *offset, int flags, register_t *retval) 393 { 394 struct uio auio; 395 struct iovec *iov, *needfree = NULL, aiov[UIO_SMALLIOV]; 396 int i, error; 397 size_t cnt; 398 u_int iovlen; 399 struct file *fp; 400 struct iovec *ktriov = NULL; 401 402 if (iovcnt == 0) 403 return EINVAL; 404 405 if ((fp = fd_getfile(fd)) == NULL) 406 return EBADF; 407 408 if ((fp->f_flag & FWRITE) == 0) { 409 fd_putfile(fd); 410 return EBADF; 411 } 412 413 if (offset == NULL) 414 offset = &fp->f_offset; 415 else { 416 struct vnode *vp = fp->f_vnode; 417 if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) { 418 error = ESPIPE; 419 goto out; 420 } 421 /* 422 * Test that the device is seekable ? 423 * XXX This works because no file systems actually 424 * XXX take any action on the seek operation. 425 */ 426 error = VOP_SEEK(vp, fp->f_offset, *offset, fp->f_cred); 427 if (error != 0) 428 goto out; 429 } 430 431 iovlen = iovcnt * sizeof(struct iovec); 432 if (flags & FOF_IOV_SYSSPACE) 433 iov = __UNCONST(iovp); 434 else { 435 iov = aiov; 436 if ((u_int)iovcnt > UIO_SMALLIOV) { 437 if ((u_int)iovcnt > IOV_MAX) { 438 error = EINVAL; 439 goto out; 440 } 441 iov = kmem_alloc(iovlen, KM_SLEEP); 442 if (iov == NULL) { 443 error = ENOMEM; 444 goto out; 445 } 446 needfree = iov; 447 } 448 error = copyin(iovp, iov, iovlen); 449 if (error) 450 goto done; 451 } 452 453 auio.uio_iov = iov; 454 auio.uio_iovcnt = iovcnt; 455 auio.uio_rw = UIO_WRITE; 456 auio.uio_vmspace = curproc->p_vmspace; 457 458 auio.uio_resid = 0; 459 for (i = 0; i < iovcnt; i++, iov++) { 460 auio.uio_resid += iov->iov_len; 461 /* 462 * Writes return ssize_t because -1 is returned on error. 463 * Therefore we must restrict the length to SSIZE_MAX to 464 * avoid garbage return values. 465 */ 466 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 467 error = EINVAL; 468 goto done; 469 } 470 } 471 472 /* 473 * if tracing, save a copy of iovec 474 */ 475 if (ktrpoint(KTR_GENIO)) { 476 ktriov = kmem_alloc(iovlen, KM_SLEEP); 477 if (ktriov != NULL) 478 memcpy(ktriov, auio.uio_iov, iovlen); 479 } 480 481 cnt = auio.uio_resid; 482 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 483 if (error) { 484 if (auio.uio_resid != cnt && (error == ERESTART || 485 error == EINTR || error == EWOULDBLOCK)) 486 error = 0; 487 if (error == EPIPE && !(fp->f_flag & FNOSIGPIPE)) { 488 mutex_enter(proc_lock); 489 psignal(curproc, SIGPIPE); 490 mutex_exit(proc_lock); 491 } 492 } 493 cnt -= auio.uio_resid; 494 *retval = cnt; 495 496 if (ktriov != NULL) { 497 ktrgeniov(fd, UIO_WRITE, ktriov, cnt, error); 498 kmem_free(ktriov, iovlen); 499 } 500 501 done: 502 if (needfree) 503 kmem_free(needfree, iovlen); 504 out: 505 fd_putfile(fd); 506 return (error); 507 } 508 509 /* 510 * Ioctl system call 511 */ 512 /* ARGSUSED */ 513 int 514 sys_ioctl(struct lwp *l, const struct sys_ioctl_args *uap, register_t *retval) 515 { 516 /* { 517 syscallarg(int) fd; 518 syscallarg(u_long) com; 519 syscallarg(void *) data; 520 } */ 521 struct file *fp; 522 proc_t *p; 523 u_long com; 524 int error; 525 size_t size, alloc_size; 526 void *data, *memp; 527 #define STK_PARAMS 128 528 u_long stkbuf[STK_PARAMS/sizeof(u_long)]; 529 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 530 size_t zero_last = 0; 531 #define zero_size(SZ) ((SZ)+zero_last) 532 #else 533 #define zero_size(SZ) (SZ) 534 #endif 535 536 memp = NULL; 537 alloc_size = 0; 538 error = 0; 539 p = l->l_proc; 540 541 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) 542 return (EBADF); 543 544 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 545 error = EBADF; 546 com = 0; 547 goto out; 548 } 549 550 switch (com = SCARG(uap, com)) { 551 case FIONCLEX: 552 case FIOCLEX: 553 fd_set_exclose(l, SCARG(uap, fd), com == FIOCLEX); 554 goto out; 555 } 556 557 /* 558 * Interpret high order word to find amount of data to be 559 * copied to/from the user's address space. 560 */ 561 size = IOCPARM_LEN(com); 562 alloc_size = size; 563 564 /* 565 * The disklabel is now padded to a multiple of 8 bytes however the old 566 * disklabel on 32bit platforms wasn't. This leaves a difference in 567 * size of 4 bytes between the two but are otherwise identical. 568 * To deal with this, we allocate enough space for the new disklabel 569 * but only copyin/out the smaller amount. 570 */ 571 if (IOCGROUP(com) == 'd') { 572 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 573 u_long ocom = com; 574 #endif 575 u_long ncom = com ^ (DIOCGDINFO ^ DIOCGDINFO32); 576 577 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 578 /* 579 * Userland might use struct disklabel that is bigger than the 580 * the kernel version (historic accident) - alloc userland 581 * size and zero unused part on copyout. 582 */ 583 #define DISKLABELLENDIFF (sizeof(struct partition) \ 584 *(__TMPBIGMAXPARTITIONS-MAXPARTITIONS)) 585 #define IOCFIXUP(NIOC) ((NIOC&~(IOCPARM_MASK<<IOCPARM_SHIFT)) | \ 586 (IOCPARM_LEN(NIOC)-DISKLABELLENDIFF)<<IOCPARM_SHIFT) 587 588 switch (IOCFIXUP(ocom)) { 589 case DIOCGDINFO: 590 case DIOCWDINFO: 591 case DIOCSDINFO: 592 case DIOCGDEFLABEL: 593 com = ncom = IOCFIXUP(ocom); 594 zero_last = DISKLABELLENDIFF; 595 size -= DISKLABELLENDIFF; 596 goto done; 597 } 598 #endif 599 600 switch (ncom) { 601 case DIOCGDINFO: 602 case DIOCWDINFO: 603 case DIOCSDINFO: 604 case DIOCGDEFLABEL: 605 com = ncom; 606 if (IOCPARM_LEN(DIOCGDINFO32) < IOCPARM_LEN(DIOCGDINFO)) 607 alloc_size = IOCPARM_LEN(DIOCGDINFO); 608 break; 609 } 610 #if __TMPBIGMAXPARTITIONS > MAXPARTITIONS 611 done: ; 612 #endif 613 } 614 if (size > IOCPARM_MAX) { 615 error = ENOTTY; 616 goto out; 617 } 618 memp = NULL; 619 if ((com >> IOCPARM_SHIFT) == 0) { 620 /* UNIX-style ioctl. */ 621 data = SCARG(uap, data); 622 } else { 623 if (alloc_size > sizeof(stkbuf)) { 624 memp = kmem_alloc(alloc_size, KM_SLEEP); 625 data = memp; 626 } else { 627 data = (void *)stkbuf; 628 } 629 if (com&IOC_IN) { 630 if (size) { 631 error = copyin(SCARG(uap, data), data, size); 632 if (error) { 633 goto out; 634 } 635 /* 636 * The data between size and alloc_size has 637 * not been overwritten. It shouldn't matter 638 * but let's clear that anyway. 639 */ 640 if (__predict_false(size < alloc_size)) { 641 memset((char *)data+size, 0, 642 alloc_size - size); 643 } 644 ktrgenio(SCARG(uap, fd), UIO_WRITE, 645 SCARG(uap, data), size, 0); 646 } else { 647 *(void **)data = SCARG(uap, data); 648 } 649 } else if ((com&IOC_OUT) && size) { 650 /* 651 * Zero the buffer so the user always 652 * gets back something deterministic. 653 */ 654 memset(data, 0, zero_size(size)); 655 } else if (com&IOC_VOID) { 656 *(void **)data = SCARG(uap, data); 657 } 658 } 659 660 switch (com) { 661 662 case FIONBIO: 663 /* XXX Code block is not atomic */ 664 if (*(int *)data != 0) 665 atomic_or_uint(&fp->f_flag, FNONBLOCK); 666 else 667 atomic_and_uint(&fp->f_flag, ~FNONBLOCK); 668 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, data); 669 break; 670 671 case FIOASYNC: 672 /* XXX Code block is not atomic */ 673 if (*(int *)data != 0) 674 atomic_or_uint(&fp->f_flag, FASYNC); 675 else 676 atomic_and_uint(&fp->f_flag, ~FASYNC); 677 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, data); 678 break; 679 680 default: 681 error = (*fp->f_ops->fo_ioctl)(fp, com, data); 682 /* 683 * Copy any data to user, size was 684 * already set and checked above. 685 */ 686 if (error == 0 && (com&IOC_OUT) && size) { 687 error = copyout(data, SCARG(uap, data), 688 zero_size(size)); 689 ktrgenio(SCARG(uap, fd), UIO_READ, SCARG(uap, data), 690 size, error); 691 } 692 break; 693 } 694 out: 695 if (memp) 696 kmem_free(memp, alloc_size); 697 fd_putfile(SCARG(uap, fd)); 698 switch (error) { 699 case -1: 700 printf("sys_ioctl: _IO%s%s('%c', %lu, %lu) returned -1: " 701 "pid=%d comm=%s\n", 702 (com & IOC_IN) ? "W" : "", (com & IOC_OUT) ? "R" : "", 703 (char)IOCGROUP(com), (com & 0xff), IOCPARM_LEN(com), 704 p->p_pid, p->p_comm); 705 /* FALLTHROUGH */ 706 case EPASSTHROUGH: 707 error = ENOTTY; 708 /* FALLTHROUGH */ 709 default: 710 return (error); 711 } 712 } 713