1 /* $NetBSD: sys_generic.c,v 1.34 1997/10/15 17:04:14 mycroft 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.5 (Berkeley) 1/21/94 41 */ 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/filedesc.h> 46 #include <sys/ioctl.h> 47 #include <sys/file.h> 48 #include <sys/proc.h> 49 #include <sys/socketvar.h> 50 #include <sys/signalvar.h> 51 #include <sys/uio.h> 52 #include <sys/kernel.h> 53 #include <sys/stat.h> 54 #include <sys/malloc.h> 55 #include <sys/poll.h> 56 #ifdef KTRACE 57 #include <sys/ktrace.h> 58 #endif 59 60 #include <sys/mount.h> 61 #include <sys/syscallargs.h> 62 63 int selscan __P((struct proc *, fd_mask *, fd_mask *, int, register_t *)); 64 int pollscan __P((struct proc *, struct pollfd *, int, register_t *)); 65 66 /* 67 * Read system call. 68 */ 69 /* ARGSUSED */ 70 int 71 sys_read(p, v, retval) 72 struct proc *p; 73 void *v; 74 register_t *retval; 75 { 76 register struct sys_read_args /* { 77 syscallarg(int) fd; 78 syscallarg(void *) buf; 79 syscallarg(size_t) nbyte; 80 } */ *uap = v; 81 int fd = SCARG(uap, fd); 82 register struct file *fp; 83 register struct filedesc *fdp = p->p_fd; 84 struct uio auio; 85 struct iovec aiov; 86 long cnt, error = 0; 87 #ifdef KTRACE 88 struct iovec ktriov; 89 #endif 90 91 if ((u_int)fd >= fdp->fd_nfiles || 92 (fp = fdp->fd_ofiles[fd]) == NULL || 93 (fp->f_flag & FREAD) == 0) 94 return (EBADF); 95 aiov.iov_base = (caddr_t)SCARG(uap, buf); 96 aiov.iov_len = SCARG(uap, nbyte); 97 auio.uio_iov = &aiov; 98 auio.uio_iovcnt = 1; 99 auio.uio_resid = SCARG(uap, nbyte); 100 auio.uio_rw = UIO_READ; 101 auio.uio_segflg = UIO_USERSPACE; 102 auio.uio_procp = p; 103 if (auio.uio_resid < 0) 104 return EINVAL; 105 #ifdef KTRACE 106 /* 107 * if tracing, save a copy of iovec 108 */ 109 if (KTRPOINT(p, KTR_GENIO)) 110 ktriov = aiov; 111 #endif 112 cnt = SCARG(uap, nbyte); 113 error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred); 114 if (error) 115 if (auio.uio_resid != cnt && (error == ERESTART || 116 error == EINTR || error == EWOULDBLOCK)) 117 error = 0; 118 cnt -= auio.uio_resid; 119 #ifdef KTRACE 120 if (KTRPOINT(p, KTR_GENIO) && error == 0) 121 ktrgenio(p->p_tracep, fd, UIO_READ, &ktriov, cnt, error); 122 #endif 123 *retval = cnt; 124 return (error); 125 } 126 127 /* 128 * Scatter read system call. 129 */ 130 int 131 sys_readv(p, v, retval) 132 struct proc *p; 133 void *v; 134 register_t *retval; 135 { 136 register struct sys_readv_args /* { 137 syscallarg(int) fd; 138 syscallarg(const struct iovec *) iovp; 139 syscallarg(int) iovcnt; 140 } */ *uap = v; 141 int fd = SCARG(uap, fd); 142 int iovcnt = SCARG(uap, iovcnt); 143 register struct file *fp; 144 register struct filedesc *fdp = p->p_fd; 145 struct uio auio; 146 register struct iovec *iov; 147 struct iovec *needfree; 148 struct iovec aiov[UIO_SMALLIOV]; 149 long i, cnt, error = 0; 150 u_int iovlen; 151 #ifdef KTRACE 152 struct iovec *ktriov = NULL; 153 #endif 154 155 if ((u_int)fd >= fdp->fd_nfiles || 156 (fp = fdp->fd_ofiles[fd]) == NULL || 157 (fp->f_flag & FREAD) == 0) 158 return (EBADF); 159 /* note: can't use iovlen until iovcnt is validated */ 160 iovlen = iovcnt * sizeof (struct iovec); 161 if ((u_int)iovcnt > UIO_SMALLIOV) { 162 if ((u_int)iovcnt > UIO_MAXIOV) 163 return (EINVAL); 164 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 165 needfree = iov; 166 } else { 167 iov = aiov; 168 needfree = NULL; 169 } 170 auio.uio_iov = iov; 171 auio.uio_iovcnt = iovcnt; 172 auio.uio_rw = UIO_READ; 173 auio.uio_segflg = UIO_USERSPACE; 174 auio.uio_procp = p; 175 error = copyin(SCARG(uap, iovp), iov, iovlen); 176 if (error) 177 goto done; 178 auio.uio_resid = 0; 179 for (i = 0; i < iovcnt; i++) { 180 #if 0 181 /* Cannot happen iov_len is unsigned */ 182 if (iov->iov_len < 0) { 183 error = EINVAL; 184 goto done; 185 } 186 #endif 187 auio.uio_resid += iov->iov_len; 188 if (auio.uio_resid < 0) { 189 error = EINVAL; 190 goto done; 191 } 192 iov++; 193 } 194 #ifdef KTRACE 195 /* 196 * if tracing, save a copy of iovec 197 */ 198 if (KTRPOINT(p, KTR_GENIO)) { 199 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 200 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 201 } 202 #endif 203 cnt = auio.uio_resid; 204 error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred); 205 if (error) 206 if (auio.uio_resid != cnt && (error == ERESTART || 207 error == EINTR || error == EWOULDBLOCK)) 208 error = 0; 209 cnt -= auio.uio_resid; 210 #ifdef KTRACE 211 if (KTRPOINT(p, KTR_GENIO)) 212 if (error == 0) { 213 ktrgenio(p->p_tracep, fd, UIO_READ, ktriov, cnt, 214 error); 215 FREE(ktriov, M_TEMP); 216 } 217 #endif 218 *retval = cnt; 219 done: 220 if (needfree) 221 FREE(needfree, M_IOV); 222 return (error); 223 } 224 225 /* 226 * Write system call 227 */ 228 int 229 sys_write(p, v, retval) 230 struct proc *p; 231 void *v; 232 register_t *retval; 233 { 234 register struct sys_write_args /* { 235 syscallarg(int) fd; 236 syscallarg(const void *) buf; 237 syscallarg(size_t) nbyte; 238 } */ *uap = v; 239 int fd = SCARG(uap, fd); 240 register struct file *fp; 241 register struct filedesc *fdp = p->p_fd; 242 struct uio auio; 243 struct iovec aiov; 244 long cnt, error = 0; 245 #ifdef KTRACE 246 struct iovec ktriov; 247 #endif 248 249 if ((u_int)fd >= fdp->fd_nfiles || 250 (fp = fdp->fd_ofiles[fd]) == NULL || 251 (fp->f_flag & FWRITE) == 0) 252 return (EBADF); 253 aiov.iov_base = (char *)SCARG(uap, buf); /* XXX kills const */ 254 aiov.iov_len = SCARG(uap, nbyte); 255 auio.uio_iov = &aiov; 256 auio.uio_iovcnt = 1; 257 auio.uio_resid = SCARG(uap, nbyte); 258 auio.uio_rw = UIO_WRITE; 259 auio.uio_segflg = UIO_USERSPACE; 260 auio.uio_procp = p; 261 if (auio.uio_resid < 0) 262 return EINVAL; 263 #ifdef KTRACE 264 /* 265 * if tracing, save a copy of iovec 266 */ 267 if (KTRPOINT(p, KTR_GENIO)) 268 ktriov = aiov; 269 #endif 270 cnt = SCARG(uap, nbyte); 271 error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred); 272 if (error) { 273 if (auio.uio_resid != cnt && (error == ERESTART || 274 error == EINTR || error == EWOULDBLOCK)) 275 error = 0; 276 if (error == EPIPE) 277 psignal(p, SIGPIPE); 278 } 279 cnt -= auio.uio_resid; 280 #ifdef KTRACE 281 if (KTRPOINT(p, KTR_GENIO) && error == 0) 282 ktrgenio(p->p_tracep, fd, UIO_WRITE, &ktriov, cnt, error); 283 #endif 284 *retval = cnt; 285 return (error); 286 } 287 288 /* 289 * Gather write system call 290 */ 291 int 292 sys_writev(p, v, retval) 293 struct proc *p; 294 void *v; 295 register_t *retval; 296 { 297 register struct sys_writev_args /* { 298 syscallarg(int) fd; 299 syscallarg(const struct iovec *) iovp; 300 syscallarg(u_int) iovcnt; 301 } */ *uap = v; 302 int fd = SCARG(uap, fd); 303 int iovcnt = SCARG(uap, iovcnt); 304 register struct file *fp; 305 register struct filedesc *fdp = p->p_fd; 306 struct uio auio; 307 register struct iovec *iov; 308 struct iovec *needfree; 309 struct iovec aiov[UIO_SMALLIOV]; 310 long i, cnt, error = 0; 311 u_int iovlen; 312 #ifdef KTRACE 313 struct iovec *ktriov = NULL; 314 #endif 315 316 if ((u_int)fd >= fdp->fd_nfiles || 317 (fp = fdp->fd_ofiles[fd]) == NULL || 318 (fp->f_flag & FWRITE) == 0) 319 return (EBADF); 320 /* note: can't use iovlen until iovcnt is validated */ 321 iovlen = iovcnt * sizeof (struct iovec); 322 if ((u_int)iovcnt > UIO_SMALLIOV) { 323 if ((u_int)iovcnt > UIO_MAXIOV) 324 return (EINVAL); 325 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 326 needfree = iov; 327 } else { 328 iov = aiov; 329 needfree = NULL; 330 } 331 auio.uio_iov = iov; 332 auio.uio_iovcnt = iovcnt; 333 auio.uio_rw = UIO_WRITE; 334 auio.uio_segflg = UIO_USERSPACE; 335 auio.uio_procp = p; 336 error = copyin(SCARG(uap, iovp), iov, iovlen); 337 if (error) 338 goto done; 339 auio.uio_resid = 0; 340 for (i = 0; i < iovcnt; i++) { 341 #if 0 342 /* Cannot happen iov_len is unsigned */ 343 if (iov->iov_len < 0) { 344 error = EINVAL; 345 goto done; 346 } 347 #endif 348 auio.uio_resid += iov->iov_len; 349 if (auio.uio_resid < 0) { 350 error = EINVAL; 351 goto done; 352 } 353 iov++; 354 } 355 #ifdef KTRACE 356 /* 357 * if tracing, save a copy of iovec 358 */ 359 if (KTRPOINT(p, KTR_GENIO)) { 360 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 361 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 362 } 363 #endif 364 cnt = auio.uio_resid; 365 error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred); 366 if (error) { 367 if (auio.uio_resid != cnt && (error == ERESTART || 368 error == EINTR || error == EWOULDBLOCK)) 369 error = 0; 370 if (error == EPIPE) 371 psignal(p, SIGPIPE); 372 } 373 cnt -= auio.uio_resid; 374 #ifdef KTRACE 375 if (KTRPOINT(p, KTR_GENIO)) 376 if (error == 0) { 377 ktrgenio(p->p_tracep, fd, UIO_WRITE, ktriov, cnt, 378 error); 379 FREE(ktriov, M_TEMP); 380 } 381 #endif 382 *retval = cnt; 383 done: 384 if (needfree) 385 FREE(needfree, M_IOV); 386 return (error); 387 } 388 389 /* 390 * Ioctl system call 391 */ 392 /* ARGSUSED */ 393 int 394 sys_ioctl(p, v, retval) 395 struct proc *p; 396 void *v; 397 register_t *retval; 398 { 399 register struct sys_ioctl_args /* { 400 syscallarg(int) fd; 401 syscallarg(u_long) com; 402 syscallarg(caddr_t) data; 403 } */ *uap = v; 404 register struct file *fp; 405 register struct filedesc *fdp; 406 register u_long com; 407 register int error; 408 register u_int size; 409 caddr_t data, memp; 410 int tmp; 411 #define STK_PARAMS 128 412 char stkbuf[STK_PARAMS]; 413 414 fdp = p->p_fd; 415 if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles || 416 (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL) 417 return (EBADF); 418 419 if ((fp->f_flag & (FREAD | FWRITE)) == 0) 420 return (EBADF); 421 422 switch (com = SCARG(uap, com)) { 423 case FIONCLEX: 424 fdp->fd_ofileflags[SCARG(uap, fd)] &= ~UF_EXCLOSE; 425 return (0); 426 case FIOCLEX: 427 fdp->fd_ofileflags[SCARG(uap, fd)] |= UF_EXCLOSE; 428 return (0); 429 } 430 431 /* 432 * Interpret high order word to find amount of data to be 433 * copied to/from the user's address space. 434 */ 435 size = IOCPARM_LEN(com); 436 if (size > IOCPARM_MAX) 437 return (ENOTTY); 438 memp = NULL; 439 if (size > sizeof (stkbuf)) { 440 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 441 data = memp; 442 } else 443 data = stkbuf; 444 if (com&IOC_IN) { 445 if (size) { 446 error = copyin(SCARG(uap, data), data, size); 447 if (error) { 448 if (memp) 449 free(memp, M_IOCTLOPS); 450 return (error); 451 } 452 } else 453 *(caddr_t *)data = SCARG(uap, data); 454 } else if ((com&IOC_OUT) && size) 455 /* 456 * Zero the buffer so the user always 457 * gets back something deterministic. 458 */ 459 bzero(data, size); 460 else if (com&IOC_VOID) 461 *(caddr_t *)data = SCARG(uap, data); 462 463 switch (com) { 464 465 case FIONBIO: 466 if ((tmp = *(int *)data) != 0) 467 fp->f_flag |= FNONBLOCK; 468 else 469 fp->f_flag &= ~FNONBLOCK; 470 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 471 break; 472 473 case FIOASYNC: 474 if ((tmp = *(int *)data) != 0) 475 fp->f_flag |= FASYNC; 476 else 477 fp->f_flag &= ~FASYNC; 478 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 479 break; 480 481 case FIOSETOWN: 482 tmp = *(int *)data; 483 if (fp->f_type == DTYPE_SOCKET) { 484 ((struct socket *)fp->f_data)->so_pgid = tmp; 485 error = 0; 486 break; 487 } 488 if (tmp <= 0) { 489 tmp = -tmp; 490 } else { 491 struct proc *p1 = pfind(tmp); 492 if (p1 == 0) { 493 error = ESRCH; 494 break; 495 } 496 tmp = p1->p_pgrp->pg_id; 497 } 498 error = (*fp->f_ops->fo_ioctl) 499 (fp, TIOCSPGRP, (caddr_t)&tmp, p); 500 break; 501 502 case FIOGETOWN: 503 if (fp->f_type == DTYPE_SOCKET) { 504 error = 0; 505 *(int *)data = ((struct socket *)fp->f_data)->so_pgid; 506 break; 507 } 508 error = (*fp->f_ops->fo_ioctl)(fp, TIOCGPGRP, data, p); 509 *(int *)data = -*(int *)data; 510 break; 511 512 default: 513 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 514 /* 515 * Copy any data to user, size was 516 * already set and checked above. 517 */ 518 if (error == 0 && (com&IOC_OUT) && size) 519 error = copyout(data, SCARG(uap, data), size); 520 break; 521 } 522 if (memp) 523 free(memp, M_IOCTLOPS); 524 return (error); 525 } 526 527 int selwait, nselcoll; 528 529 /* 530 * Select system call. 531 */ 532 int 533 sys_select(p, v, retval) 534 register struct proc *p; 535 void *v; 536 register_t *retval; 537 { 538 register struct sys_select_args /* { 539 syscallarg(u_int) nd; 540 syscallarg(fd_set *) in; 541 syscallarg(fd_set *) ou; 542 syscallarg(fd_set *) ex; 543 syscallarg(struct timeval *) tv; 544 } */ *uap = v; 545 caddr_t bits; 546 char smallbits[howmany(FD_SETSIZE, NFDBITS) * sizeof(fd_mask) * 6]; 547 struct timeval atv; 548 int s, ncoll, error = 0, timo; 549 size_t ni; 550 551 if (SCARG(uap, nd) > p->p_fd->fd_nfiles) { 552 /* forgiving; slightly wrong */ 553 SCARG(uap, nd) = p->p_fd->fd_nfiles; 554 } 555 ni = howmany(SCARG(uap, nd), NFDBITS) * sizeof(fd_mask); 556 if (ni * 6 > sizeof(smallbits)) 557 bits = malloc(ni * 6, M_TEMP, M_WAITOK); 558 else 559 bits = smallbits; 560 561 #define getbits(name, x) \ 562 if (SCARG(uap, name)) { \ 563 error = copyin(SCARG(uap, name), bits + ni * x, ni); \ 564 if (error) \ 565 goto done; \ 566 } else \ 567 bzero(bits + ni * x, ni); 568 getbits(in, 0); 569 getbits(ou, 1); 570 getbits(ex, 2); 571 #undef getbits 572 573 if (SCARG(uap, tv)) { 574 error = copyin(SCARG(uap, tv), (caddr_t)&atv, 575 sizeof (atv)); 576 if (error) 577 goto done; 578 if (itimerfix(&atv)) { 579 error = EINVAL; 580 goto done; 581 } 582 s = splclock(); 583 timeradd(&atv, &time, &atv); 584 timo = hzto(&atv); 585 /* 586 * Avoid inadvertently sleeping forever. 587 */ 588 if (timo == 0) 589 timo = 1; 590 splx(s); 591 } else 592 timo = 0; 593 retry: 594 ncoll = nselcoll; 595 p->p_flag |= P_SELECT; 596 error = selscan(p, (fd_mask *)(bits + ni * 0), 597 (fd_mask *)(bits + ni * 3), SCARG(uap, nd), retval); 598 if (error || *retval) 599 goto done; 600 s = splhigh(); 601 if (timo && timercmp(&time, &atv, >=)) { 602 splx(s); 603 goto done; 604 } 605 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 606 splx(s); 607 goto retry; 608 } 609 p->p_flag &= ~P_SELECT; 610 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 611 splx(s); 612 if (error == 0) 613 goto retry; 614 done: 615 p->p_flag &= ~P_SELECT; 616 /* select is not restarted after signals... */ 617 if (error == ERESTART) 618 error = EINTR; 619 if (error == EWOULDBLOCK) 620 error = 0; 621 if (error == 0) { 622 #define putbits(name, x) \ 623 if (SCARG(uap, name)) { \ 624 error = copyout(bits + ni * x, SCARG(uap, name), ni); \ 625 if (error) \ 626 goto out; \ 627 } 628 putbits(in, 3); 629 putbits(ou, 4); 630 putbits(ex, 5); 631 #undef putbits 632 } 633 out: 634 if (ni * 6 > sizeof(smallbits)) 635 free(bits, M_TEMP); 636 return (error); 637 } 638 639 int 640 selscan(p, ibitp, obitp, nfd, retval) 641 struct proc *p; 642 fd_mask *ibitp, *obitp; 643 int nfd; 644 register_t *retval; 645 { 646 register struct filedesc *fdp = p->p_fd; 647 register int msk, i, j, fd; 648 register fd_mask ibits, obits; 649 struct file *fp; 650 int n = 0; 651 static int flag[3] = { POLLRDNORM | POLLHUP | POLLERR, 652 POLLWRNORM | POLLHUP | POLLERR, 653 POLLRDBAND }; 654 655 for (msk = 0; msk < 3; msk++) { 656 for (i = 0; i < nfd; i += NFDBITS) { 657 ibits = *ibitp++; 658 obits = 0; 659 while ((j = ffs(ibits)) && (fd = i + --j) < nfd) { 660 ibits &= ~(1 << j); 661 fp = fdp->fd_ofiles[fd]; 662 if (fp == NULL) 663 return (EBADF); 664 if ((*fp->f_ops->fo_poll)(fp, flag[msk], p)) { 665 obits |= (1 << j); 666 n++; 667 } 668 } 669 *obitp++ = obits; 670 } 671 } 672 *retval = n; 673 return (0); 674 } 675 676 /* 677 * Poll system call. 678 */ 679 int 680 sys_poll(p, v, retval) 681 register struct proc *p; 682 void *v; 683 register_t *retval; 684 { 685 register struct sys_poll_args /* { 686 syscallarg(struct pollfd *) fds; 687 syscallarg(u_int) nfds; 688 syscallarg(int) timeout; 689 } */ *uap = v; 690 caddr_t bits; 691 char smallbits[32 * sizeof(struct pollfd)]; 692 struct timeval atv; 693 int s, ncoll, error = 0, timo; 694 size_t ni; 695 696 if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) { 697 /* forgiving; slightly wrong */ 698 SCARG(uap, nfds) = p->p_fd->fd_nfiles; 699 } 700 ni = SCARG(uap, nfds) * sizeof(struct pollfd); 701 if (ni > sizeof(smallbits)) 702 bits = malloc(ni, M_TEMP, M_WAITOK); 703 else 704 bits = smallbits; 705 706 error = copyin(SCARG(uap, fds), bits, ni); 707 if (error) 708 goto done; 709 710 if (SCARG(uap, timeout) != INFTIM) { 711 atv.tv_sec = SCARG(uap, timeout) / 1000; 712 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 713 if (itimerfix(&atv)) { 714 error = EINVAL; 715 goto done; 716 } 717 s = splclock(); 718 timeradd(&atv, &time, &atv); 719 timo = hzto(&atv); 720 /* 721 * Avoid inadvertently sleeping forever. 722 */ 723 if (timo == 0) 724 timo = 1; 725 splx(s); 726 } else 727 timo = 0; 728 retry: 729 ncoll = nselcoll; 730 p->p_flag |= P_SELECT; 731 error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds), retval); 732 if (error || *retval) 733 goto done; 734 s = splhigh(); 735 if (timo && timercmp(&time, &atv, >=)) { 736 splx(s); 737 goto done; 738 } 739 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 740 splx(s); 741 goto retry; 742 } 743 p->p_flag &= ~P_SELECT; 744 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 745 splx(s); 746 if (error == 0) 747 goto retry; 748 done: 749 p->p_flag &= ~P_SELECT; 750 /* poll is not restarted after signals... */ 751 if (error == ERESTART) 752 error = EINTR; 753 if (error == EWOULDBLOCK) 754 error = 0; 755 if (error == 0) { 756 error = copyout(bits, SCARG(uap, fds), ni); 757 if (error) 758 goto out; 759 } 760 out: 761 if (ni > sizeof(smallbits)) 762 free(bits, M_TEMP); 763 return (error); 764 } 765 766 int 767 pollscan(p, fds, nfd, retval) 768 struct proc *p; 769 struct pollfd *fds; 770 int nfd; 771 register_t *retval; 772 { 773 register struct filedesc *fdp = p->p_fd; 774 int i; 775 struct file *fp; 776 int n = 0; 777 778 for (i = 0; i < nfd; i++, fds++) { 779 if ((u_int)fds->fd >= fdp->fd_nfiles) { 780 fds->revents = POLLNVAL; 781 n++; 782 } else { 783 fp = fdp->fd_ofiles[fds->fd]; 784 if (fp == 0) { 785 fds->revents = POLLNVAL; 786 n++; 787 } else { 788 fds->revents = (*fp->f_ops->fo_poll)(fp, 789 fds->events | POLLERR | POLLHUP, p); 790 if (fds->revents != 0) 791 n++; 792 } 793 } 794 } 795 *retval = n; 796 return (0); 797 } 798 799 /*ARGSUSED*/ 800 int 801 seltrue(dev, events, p) 802 dev_t dev; 803 int events; 804 struct proc *p; 805 { 806 807 return (events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); 808 } 809 810 /* 811 * Record a select request. 812 */ 813 void 814 selrecord(selector, sip) 815 struct proc *selector; 816 struct selinfo *sip; 817 { 818 struct proc *p; 819 pid_t mypid; 820 821 mypid = selector->p_pid; 822 if (sip->si_pid == mypid) 823 return; 824 if (sip->si_pid && (p = pfind(sip->si_pid)) && 825 p->p_wchan == (caddr_t)&selwait) 826 sip->si_flags |= SI_COLL; 827 else 828 sip->si_pid = mypid; 829 } 830 831 /* 832 * Do a wakeup when a selectable event occurs. 833 */ 834 void 835 selwakeup(sip) 836 register struct selinfo *sip; 837 { 838 register struct proc *p; 839 int s; 840 841 if (sip->si_pid == 0) 842 return; 843 if (sip->si_flags & SI_COLL) { 844 nselcoll++; 845 sip->si_flags &= ~SI_COLL; 846 wakeup((caddr_t)&selwait); 847 } 848 p = pfind(sip->si_pid); 849 sip->si_pid = 0; 850 if (p != NULL) { 851 s = splhigh(); 852 if (p->p_wchan == (caddr_t)&selwait) { 853 if (p->p_stat == SSLEEP) 854 setrunnable(p); 855 else 856 unsleep(p); 857 } else if (p->p_flag & P_SELECT) 858 p->p_flag &= ~P_SELECT; 859 splx(s); 860 } 861 } 862