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