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