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