1 /* $NetBSD: sys_generic.c,v 1.45 1999/05/05 20:01:09 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)sys_generic.c 8.9 (Berkeley) 2/14/95 41 */ 42 43 #include "opt_ktrace.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/filedesc.h> 48 #include <sys/ioctl.h> 49 #include <sys/file.h> 50 #include <sys/proc.h> 51 #include <sys/socketvar.h> 52 #include <sys/signalvar.h> 53 #include <sys/uio.h> 54 #include <sys/kernel.h> 55 #include <sys/stat.h> 56 #include <sys/malloc.h> 57 #include <sys/poll.h> 58 #ifdef KTRACE 59 #include <sys/ktrace.h> 60 #endif 61 62 #include <sys/mount.h> 63 #include <sys/syscallargs.h> 64 65 int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *)); 66 int pollscan __P((struct proc *, struct pollfd *, int, register_t *)); 67 68 /* 69 * Read system call. 70 */ 71 /* ARGSUSED */ 72 int 73 sys_read(p, v, retval) 74 struct proc *p; 75 void *v; 76 register_t *retval; 77 { 78 register struct sys_read_args /* { 79 syscallarg(int) fd; 80 syscallarg(void *) buf; 81 syscallarg(size_t) nbyte; 82 } */ *uap = v; 83 int fd = SCARG(uap, fd); 84 register struct file *fp; 85 register struct filedesc *fdp = p->p_fd; 86 87 if ((u_int)fd >= fdp->fd_nfiles || 88 (fp = fdp->fd_ofiles[fd]) == NULL || 89 (fp->f_iflags & FIF_WANTCLOSE) != 0 || 90 (fp->f_flag & FREAD) == 0) 91 return (EBADF); 92 93 FILE_USE(fp); 94 95 /* dofileread() will unuse the descriptor for us */ 96 return (dofileread(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 97 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 98 } 99 100 int 101 dofileread(p, fd, fp, buf, nbyte, offset, flags, retval) 102 struct proc *p; 103 int fd; 104 struct file *fp; 105 void *buf; 106 size_t nbyte; 107 off_t *offset; 108 int flags; 109 register_t *retval; 110 { 111 struct uio auio; 112 struct iovec aiov; 113 long cnt, error = 0; 114 #ifdef KTRACE 115 struct iovec ktriov; 116 #endif 117 118 aiov.iov_base = (caddr_t)buf; 119 aiov.iov_len = nbyte; 120 auio.uio_iov = &aiov; 121 auio.uio_iovcnt = 1; 122 auio.uio_resid = nbyte; 123 auio.uio_rw = UIO_READ; 124 auio.uio_segflg = UIO_USERSPACE; 125 auio.uio_procp = p; 126 127 /* 128 * Reads return ssize_t because -1 is returned on error. Therefore 129 * we must restrict the length to SSIZE_MAX to avoid garbage return 130 * values. 131 */ 132 if (auio.uio_resid > SSIZE_MAX) { 133 error = EINVAL; 134 goto out; 135 } 136 137 #ifdef KTRACE 138 /* 139 * if tracing, save a copy of iovec 140 */ 141 if (KTRPOINT(p, KTR_GENIO)) 142 ktriov = aiov; 143 #endif 144 cnt = auio.uio_resid; 145 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 146 if (error) 147 if (auio.uio_resid != cnt && (error == ERESTART || 148 error == EINTR || error == EWOULDBLOCK)) 149 error = 0; 150 cnt -= auio.uio_resid; 151 #ifdef KTRACE 152 if (KTRPOINT(p, KTR_GENIO) && error == 0) 153 ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error); 154 #endif 155 *retval = cnt; 156 out: 157 FILE_UNUSE(fp, p); 158 return (error); 159 } 160 161 /* 162 * Scatter read system call. 163 */ 164 int 165 sys_readv(p, v, retval) 166 struct proc *p; 167 void *v; 168 register_t *retval; 169 { 170 register struct sys_readv_args /* { 171 syscallarg(int) fd; 172 syscallarg(const struct iovec *) iovp; 173 syscallarg(int) iovcnt; 174 } */ *uap = v; 175 int fd = SCARG(uap, fd); 176 register struct file *fp; 177 register struct filedesc *fdp = p->p_fd; 178 179 if ((u_int)fd >= fdp->fd_nfiles || 180 (fp = fdp->fd_ofiles[fd]) == NULL || 181 (fp->f_iflags & FIF_WANTCLOSE) != 0 || 182 (fp->f_flag & FREAD) == 0) 183 return (EBADF); 184 185 FILE_USE(fp); 186 187 /* dofilereadv() will unuse the descriptor for us */ 188 return (dofilereadv(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt), 189 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 190 } 191 192 int 193 dofilereadv(p, fd, fp, iovp, iovcnt, offset, flags, retval) 194 struct proc *p; 195 int fd; 196 struct file *fp; 197 const struct iovec *iovp; 198 int iovcnt; 199 off_t *offset; 200 int flags; 201 register_t *retval; 202 { 203 struct uio auio; 204 register struct iovec *iov; 205 struct iovec *needfree; 206 struct iovec aiov[UIO_SMALLIOV]; 207 long i, cnt, error = 0; 208 u_int iovlen; 209 #ifdef KTRACE 210 struct iovec *ktriov = NULL; 211 #endif 212 213 /* note: can't use iovlen until iovcnt is validated */ 214 iovlen = iovcnt * sizeof(struct iovec); 215 if ((u_int)iovcnt > UIO_SMALLIOV) { 216 if ((u_int)iovcnt > IOV_MAX) { 217 error = EINVAL; 218 goto out; 219 } 220 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 221 needfree = iov; 222 } else if ((u_int)iovcnt > 0) { 223 iov = aiov; 224 needfree = NULL; 225 } else { 226 error = EINVAL; 227 goto out; 228 } 229 230 auio.uio_iov = iov; 231 auio.uio_iovcnt = iovcnt; 232 auio.uio_rw = UIO_READ; 233 auio.uio_segflg = UIO_USERSPACE; 234 auio.uio_procp = p; 235 error = copyin(iovp, iov, iovlen); 236 if (error) 237 goto done; 238 auio.uio_resid = 0; 239 for (i = 0; i < iovcnt; i++) { 240 auio.uio_resid += iov->iov_len; 241 /* 242 * Reads return ssize_t because -1 is returned on error. 243 * Therefore we must restrict the length to SSIZE_MAX to 244 * avoid garbage return values. 245 */ 246 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 247 error = EINVAL; 248 goto done; 249 } 250 iov++; 251 } 252 #ifdef KTRACE 253 /* 254 * if tracing, save a copy of iovec 255 */ 256 if (KTRPOINT(p, KTR_GENIO)) { 257 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 258 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen); 259 } 260 #endif 261 cnt = auio.uio_resid; 262 error = (*fp->f_ops->fo_read)(fp, offset, &auio, fp->f_cred, flags); 263 if (error) 264 if (auio.uio_resid != cnt && (error == ERESTART || 265 error == EINTR || error == EWOULDBLOCK)) 266 error = 0; 267 cnt -= auio.uio_resid; 268 #ifdef KTRACE 269 if (KTRPOINT(p, KTR_GENIO)) 270 if (error == 0) { 271 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt, 272 error); 273 FREE(ktriov, M_TEMP); 274 } 275 #endif 276 *retval = cnt; 277 done: 278 if (needfree) 279 FREE(needfree, M_IOV); 280 out: 281 FILE_UNUSE(fp, p); 282 return (error); 283 } 284 285 /* 286 * Write system call 287 */ 288 int 289 sys_write(p, v, retval) 290 struct proc *p; 291 void *v; 292 register_t *retval; 293 { 294 register struct sys_write_args /* { 295 syscallarg(int) fd; 296 syscallarg(const void *) buf; 297 syscallarg(size_t) nbyte; 298 } */ *uap = v; 299 int fd = SCARG(uap, fd); 300 register struct file *fp; 301 register struct filedesc *fdp = p->p_fd; 302 303 if ((u_int)fd >= fdp->fd_nfiles || 304 (fp = fdp->fd_ofiles[fd]) == NULL || 305 (fp->f_iflags & FIF_WANTCLOSE) != 0 || 306 (fp->f_flag & FWRITE) == 0) 307 return (EBADF); 308 309 FILE_USE(fp); 310 311 /* dofilewrite() will unuse the descriptor for us */ 312 return (dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte), 313 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 314 } 315 316 int 317 dofilewrite(p, fd, fp, buf, nbyte, offset, flags, retval) 318 struct proc *p; 319 int fd; 320 struct file *fp; 321 const void *buf; 322 size_t nbyte; 323 off_t *offset; 324 int flags; 325 register_t *retval; 326 { 327 struct uio auio; 328 struct iovec aiov; 329 long cnt, error = 0; 330 #ifdef KTRACE 331 struct iovec ktriov; 332 #endif 333 334 aiov.iov_base = (caddr_t)buf; /* XXX kills const */ 335 aiov.iov_len = nbyte; 336 auio.uio_iov = &aiov; 337 auio.uio_iovcnt = 1; 338 auio.uio_resid = nbyte; 339 auio.uio_rw = UIO_WRITE; 340 auio.uio_segflg = UIO_USERSPACE; 341 auio.uio_procp = p; 342 343 /* 344 * Writes return ssize_t because -1 is returned on error. Therefore 345 * we must restrict the length to SSIZE_MAX to avoid garbage return 346 * values. 347 */ 348 if (auio.uio_resid > SSIZE_MAX) { 349 error = EINVAL; 350 goto out; 351 } 352 353 #ifdef KTRACE 354 /* 355 * if tracing, save a copy of iovec 356 */ 357 if (KTRPOINT(p, KTR_GENIO)) 358 ktriov = aiov; 359 #endif 360 cnt = auio.uio_resid; 361 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 362 if (error) { 363 if (auio.uio_resid != cnt && (error == ERESTART || 364 error == EINTR || error == EWOULDBLOCK)) 365 error = 0; 366 if (error == EPIPE) 367 psignal(p, SIGPIPE); 368 } 369 cnt -= auio.uio_resid; 370 #ifdef KTRACE 371 if (KTRPOINT(p, KTR_GENIO) && error == 0) 372 ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktriov, cnt, error); 373 #endif 374 *retval = cnt; 375 out: 376 FILE_UNUSE(fp, p); 377 return (error); 378 } 379 380 /* 381 * Gather write system call 382 */ 383 int 384 sys_writev(p, v, retval) 385 struct proc *p; 386 void *v; 387 register_t *retval; 388 { 389 register struct sys_writev_args /* { 390 syscallarg(int) fd; 391 syscallarg(const struct iovec *) iovp; 392 syscallarg(int) iovcnt; 393 } */ *uap = v; 394 int fd = SCARG(uap, fd); 395 register struct file *fp; 396 register struct filedesc *fdp = p->p_fd; 397 398 if ((u_int)fd >= fdp->fd_nfiles || 399 (fp = fdp->fd_ofiles[fd]) == NULL || 400 (fp->f_iflags & FIF_WANTCLOSE) != 0 || 401 (fp->f_flag & FWRITE) == 0) 402 return (EBADF); 403 404 FILE_USE(fp); 405 406 /* dofilewritev() will unuse the descriptor for us */ 407 return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt), 408 &fp->f_offset, FOF_UPDATE_OFFSET, retval)); 409 } 410 411 int 412 dofilewritev(p, fd, fp, iovp, iovcnt, offset, flags, retval) 413 struct proc *p; 414 int fd; 415 struct file *fp; 416 const struct iovec *iovp; 417 int iovcnt; 418 off_t *offset; 419 int flags; 420 register_t *retval; 421 { 422 struct uio auio; 423 register struct iovec *iov; 424 struct iovec *needfree; 425 struct iovec aiov[UIO_SMALLIOV]; 426 long i, cnt, error = 0; 427 u_int iovlen; 428 #ifdef KTRACE 429 struct iovec *ktriov = NULL; 430 #endif 431 432 /* note: can't use iovlen until iovcnt is validated */ 433 iovlen = iovcnt * sizeof(struct iovec); 434 if ((u_int)iovcnt > UIO_SMALLIOV) { 435 if ((u_int)iovcnt > IOV_MAX) 436 return (EINVAL); 437 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 438 needfree = iov; 439 } else if ((u_int)iovcnt > 0) { 440 iov = aiov; 441 needfree = NULL; 442 } else { 443 error = EINVAL; 444 goto out; 445 } 446 447 auio.uio_iov = iov; 448 auio.uio_iovcnt = iovcnt; 449 auio.uio_rw = UIO_WRITE; 450 auio.uio_segflg = UIO_USERSPACE; 451 auio.uio_procp = p; 452 error = copyin(iovp, iov, iovlen); 453 if (error) 454 goto done; 455 auio.uio_resid = 0; 456 for (i = 0; i < iovcnt; i++) { 457 auio.uio_resid += iov->iov_len; 458 /* 459 * Writes return ssize_t because -1 is returned on error. 460 * Therefore we must restrict the length to SSIZE_MAX to 461 * avoid garbage return values. 462 */ 463 if (iov->iov_len > SSIZE_MAX || auio.uio_resid > SSIZE_MAX) { 464 error = EINVAL; 465 goto done; 466 } 467 iov++; 468 } 469 #ifdef KTRACE 470 /* 471 * if tracing, save a copy of iovec 472 */ 473 if (KTRPOINT(p, KTR_GENIO)) { 474 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 475 memcpy((caddr_t)ktriov, (caddr_t)auio.uio_iov, iovlen); 476 } 477 #endif 478 cnt = auio.uio_resid; 479 error = (*fp->f_ops->fo_write)(fp, offset, &auio, fp->f_cred, flags); 480 if (error) { 481 if (auio.uio_resid != cnt && (error == ERESTART || 482 error == EINTR || error == EWOULDBLOCK)) 483 error = 0; 484 if (error == EPIPE) 485 psignal(p, SIGPIPE); 486 } 487 cnt -= auio.uio_resid; 488 #ifdef KTRACE 489 if (KTRPOINT(p, KTR_GENIO)) 490 if (error == 0) { 491 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt, 492 error); 493 FREE(ktriov, M_TEMP); 494 } 495 #endif 496 *retval = cnt; 497 done: 498 if (needfree) 499 FREE(needfree, M_IOV); 500 out: 501 FILE_UNUSE(fp, p); 502 return (error); 503 } 504 505 /* 506 * Ioctl system call 507 */ 508 /* ARGSUSED */ 509 int 510 sys_ioctl(p, v, retval) 511 struct proc *p; 512 void *v; 513 register_t *retval; 514 { 515 register struct sys_ioctl_args /* { 516 syscallarg(int) fd; 517 syscallarg(u_long) com; 518 syscallarg(caddr_t) data; 519 } */ *uap = v; 520 register struct file *fp; 521 register struct filedesc *fdp; 522 register u_long com; 523 register int error = 0; 524 register u_int size; 525 caddr_t data, memp; 526 int tmp; 527 #define STK_PARAMS 128 528 char stkbuf[STK_PARAMS]; 529 530 fdp = p->p_fd; 531 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 532 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL || 533 (fp->f_iflags & FIF_WANTCLOSE) != 0) 534 return (EBADF); 535 536 FILE_USE(fp); 537 538 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 539 error = EBADF; 540 goto out; 541 } 542 543 switch (com = SCARG(uap, com)) { 544 case FIONCLEX: 545 fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE; 546 goto out; 547 548 case FIOCLEX: 549 fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE; 550 goto out; 551 } 552 553 /* 554 * Interpret high order word to find amount of data to be 555 * copied to/from the user's address space. 556 */ 557 size = IOCPARM_LEN(com); 558 if (size > IOCPARM_MAX) { 559 error = ENOTTY; 560 goto out; 561 } 562 memp = NULL; 563 if (size > sizeof(stkbuf)) { 564 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 565 data = memp; 566 } else 567 data = stkbuf; 568 if (com&IOC_IN) { 569 if (size) { 570 error = copyin(SCARG(uap, data), data, size); 571 if (error) { 572 if (memp) 573 free(memp, M_IOCTLOPS); 574 goto out; 575 } 576 } else 577 *(caddr_t *)data = SCARG(uap, data); 578 } else if ((com&IOC_OUT) && size) 579 /* 580 * Zero the buffer so the user always 581 * gets back something deterministic. 582 */ 583 memset(data, 0, size); 584 else if (com&IOC_VOID) 585 *(caddr_t *)data = SCARG(uap, data); 586 587 switch (com) { 588 589 case FIONBIO: 590 if ((tmp = *(int *)data) != 0) 591 fp->f_flag |= FNONBLOCK; 592 else 593 fp->f_flag &= ~FNONBLOCK; 594 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 595 break; 596 597 case FIOASYNC: 598 if ((tmp = *(int *)data) != 0) 599 fp->f_flag |= FASYNC; 600 else 601 fp->f_flag &= ~FASYNC; 602 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 603 break; 604 605 case FIOSETOWN: 606 tmp = *(int *)data; 607 if (fp->f_type == DTYPE_SOCKET) { 608 ((struct socket *)fp->f_data)->so_pgid = tmp; 609 error = 0; 610 break; 611 } 612 if (tmp <= 0) { 613 tmp = -tmp; 614 } else { 615 struct proc *p1 = pfind(tmp); 616 if (p1 == 0) { 617 error = ESRCH; 618 break; 619 } 620 tmp = p1->p_pgrp->pg_id; 621 } 622 error = (*fp->f_ops->fo_ioctl) 623 (fp, TIOCSPGRP, (caddr_t)&tmp, p); 624 break; 625 626 case FIOGETOWN: 627 if (fp->f_type == DTYPE_SOCKET) { 628 error = 0; 629 *(int *)data = ((struct socket *)fp->f_data)->so_pgid; 630 break; 631 } 632 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p); 633 *(int *)data = -*(int *)data; 634 break; 635 636 default: 637 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 638 /* 639 * Copy any data to user, size was 640 * already set and checked above. 641 */ 642 if (error == 0 && (com&IOC_OUT) && size) 643 error = copyout(data, SCARG(uap, data), size); 644 break; 645 } 646 if (memp) 647 free(memp, M_IOCTLOPS); 648 out: 649 FILE_UNUSE(fp, p); 650 return (error); 651 } 652 653 int selwait, nselcoll; 654 655 /* 656 * Select system call. 657 */ 658 int 659 sys_select(p, v, retval) 660 register struct proc *p; 661 void *v; 662 register_t *retval; 663 { 664 register struct sys_select_args /* { 665 syscallarg(int) nd; 666 syscallarg(fd_set *) in; 667 syscallarg(fd_set *) ou; 668 syscallarg(fd_set *) ex; 669 syscallarg(struct timeval *) tv; 670 } */ *uap = v; 671 caddr_t bits; 672 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6]; 673 struct timeval atv; 674 int s, ncoll, error = 0, timo; 675 size_t ni; 676 677 if (SCARG(uap, nd) < 0) 678 return (EINVAL); 679 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) { 680 /* forgiving; slightly wrong */ 681 SCARG(uap, nd) = p->p_fd->fd_nfiles; 682 } 683 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask); 684 if (ni * 6 > sizeof(smallbits)) 685 bits = malloc(ni * 6, M_TEMP, M_WAITOK); 686 else 687 bits = smallbits; 688 689 #define getbits(name, x) \ 690 if (SCARG(uap, name)) { \ 691 error = copyin(SCARG(uap, name), bits + ni * x, ni); \ 692 if (error) \ 693 goto done; \ 694 } else \ 695 memset(bits + ni * x, 0, ni); 696 getbits(in, 0); 697 getbits(ou, 1); 698 getbits(ex, 2); 699 #undef getbits 700 701 if (SCARG(uap, tv)) { 702 error = copyin(SCARG(uap, tv), (caddr_t)&atv, 703 sizeof(atv)); 704 if (error) 705 goto done; 706 if (itimerfix(&atv)) { 707 error = EINVAL; 708 goto done; 709 } 710 s = splclock(); 711 timeradd(&atv, &time, &atv); 712 timo = hzto(&atv); 713 /* 714 * Avoid inadvertently sleeping forever. 715 */ 716 if (timo == 0) 717 timo = 1; 718 splx(s); 719 } else 720 timo = 0; 721 retry: 722 ncoll = nselcoll; 723 p->p_flag |= P_SELECT; 724 error = selscan(p, (fd_mask *)(bits + ni * 0), 725 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval); 726 if (error || *retval) 727 goto done; 728 s = splhigh(); 729 if (timo && timercmp(&time, &atv, >=)) { 730 splx(s); 731 goto done; 732 } 733 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 734 splx(s); 735 goto retry; 736 } 737 p->p_flag &= ~P_SELECT; 738 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 739 splx(s); 740 if (error == 0) 741 goto retry; 742 done: 743 p->p_flag &= ~P_SELECT; 744 /* select is not restarted after signals... */ 745 if (error == ERESTART) 746 error = EINTR; 747 if (error == EWOULDBLOCK) 748 error = 0; 749 if (error == 0) { 750 #define putbits(name, x) \ 751 if (SCARG(uap, name)) { \ 752 error = copyout(bits + ni * x, SCARG(uap, name), ni); \ 753 if (error) \ 754 goto out; \ 755 } 756 putbits(in, 3); 757 putbits(ou, 4); 758 putbits(ex, 5); 759 #undef putbits 760 } 761 out: 762 if (ni * 6 > sizeof(smallbits)) 763 free(bits, M_TEMP); 764 return (error); 765 } 766 767 int 768 selscan(p, ibitp, obitp, nfd, retval) 769 struct proc *p; 770 fd_mask *ibitp, *obitp; 771 int nfd; 772 register_t *retval; 773 { 774 register struct filedesc *fdp = p->p_fd; 775 register int msk, i, j, fd; 776 register fd_mask ibits, obits; 777 struct file *fp; 778 int n = 0; 779 static int flag[3] = { POLLRDNORM | POLLHUP | POLLERR, 780 POLLWRNORM | POLLHUP | POLLERR, 781 POLLRDBAND }; 782 783 for (msk = 0; msk < 3; msk++) { 784 for (i = 0; i < nfd; i += NFDBITS) { 785 ibits = *ibitp++; 786 obits = 0; 787 while ((j = ffs(ibits)) && (fd = i + --j) < nfd) { 788 ibits &= ~(1 << j); 789 fp = fdp->fd_ofiles[fd]; 790 if (fp == NULL || 791 (fp->f_iflags & FIF_WANTCLOSE) != 0) 792 return (EBADF); 793 FILE_USE(fp); 794 if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) { 795 obits |= (1 << j); 796 n++; 797 } 798 FILE_UNUSE(fp, p); 799 } 800 *obitp++ = obits; 801 } 802 } 803 *retval = n; 804 return (0); 805 } 806 807 /* 808 * Poll system call. 809 */ 810 int 811 sys_poll(p, v, retval) 812 register struct proc *p; 813 void *v; 814 register_t *retval; 815 { 816 register struct sys_poll_args /* { 817 syscallarg(struct pollfd *) fds; 818 syscallarg(u_int) nfds; 819 syscallarg(int) timeout; 820 } */ *uap = v; 821 caddr_t bits; 822 char smallbits[32 * sizeof(struct pollfd)]; 823 struct timeval atv; 824 int s, ncoll, error = 0, timo; 825 size_t ni; 826 827 if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) { 828 /* forgiving; slightly wrong */ 829 SCARG(uap, nfds) = p->p_fd->fd_nfiles; 830 } 831 ni = SCARG(uap, nfds) * sizeof(struct pollfd); 832 if (ni > sizeof(smallbits)) 833 bits = malloc(ni, M_TEMP, M_WAITOK); 834 else 835 bits = smallbits; 836 837 error = copyin(SCARG(uap, fds), bits, ni); 838 if (error) 839 goto done; 840 841 if (SCARG(uap, timeout) != INFTIM) { 842 atv.tv_sec = SCARG(uap, timeout) / 1000; 843 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 844 if (itimerfix(&atv)) { 845 error = EINVAL; 846 goto done; 847 } 848 s = splclock(); 849 timeradd(&atv, &time, &atv); 850 timo = hzto(&atv); 851 /* 852 * Avoid inadvertently sleeping forever. 853 */ 854 if (timo == 0) 855 timo = 1; 856 splx(s); 857 } else 858 timo = 0; 859 retry: 860 ncoll = nselcoll; 861 p->p_flag |= P_SELECT; 862 error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds), retval); 863 if (error || *retval) 864 goto done; 865 s = splhigh(); 866 if (timo && timercmp(&time, &atv, >=)) { 867 splx(s); 868 goto done; 869 } 870 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 871 splx(s); 872 goto retry; 873 } 874 p->p_flag &= ~P_SELECT; 875 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 876 splx(s); 877 if (error == 0) 878 goto retry; 879 done: 880 p->p_flag &= ~P_SELECT; 881 /* poll is not restarted after signals... */ 882 if (error == ERESTART) 883 error = EINTR; 884 if (error == EWOULDBLOCK) 885 error = 0; 886 if (error == 0) { 887 error = copyout(bits, SCARG(uap, fds), ni); 888 if (error) 889 goto out; 890 } 891 out: 892 if (ni > sizeof(smallbits)) 893 free(bits, M_TEMP); 894 return (error); 895 } 896 897 int 898 pollscan(p, fds, nfd, retval) 899 struct proc *p; 900 struct pollfd *fds; 901 int nfd; 902 register_t *retval; 903 { 904 register struct filedesc *fdp = p->p_fd; 905 int i; 906 struct file *fp; 907 int n = 0; 908 909 for (i = 0; i < nfd; i++, fds++) { 910 if ((u_int)fds->fd >= fdp->fd_nfiles) { 911 fds->revents = POLLNVAL; 912 n++; 913 } else { 914 fp = fdp->fd_ofiles[fds->fd]; 915 if (fp == NULL || 916 (fp->f_iflags & FIF_WANTCLOSE) != 0) { 917 fds->revents = POLLNVAL; 918 n++; 919 } else { 920 FILE_USE(fp); 921 fds->revents = (*fp->f_ops->fo_poll)(fp, 922 fds->events | POLLERR | POLLHUP, p); 923 if (fds->revents != 0) 924 n++; 925 FILE_UNUSE(fp, p); 926 } 927 } 928 } 929 *retval = n; 930 return (0); 931 } 932 933 /*ARGSUSED*/ 934 int 935 seltrue(dev, events, p) 936 dev_t dev; 937 int events; 938 struct proc *p; 939 { 940 941 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 942 } 943 944 /* 945 * Record a select request. 946 */ 947 void 948 selrecord(selector, sip) 949 struct proc *selector; 950 struct selinfo *sip; 951 { 952 struct proc *p; 953 pid_t mypid; 954 955 mypid = selector->p_pid; 956 if (sip->si_pid == mypid) 957 return; 958 if (sip->si_pid && (p = pfind(sip->si_pid)) && 959 p->p_wchan == (caddr_t)&selwait) 960 sip->si_flags |= SI_COLL; 961 else 962 sip->si_pid = mypid; 963 } 964 965 /* 966 * Do a wakeup when a selectable event occurs. 967 */ 968 void 969 selwakeup(sip) 970 register struct selinfo *sip; 971 { 972 register struct proc *p; 973 int s; 974 975 if (sip->si_pid == 0) 976 return; 977 if (sip->si_flags & SI_COLL) { 978 nselcoll++; 979 sip->si_flags &= ~SI_COLL; 980 wakeup((caddr_t)&selwait); 981 } 982 p = pfind(sip->si_pid); 983 sip->si_pid = 0; 984 if (p != NULL) { 985 s = splhigh(); 986 if (p->p_wchan == (caddr_t)&selwait) { 987 if (p->p_stat == SSLEEP) 988 setrunnable(p); 989 else 990 unsleep(p); 991 } else if (p->p_flag & P_SELECT) 992 p->p_flag &= ~P_SELECT; 993 splx(s); 994 } 995 } 996