1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)sys_generic.c 1.8 (2.11BSD) 2000/2/28 7: */ 8: 9: #include "param.h" 10: #include "../machine/seg.h" 11: 12: #include "user.h" 13: #include "proc.h" 14: #include "signalvar.h" 15: #include "inode.h" 16: #include "file.h" 17: #include "ioctl.h" 18: #include "conf.h" 19: #include "uio.h" 20: #include "pty.h" 21: #include "kernel.h" 22: #include "systm.h" 23: 24: /* 25: * this is consolidated here rather than being scattered all over the 26: * place. the socketops table has to be in kernel space, but since 27: * networking might not be defined an appropriate error has to be set 28: */ 29: 30: int sorw(), soctl(), sosel(), socls(); 31: struct fileops socketops = 32: { sorw, soctl, sosel, socls }; 33: extern struct fileops inodeops, pipeops; 34: struct fileops *Fops[] = { NULL, &inodeops, &socketops, &pipeops }; 35: 36: /* 37: * Read system call. 38: */ 39: read() 40: { 41: register struct a { 42: int fdes; 43: char *cbuf; 44: unsigned count; 45: } *uap = (struct a *)u.u_ap; 46: struct uio auio; 47: struct iovec aiov; 48: 49: aiov.iov_base = (caddr_t)uap->cbuf; 50: aiov.iov_len = uap->count; 51: auio.uio_iov = &aiov; 52: auio.uio_iovcnt = 1; 53: auio.uio_rw = UIO_READ; 54: rwuio(&auio); 55: } 56: 57: readv() 58: { 59: register struct a { 60: int fdes; 61: struct iovec *iovp; 62: unsigned iovcnt; 63: } *uap = (struct a *)u.u_ap; 64: struct uio auio; 65: struct iovec aiov[16]; /* XXX */ 66: 67: if (uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) { 68: u.u_error = EINVAL; 69: return; 70: } 71: auio.uio_iov = aiov; 72: auio.uio_iovcnt = uap->iovcnt; 73: auio.uio_rw = UIO_READ; 74: u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov, 75: uap->iovcnt * sizeof (struct iovec)); 76: if (u.u_error) 77: return; 78: rwuio(&auio); 79: } 80: 81: /* 82: * Write system call 83: */ 84: write() 85: { 86: register struct a { 87: int fdes; 88: char *cbuf; 89: unsigned count; 90: } *uap = (struct a *)u.u_ap; 91: struct uio auio; 92: struct iovec aiov; 93: 94: auio.uio_iov = &aiov; 95: auio.uio_iovcnt = 1; 96: auio.uio_rw = UIO_WRITE; 97: aiov.iov_base = uap->cbuf; 98: aiov.iov_len = uap->count; 99: rwuio(&auio); 100: } 101: 102: writev() 103: { 104: register struct a { 105: int fdes; 106: struct iovec *iovp; 107: unsigned iovcnt; 108: } *uap = (struct a *)u.u_ap; 109: struct uio auio; 110: struct iovec aiov[16]; /* XXX */ 111: 112: if (uap->iovcnt > sizeof(aiov)/sizeof(aiov[0])) { 113: u.u_error = EINVAL; 114: return; 115: } 116: auio.uio_iov = aiov; 117: auio.uio_iovcnt = uap->iovcnt; 118: auio.uio_rw = UIO_WRITE; 119: u.u_error = copyin((caddr_t)uap->iovp, (caddr_t)aiov, 120: uap->iovcnt * sizeof (struct iovec)); 121: if (u.u_error) 122: return; 123: rwuio(&auio); 124: } 125: 126: static 127: rwuio(uio) 128: register struct uio *uio; 129: { 130: struct a { 131: int fdes; 132: }; 133: register struct file *fp; 134: register struct iovec *iov; 135: u_int i, count; 136: off_t total; 137: 138: GETF(fp, ((struct a *)u.u_ap)->fdes); 139: if ((fp->f_flag & (uio->uio_rw == UIO_READ ? FREAD : FWRITE)) == 0) { 140: u.u_error = EBADF; 141: return; 142: } 143: total =(off_t)0; 144: uio->uio_resid = 0; 145: uio->uio_segflg = UIO_USERSPACE; 146: for (iov = uio->uio_iov, i = 0; i < uio->uio_iovcnt; i++, iov++) 147: total += iov->iov_len; 148: 149: uio->uio_resid = total; 150: if (uio->uio_resid != total) /* check wraparound */ 151: return(u.u_error = EINVAL); 152: 153: count = uio->uio_resid; 154: if (setjmp(&u.u_qsave)) 155: { 156: /* 157: * The ONLY way we can get here is via the longjump in sleep. Thus signals 158: * have been checked and u_error set accordingly. If no bytes have been 159: * transferred then all that needs to be done now is 'return'; the system 160: * call will either be restarted or reported as interrupted. If bytes have 161: * been transferred then we need to calculate the number of bytes transferred. 162: */ 163: if (uio->uio_resid == count) 164: return; 165: else 166: u.u_error = 0; 167: } 168: else 169: u.u_error = (*Fops[fp->f_type]->fo_rw)(fp, uio); 170: u.u_r.r_val1 = count - uio->uio_resid; 171: } 172: 173: /* 174: * Ioctl system call 175: */ 176: ioctl() 177: { 178: register struct file *fp; 179: register struct a { 180: int fdes; 181: long cmd; 182: caddr_t cmarg; 183: } *uap; 184: long com; 185: u_int k_com; 186: register u_int size; 187: char data[IOCPARM_MASK+1]; 188: 189: uap = (struct a *)u.u_ap; 190: if ((fp = getf(uap->fdes)) == NULL) 191: return; 192: if ((fp->f_flag & (FREAD|FWRITE)) == 0) { 193: u.u_error = EBADF; 194: return; 195: } 196: com = uap->cmd; 197: 198: /* THE 2.11 KERNEL STILL THINKS THAT IOCTL COMMANDS ARE 16 BITS */ 199: k_com = (u_int)com; 200: 201: if (k_com == FIOCLEX) { 202: u.u_pofile[uap->fdes] |= UF_EXCLOSE; 203: return; 204: } 205: if (k_com == FIONCLEX) { 206: u.u_pofile[uap->fdes] &= ~UF_EXCLOSE; 207: return; 208: } 209: 210: /* 211: * Interpret high order word to find 212: * amount of data to be copied to/from the 213: * user's address space. 214: */ 215: size = (com &~ (IOC_INOUT|IOC_VOID)) >> 16; 216: if (size > sizeof (data)) { 217: u.u_error = EFAULT; 218: return; 219: } 220: if (com&IOC_IN) { 221: if (size) { 222: if (((u_int)uap->cmarg|size)&1) 223: u.u_error = 224: vcopyin(uap->cmarg, (caddr_t)data, size); 225: else 226: u.u_error = 227: copyin(uap->cmarg, (caddr_t)data, size); 228: if (u.u_error) 229: return; 230: } else 231: *(caddr_t *)data = uap->cmarg; 232: } else if ((com&IOC_OUT) && size) 233: /* 234: * Zero the buffer on the stack so the user 235: * always gets back something deterministic. 236: */ 237: bzero((caddr_t)data, size); 238: else if (com&IOC_VOID) 239: *(caddr_t *)data = uap->cmarg; 240: 241: switch (k_com) { 242: 243: case FIONBIO: 244: u.u_error = fset(fp, FNONBLOCK, *(int *)data); 245: return; 246: 247: case FIOASYNC: 248: u.u_error = fset(fp, FASYNC, *(int *)data); 249: return; 250: 251: case FIOSETOWN: 252: u.u_error = fsetown(fp, *(int *)data); 253: return; 254: 255: case FIOGETOWN: 256: u.u_error = fgetown(fp, (int *)data); 257: return; 258: } 259: u.u_error = (*Fops[fp->f_type]->fo_ioctl)(fp, k_com, data); 260: /* 261: * Copy any data to user, size was 262: * already set and checked above. 263: */ 264: if (u.u_error == 0 && (com&IOC_OUT) && size) 265: if (((u_int)uap->cmarg|size)&1) 266: u.u_error = vcopyout(data, uap->cmarg, size); 267: else 268: u.u_error = copyout(data, uap->cmarg, size); 269: } 270: 271: int nselcoll; 272: 273: struct pselect_args 274: { 275: int nd; 276: fd_set *in; 277: fd_set *ou; 278: fd_set *ex; 279: struct timespec *ts; 280: sigset_t *maskp; 281: }; 282: 283: /* 284: * Select system call. 285: */ 286: int 287: select() 288: { 289: struct uap 290: { 291: int nd; 292: fd_set *in, *ou, *ex; 293: struct timeval *tv; 294: } *uap = (struct uap *)u.u_ap; 295: register struct pselect_args *pselargs = (struct pselect_args *)uap; 296: 297: /* 298: * Fake the 6th parameter of pselect. See the comment below about the 299: * number of parameters! 300: */ 301: pselargs->maskp = 0; 302: return(u.u_error = select1(pselargs, 0)); 303: } 304: 305: /* 306: * pselect (posix select) 307: * 308: * N.B. There is only room for 6 arguments - see user.h - so pselect() is 309: * at the maximum! See user.h 310: */ 311: int 312: pselect() 313: { 314: register struct pselect_args *uap = (struct pselect_args *)u.u_ap; 315: 316: return(u.u_error = select1(uap, 1)); 317: } 318: 319: /* 320: * Select helper function common to both select() and pselect() 321: */ 322: static int 323: select1(uap, is_pselect) 324: register struct pselect_args *uap; 325: int is_pselect; 326: { 327: fd_set ibits[3], obits[3]; 328: struct timeval atv; 329: sigset_t sigmsk; 330: unsigned int timo = 0; 331: register int error, ni; 332: int ncoll, s; 333: 334: bzero((caddr_t)ibits, sizeof(ibits)); 335: bzero((caddr_t)obits, sizeof(obits)); 336: if (uap->nd > NOFILE) 337: uap->nd = NOFILE; /* forgiving, if slightly wrong */ 338: ni = howmany(uap->nd, NFDBITS); 339: 340: #define getbits(name, x) \ 341: if (uap->name) { \ 342: error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \ 343: (unsigned)(ni * sizeof(fd_mask))); \ 344: if (error) \ 345: goto done; \ 346: } 347: getbits(in, 0); 348: getbits(ou, 1); 349: getbits(ex, 2); 350: #undef getbits 351: 352: if (uap->maskp) 353: { 354: error = copyin(uap->maskp, &sigmsk, sizeof(sigmsk)); 355: sigmsk &= ~sigcantmask; 356: if (error) 357: goto done; 358: } 359: if (uap->ts) 360: { 361: error = copyin((caddr_t)uap->ts, (caddr_t)&atv, sizeof (atv)); 362: if (error) 363: goto done; 364: /* 365: * nanoseconds ('struct timespec') on a PDP-11 are stupid since a 50 or 60 hz 366: * clock is all we have. Keeping the names and logic made porting easier 367: * though. 368: */ 369: if (is_pselect) 370: { 371: struct timespec *ts = (struct timespec *)&atv; 372: 373: if (ts->tv_sec == 0 && ts->tv_nsec < 1000) 374: atv.tv_usec = 1; 375: else 376: atv.tv_usec = ts->tv_nsec / 1000; 377: } 378: if (itimerfix(&atv)) 379: { 380: error = EINVAL; 381: goto done; 382: } 383: s = splhigh(); 384: time.tv_usec = lbolt * mshz; 385: timevaladd(&atv, &time); 386: splx(s); 387: } 388: retry: 389: ncoll = nselcoll; 390: u.u_procp->p_flag |= P_SELECT; 391: error = selscan(ibits, obits, uap->nd, &u.u_r.r_val1); 392: if (error || u.u_r.r_val1) 393: goto done; 394: s = splhigh(); 395: if (uap->ts) 396: { 397: /* this should be timercmp(&time, &atv, >=) */ 398: if ((time.tv_sec > atv.tv_sec || (time.tv_sec == atv.tv_sec 399: && lbolt * mshz >= atv.tv_usec))) 400: { 401: splx(s); 402: goto done; 403: } 404: timo = hzto(&atv); 405: if (timo == 0) 406: timo = 1; 407: } 408: if ((u.u_procp->p_flag & P_SELECT) == 0 || nselcoll != ncoll) 409: { 410: u.u_procp->p_flag &= ~P_SELECT; 411: splx(s); 412: goto retry; 413: } 414: u.u_procp->p_flag &= ~P_SELECT; 415: /* 416: * If doing a pselect() need to set a temporary mask while in tsleep. 417: * Returning from pselect after catching a signal the old mask has to be 418: * restored. Save it here and set the appropriate flag. 419: */ 420: if (uap->maskp) 421: { 422: u.u_oldmask = u.u_procp->p_sigmask; 423: u.u_psflags |= SAS_OLDMASK; 424: u.u_procp->p_sigmask = sigmsk; 425: } 426: error = tsleep(&selwait, PSOCK | PCATCH, timo); 427: if (uap->maskp) 428: u.u_procp->p_sigmask = u.u_oldmask; 429: splx(s); 430: if (error == 0) 431: goto retry; 432: done: 433: u.u_procp->p_flag &= ~P_SELECT; 434: /* select is not restarted after signals... */ 435: if (error == ERESTART) 436: error = EINTR; 437: if (error == EWOULDBLOCK) 438: error = 0; 439: #define putbits(name, x) \ 440: if (uap->name && \ 441: (error2 = copyout(&obits[x],uap->name,(ni*sizeof(fd_mask))))) \ 442: error = error2; 443: 444: if (error == 0) 445: { 446: int error2; 447: 448: putbits(in, 0); 449: putbits(ou, 1); 450: putbits(ex, 2); 451: #undef putbits 452: } 453: return(error); 454: } 455: 456: selscan(ibits, obits, nfd, retval) 457: fd_set *ibits, *obits; 458: int nfd, *retval; 459: { 460: register int i, j, flag; 461: fd_mask bits; 462: struct file *fp; 463: int which, n = 0; 464: 465: for (which = 0; which < 3; which++) { 466: switch (which) { 467: 468: case 0: 469: flag = FREAD; break; 470: 471: case 1: 472: flag = FWRITE; break; 473: 474: case 2: 475: flag = 0; break; 476: } 477: for (i = 0; i < nfd; i += NFDBITS) { 478: bits = ibits[which].fds_bits[i/NFDBITS]; 479: while ((j = ffs(bits)) && i + --j < nfd) { 480: bits &= ~(1L << j); 481: fp = u.u_ofile[i + j]; 482: if (fp == NULL) 483: return(EBADF); 484: if ((*Fops[fp->f_type]->fo_select)(fp,flag)) { 485: FD_SET(i + j, &obits[which]); 486: n++; 487: } 488: } 489: } 490: } 491: *retval = n; 492: return(0); 493: } 494: 495: /*ARGSUSED*/ 496: seltrue(dev, flag) 497: dev_t dev; 498: int flag; 499: { 500: 501: return (1); 502: } 503: 504: selwakeup(p, coll) 505: register struct proc *p; 506: long coll; 507: { 508: mapinfo map; 509: 510: savemap(map); 511: if (coll) { 512: nselcoll++; 513: wakeup((caddr_t)&selwait); 514: } 515: if (p) { 516: register int s = splhigh(); 517: if (p->p_wchan == (caddr_t)&selwait) { 518: if (p->p_stat == SSLEEP) 519: setrun(p); 520: else 521: unsleep(p); 522: } else if (p->p_flag & P_SELECT) 523: p->p_flag &= ~P_SELECT; 524: splx(s); 525: } 526: restormap(map); 527: } 528: 529: sorw(fp, uio) 530: register struct file *fp; 531: register struct uio *uio; 532: { 533: #ifdef INET 534: if (uio->uio_rw == UIO_READ) 535: return(SORECEIVE((struct socket *)fp->f_socket, 0, uio, 0, 0)); 536: return(SOSEND((struct socket *)fp->f_socket, 0, uio, 0, 0)); 537: #else 538: return (EOPNOTSUPP); 539: #endif 540: } 541: 542: soctl(fp, com, data) 543: struct file *fp; 544: u_int com; 545: char *data; 546: { 547: #ifdef INET 548: return (SOO_IOCTL(fp, com, data)); 549: #else 550: return (EOPNOTSUPP); 551: #endif 552: } 553: 554: sosel(fp, flag) 555: struct file *fp; 556: int flag; 557: { 558: #ifdef INET 559: return (SOO_SELECT(fp, flag)); 560: #else 561: return (EOPNOTSUPP); 562: #endif 563: } 564: 565: socls(fp) 566: register struct file *fp; 567: { 568: register int error = 0; 569: 570: #ifdef INET 571: if (fp->f_data) 572: error = SOCLOSE((struct socket *)fp->f_data); 573: fp->f_data = 0; 574: #else 575: error = EOPNOTSUPP; 576: #endif 577: return(error); 578: }