1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 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 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/filedesc.h> 44 #include <sys/ioctl.h> 45 #include <sys/file.h> 46 #include <sys/proc.h> 47 #include <sys/socketvar.h> 48 #include <sys/uio.h> 49 #include <sys/kernel.h> 50 #include <sys/stat.h> 51 #include <sys/malloc.h> 52 #ifdef KTRACE 53 #include <sys/ktrace.h> 54 #endif 55 56 /* 57 * Read system call. 58 */ 59 struct read_args { 60 int fd; 61 char *buf; 62 u_int nbyte; 63 }; 64 /* ARGSUSED */ 65 int 66 read(p, uap, retval) 67 struct proc *p; 68 register struct read_args *uap; 69 int *retval; 70 { 71 register struct file *fp; 72 register struct filedesc *fdp = p->p_fd; 73 struct uio auio; 74 struct iovec aiov; 75 long cnt, error = 0; 76 #ifdef KTRACE 77 struct iovec ktriov; 78 #endif 79 80 if (((u_int)uap->fd) >= fdp->fd_nfiles || 81 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 82 (fp->f_flag & FREAD) == 0) 83 return (EBADF); 84 aiov.iov_base = (caddr_t)uap->buf; 85 aiov.iov_len = uap->nbyte; 86 auio.uio_iov = &aiov; 87 auio.uio_iovcnt = 1; 88 auio.uio_resid = uap->nbyte; 89 auio.uio_rw = UIO_READ; 90 auio.uio_segflg = UIO_USERSPACE; 91 auio.uio_procp = p; 92 #ifdef KTRACE 93 /* 94 * if tracing, save a copy of iovec 95 */ 96 if (KTRPOINT(p, KTR_GENIO)) 97 ktriov = aiov; 98 #endif 99 cnt = uap->nbyte; 100 if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 101 if (auio.uio_resid != cnt && (error == ERESTART || 102 error == EINTR || error == EWOULDBLOCK)) 103 error = 0; 104 cnt -= auio.uio_resid; 105 #ifdef KTRACE 106 if (KTRPOINT(p, KTR_GENIO) && error == 0) 107 ktrgenio(p->p_tracep, uap->fd, UIO_READ, &ktriov, cnt, error); 108 #endif 109 *retval = cnt; 110 return (error); 111 } 112 113 /* 114 * Scatter read system call. 115 */ 116 struct readv_args { 117 int fdes; 118 struct iovec *iovp; 119 u_int iovcnt; 120 }; 121 int 122 readv(p, uap, retval) 123 struct proc *p; 124 register struct readv_args *uap; 125 int *retval; 126 { 127 register struct file *fp; 128 register struct filedesc *fdp = p->p_fd; 129 struct uio auio; 130 register struct iovec *iov; 131 struct iovec *needfree; 132 struct iovec aiov[UIO_SMALLIOV]; 133 long i, cnt, error = 0; 134 u_int iovlen; 135 #ifdef KTRACE 136 struct iovec *ktriov = NULL; 137 #endif 138 139 if (((u_int)uap->fdes) >= fdp->fd_nfiles || 140 (fp = fdp->fd_ofiles[uap->fdes]) == NULL || 141 (fp->f_flag & FREAD) == 0) 142 return (EBADF); 143 /* note: can't use iovlen until iovcnt is validated */ 144 iovlen = uap->iovcnt * sizeof (struct iovec); 145 if (uap->iovcnt > UIO_SMALLIOV) { 146 if (uap->iovcnt > UIO_MAXIOV) 147 return (EINVAL); 148 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 149 needfree = iov; 150 } else { 151 iov = aiov; 152 needfree = NULL; 153 } 154 auio.uio_iov = iov; 155 auio.uio_iovcnt = uap->iovcnt; 156 auio.uio_rw = UIO_READ; 157 auio.uio_segflg = UIO_USERSPACE; 158 auio.uio_procp = p; 159 if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 160 goto done; 161 auio.uio_resid = 0; 162 for (i = 0; i < uap->iovcnt; i++) { 163 auio.uio_resid += iov->iov_len; 164 if (auio.uio_resid < 0) { 165 error = EINVAL; 166 goto done; 167 } 168 iov++; 169 } 170 #ifdef KTRACE 171 /* 172 * if tracing, save a copy of iovec 173 */ 174 if (KTRPOINT(p, KTR_GENIO)) { 175 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 176 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 177 } 178 #endif 179 cnt = auio.uio_resid; 180 if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred)) 181 if (auio.uio_resid != cnt && (error == ERESTART || 182 error == EINTR || error == EWOULDBLOCK)) 183 error = 0; 184 cnt -= auio.uio_resid; 185 #ifdef KTRACE 186 if (ktriov != NULL) { 187 if (error == 0) 188 ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov, 189 cnt, error); 190 FREE(ktriov, M_TEMP); 191 } 192 #endif 193 *retval = cnt; 194 done: 195 if (needfree) 196 FREE(needfree, M_IOV); 197 return (error); 198 } 199 200 /* 201 * Write system call 202 */ 203 struct write_args { 204 int fd; 205 char *buf; 206 u_int nbyte; 207 }; 208 int 209 write(p, uap, retval) 210 struct proc *p; 211 register struct write_args *uap; 212 int *retval; 213 { 214 register struct file *fp; 215 register struct filedesc *fdp = p->p_fd; 216 struct uio auio; 217 struct iovec aiov; 218 long cnt, error = 0; 219 int i; 220 #ifdef KTRACE 221 struct iovec ktriov; 222 #endif 223 224 if (((u_int)uap->fd) >= fdp->fd_nfiles || 225 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 226 (fp->f_flag & FWRITE) == 0) 227 return (EBADF); 228 aiov.iov_base = (caddr_t)uap->buf; 229 aiov.iov_len = uap->nbyte; 230 auio.uio_iov = &aiov; 231 auio.uio_iovcnt = 1; 232 auio.uio_resid = uap->nbyte; 233 auio.uio_rw = UIO_WRITE; 234 auio.uio_segflg = UIO_USERSPACE; 235 auio.uio_procp = p; 236 #ifdef KTRACE 237 /* 238 * if tracing, save a copy of iovec 239 */ 240 if (KTRPOINT(p, KTR_GENIO)) 241 ktriov = aiov; 242 #endif 243 cnt = uap->nbyte; 244 if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 245 if (auio.uio_resid != cnt && (error == ERESTART || 246 error == EINTR || error == EWOULDBLOCK)) 247 error = 0; 248 if (error == EPIPE) 249 psignal(p, SIGPIPE); 250 } 251 cnt -= auio.uio_resid; 252 #ifdef KTRACE 253 if (KTRPOINT(p, KTR_GENIO) && error == 0) 254 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 255 &ktriov, cnt, error); 256 #endif 257 *retval = cnt; 258 return (error); 259 } 260 261 /* 262 * Gather write system call 263 */ 264 struct writev_args { 265 int fd; 266 struct iovec *iovp; 267 u_int iovcnt; 268 }; 269 int 270 writev(p, uap, retval) 271 struct proc *p; 272 register struct writev_args *uap; 273 int *retval; 274 { 275 register struct file *fp; 276 register struct filedesc *fdp = p->p_fd; 277 struct uio auio; 278 register struct iovec *iov; 279 struct iovec *needfree; 280 struct iovec aiov[UIO_SMALLIOV]; 281 long i, cnt, error = 0; 282 u_int iovlen; 283 #ifdef KTRACE 284 struct iovec *ktriov = NULL; 285 #endif 286 287 if (((u_int)uap->fd) >= fdp->fd_nfiles || 288 (fp = fdp->fd_ofiles[uap->fd]) == NULL || 289 (fp->f_flag & FWRITE) == 0) 290 return (EBADF); 291 /* note: can't use iovlen until iovcnt is validated */ 292 iovlen = uap->iovcnt * sizeof (struct iovec); 293 if (uap->iovcnt > UIO_SMALLIOV) { 294 if (uap->iovcnt > UIO_MAXIOV) 295 return (EINVAL); 296 MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); 297 needfree = iov; 298 } else { 299 iov = aiov; 300 needfree = NULL; 301 } 302 auio.uio_iov = iov; 303 auio.uio_iovcnt = uap->iovcnt; 304 auio.uio_rw = UIO_WRITE; 305 auio.uio_segflg = UIO_USERSPACE; 306 auio.uio_procp = p; 307 if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen)) 308 goto done; 309 auio.uio_resid = 0; 310 for (i = 0; i < uap->iovcnt; i++) { 311 auio.uio_resid += iov->iov_len; 312 if (auio.uio_resid < 0) { 313 error = EINVAL; 314 goto done; 315 } 316 iov++; 317 } 318 #ifdef KTRACE 319 /* 320 * if tracing, save a copy of iovec 321 */ 322 if (KTRPOINT(p, KTR_GENIO)) { 323 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); 324 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); 325 } 326 #endif 327 cnt = auio.uio_resid; 328 if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) { 329 if (auio.uio_resid != cnt && (error == ERESTART || 330 error == EINTR || error == EWOULDBLOCK)) 331 error = 0; 332 if (error == EPIPE) 333 psignal(p, SIGPIPE); 334 } 335 cnt -= auio.uio_resid; 336 #ifdef KTRACE 337 if (ktriov != NULL) { 338 if (error == 0) 339 ktrgenio(p->p_tracep, uap->fd, UIO_WRITE, 340 ktriov, cnt, error); 341 FREE(ktriov, M_TEMP); 342 } 343 #endif 344 *retval = cnt; 345 done: 346 if (needfree) 347 FREE(needfree, M_IOV); 348 return (error); 349 } 350 351 /* 352 * Ioctl system call 353 */ 354 struct ioctl_args { 355 int fd; 356 int com; 357 caddr_t data; 358 }; 359 /* ARGSUSED */ 360 int 361 ioctl(p, uap, retval) 362 struct proc *p; 363 register struct ioctl_args *uap; 364 int *retval; 365 { 366 register struct file *fp; 367 register struct filedesc *fdp; 368 register int com, error; 369 register u_int size; 370 caddr_t data, memp; 371 int tmp; 372 #define STK_PARAMS 128 373 char stkbuf[STK_PARAMS]; 374 375 fdp = p->p_fd; 376 if ((u_int)uap->fd >= fdp->fd_nfiles || 377 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 378 return (EBADF); 379 380 if ((fp->f_flag & (FREAD | FWRITE)) == 0) 381 return (EBADF); 382 383 switch (com = uap->com) { 384 case FIONCLEX: 385 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; 386 return (0); 387 case FIOCLEX: 388 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; 389 return (0); 390 } 391 392 /* 393 * Interpret high order word to find amount of data to be 394 * copied to/from the user's address space. 395 */ 396 size = IOCPARM_LEN(com); 397 if (size > IOCPARM_MAX) 398 return (ENOTTY); 399 memp = NULL; 400 if (size > sizeof (stkbuf)) { 401 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 402 data = memp; 403 } else 404 data = stkbuf; 405 if (com&IOC_IN) { 406 if (size) { 407 error = copyin(uap->data, data, (u_int)size); 408 if (error) { 409 if (memp) 410 free(memp, M_IOCTLOPS); 411 return (error); 412 } 413 } else 414 *(caddr_t *)data = uap->data; 415 } else if ((com&IOC_OUT) && size) 416 /* 417 * Zero the buffer so the user always 418 * gets back something deterministic. 419 */ 420 bzero(data, size); 421 else if (com&IOC_VOID) 422 *(caddr_t *)data = uap->data; 423 424 switch (com) { 425 426 case FIONBIO: 427 if (tmp = *(int *)data) 428 fp->f_flag |= FNONBLOCK; 429 else 430 fp->f_flag &= ~FNONBLOCK; 431 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 432 break; 433 434 case FIOASYNC: 435 if (tmp = *(int *)data) 436 fp->f_flag |= FASYNC; 437 else 438 fp->f_flag &= ~FASYNC; 439 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 440 break; 441 442 case FIOSETOWN: 443 tmp = *(int *)data; 444 if (fp->f_type == DTYPE_SOCKET) { 445 ((struct socket *)fp->f_data)->so_pgid = tmp; 446 error = 0; 447 break; 448 } 449 if (tmp <= 0) { 450 tmp = -tmp; 451 } else { 452 struct proc *p1 = pfind(tmp); 453 if (p1 == 0) { 454 error = ESRCH; 455 break; 456 } 457 tmp = p1->p_pgrp->pg_id; 458 } 459 error = (*fp->f_ops->fo_ioctl) 460 (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p); 461 break; 462 463 case FIOGETOWN: 464 if (fp->f_type == DTYPE_SOCKET) { 465 error = 0; 466 *(int *)data = ((struct socket *)fp->f_data)->so_pgid; 467 break; 468 } 469 error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p); 470 *(int *)data = -*(int *)data; 471 break; 472 473 default: 474 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p); 475 /* 476 * Copy any data to user, size was 477 * already set and checked above. 478 */ 479 if (error == 0 && (com&IOC_OUT) && size) 480 error = copyout(data, uap->data, (u_int)size); 481 break; 482 } 483 if (memp) 484 free(memp, M_IOCTLOPS); 485 return (error); 486 } 487 488 int selwait, nselcoll; 489 490 /* 491 * Select system call. 492 */ 493 struct select_args { 494 u_int nd; 495 fd_set *in, *ou, *ex; 496 struct timeval *tv; 497 }; 498 int 499 select(p, uap, retval) 500 register struct proc *p; 501 register struct select_args *uap; 502 int *retval; 503 { 504 fd_set ibits[3], obits[3]; 505 struct timeval atv; 506 int s, ncoll, error = 0, timo; 507 u_int ni; 508 509 bzero((caddr_t)ibits, sizeof(ibits)); 510 bzero((caddr_t)obits, sizeof(obits)); 511 if (uap->nd > FD_SETSIZE) 512 return (EINVAL); 513 if (uap->nd > p->p_fd->fd_nfiles) 514 uap->nd = p->p_fd->fd_nfiles; /* forgiving; slightly wrong */ 515 ni = howmany(uap->nd, NFDBITS) * sizeof(fd_mask); 516 517 #define getbits(name, x) \ 518 if (uap->name && \ 519 (error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], ni))) \ 520 goto done; 521 getbits(in, 0); 522 getbits(ou, 1); 523 getbits(ex, 2); 524 #undef getbits 525 526 if (uap->tv) { 527 error = copyin((caddr_t)uap->tv, (caddr_t)&atv, 528 sizeof (atv)); 529 if (error) 530 goto done; 531 if (itimerfix(&atv)) { 532 error = EINVAL; 533 goto done; 534 } 535 s = splclock(); 536 timevaladd(&atv, (struct timeval *)&time); 537 timo = hzto(&atv); 538 /* 539 * Avoid inadvertently sleeping forever. 540 */ 541 if (timo == 0) 542 timo = 1; 543 splx(s); 544 } else 545 timo = 0; 546 retry: 547 ncoll = nselcoll; 548 p->p_flag |= P_SELECT; 549 error = selscan(p, ibits, obits, uap->nd, retval); 550 if (error || *retval) 551 goto done; 552 s = splhigh(); 553 /* this should be timercmp(&time, &atv, >=) */ 554 if (uap->tv && (time.tv_sec > atv.tv_sec || 555 time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) { 556 splx(s); 557 goto done; 558 } 559 if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { 560 splx(s); 561 goto retry; 562 } 563 p->p_flag &= ~P_SELECT; 564 error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo); 565 splx(s); 566 if (error == 0) 567 goto retry; 568 done: 569 p->p_flag &= ~P_SELECT; 570 /* select is not restarted after signals... */ 571 if (error == ERESTART) 572 error = EINTR; 573 if (error == EWOULDBLOCK) 574 error = 0; 575 #define putbits(name, x) \ 576 if (uap->name && \ 577 (error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, ni))) \ 578 error = error2; 579 if (error == 0) { 580 int error2; 581 582 putbits(in, 0); 583 putbits(ou, 1); 584 putbits(ex, 2); 585 #undef putbits 586 } 587 return (error); 588 } 589 590 int 591 selscan(p, ibits, obits, nfd, retval) 592 struct proc *p; 593 fd_set *ibits, *obits; 594 int nfd, *retval; 595 { 596 register struct filedesc *fdp = p->p_fd; 597 register int msk, i, j, fd; 598 register fd_mask bits; 599 struct file *fp; 600 int n = 0; 601 static int flag[3] = { FREAD, FWRITE, 0 }; 602 603 for (msk = 0; msk < 3; msk++) { 604 for (i = 0; i < nfd; i += NFDBITS) { 605 bits = ibits[msk].fds_bits[i/NFDBITS]; 606 while ((j = ffs(bits)) && (fd = i + --j) < nfd) { 607 bits &= ~(1 << j); 608 fp = fdp->fd_ofiles[fd]; 609 if (fp == NULL) 610 return (EBADF); 611 if ((*fp->f_ops->fo_select)(fp, flag[msk], p)) { 612 FD_SET(fd, &obits[msk]); 613 n++; 614 } 615 } 616 } 617 } 618 *retval = n; 619 return (0); 620 } 621 622 /*ARGSUSED*/ 623 int 624 seltrue(dev, flag, p) 625 dev_t dev; 626 int flag; 627 struct proc *p; 628 { 629 630 return (1); 631 } 632 633 /* 634 * Record a select request. 635 */ 636 void 637 selrecord(selector, sip) 638 struct proc *selector; 639 struct selinfo *sip; 640 { 641 struct proc *p; 642 pid_t mypid; 643 644 mypid = selector->p_pid; 645 if (sip->si_pid == mypid) 646 return; 647 if (sip->si_pid && (p = pfind(sip->si_pid)) && 648 p->p_wchan == (caddr_t)&selwait) 649 sip->si_flags |= SI_COLL; 650 else 651 sip->si_pid = mypid; 652 } 653 654 /* 655 * Do a wakeup when a selectable event occurs. 656 */ 657 void 658 selwakeup(sip) 659 register struct selinfo *sip; 660 { 661 register struct proc *p; 662 int s; 663 664 if (sip->si_pid == 0) 665 return; 666 if (sip->si_flags & SI_COLL) { 667 nselcoll++; 668 sip->si_flags &= ~SI_COLL; 669 wakeup((caddr_t)&selwait); 670 } 671 p = pfind(sip->si_pid); 672 sip->si_pid = 0; 673 if (p != NULL) { 674 s = splhigh(); 675 if (p->p_wchan == (caddr_t)&selwait) { 676 if (p->p_stat == SSLEEP) 677 setrunnable(p); 678 else 679 unsleep(p); 680 } else if (p->p_flag & P_SELECT) 681 p->p_flag &= ~P_SELECT; 682 splx(s); 683 } 684 } 685