|
|
1.1 ! root 1: /* mx2.c 4.2 11/9/80 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../h/systm.h" ! 5: #include "../h/dir.h" ! 6: #include "../h/user.h" ! 7: #include "../h/proc.h" ! 8: #include "../h/tty.h" ! 9: #include "../h/inode.h" ! 10: #include "../h/mx.h" ! 11: #include "../h/file.h" ! 12: #include "../h/conf.h" ! 13: #include "../h/buf.h" ! 14: /* ! 15: * multiplexor driver ! 16: */ ! 17: struct chan chans[NCHANS]; ! 18: struct group *groups[NGROUPS]; ! 19: int mpxline; ! 20: ! 21: short cmask[16] ={ ! 22: 01, 02, 04, ! 23: 010, 020, 040, ! 24: 0100, 0200, 0400, ! 25: 01000, 02000, 04000, ! 26: 010000, 020000, 040000, 0100000 ! 27: }; ! 28: ! 29: #define IOMOVE iomove ! 30: #define FPEND &file[NFILE] ! 31: struct chan *xcp(),*addch(),*nextcp(); ! 32: ! 33: #define HIQ 100 ! 34: #define LOQ 20 ! 35: #define FP ((struct file *)cp) ! 36: ! 37: char mcdebugs[NDEBUGS]; ! 38: ! 39: struct group * ! 40: getmpx(dev) ! 41: dev_t dev; ! 42: { ! 43: register d; ! 44: ! 45: d = minor(dev); ! 46: if (d >= NGROUPS) { ! 47: u.u_error = ENXIO; ! 48: return(NULL); ! 49: } ! 50: return(groups[d]); ! 51: } ! 52: ! 53: ! 54: /*ARGSUSED*/ ! 55: mxopen(dev, flag) ! 56: { ! 57: register struct group *gp; ! 58: register struct file *fp; ! 59: register struct chan *cp; ! 60: int msg; ! 61: ! 62: if ((gp=getmpx(dev)) == NULL) { ! 63: return; ! 64: } ! 65: if (!(gp->g_state&INUSE)) { ! 66: u.u_error = ENXIO; ! 67: return; ! 68: } ! 69: fp = u.u_ofile[u.u_r.r_val1]; ! 70: if (fp->f_inode != gp->g_inode) { ! 71: u.u_error = ENXIO; ! 72: return; ! 73: } ! 74: if ((cp=addch(gp->g_inode,0)) == NULL) { ! 75: u.u_error = ENXIO; ! 76: return; ! 77: } ! 78: ! 79: cp->c_flags = XGRP; ! 80: cp->c_ottyp = cp->c_ttyp = (struct tty *)cp; ! 81: cp->c_line = cp->c_oline = mpxline; ! 82: ! 83: fp->f_flag |= FMPY; ! 84: fp->f_flag |= FREAD+FWRITE; ! 85: fp->f_un.f_chan = cp; ! 86: ! 87: if (gp->g_inode == mpxip) { ! 88: plock(mpxip); ! 89: mpxname(cp); ! 90: msg = M_OPEN; ! 91: } else ! 92: msg = M_WATCH; ! 93: ! 94: scontrol(cp, msg+(cp->c_index<<8), u.u_uid); ! 95: sleep((caddr_t)cp,TTIPRI); ! 96: if (cp->c_flags&NMBUF) ! 97: prele(mpxip); ! 98: if (cp->c_flags & WCLOSE) { ! 99: chdrain(cp); ! 100: chfree(cp); ! 101: u.u_error = ENXIO; ! 102: return; ! 103: } ! 104: cp->c_fy = fp; ! 105: cp->c_pgrp = u.u_procp->p_pgrp; ! 106: } ! 107: ! 108: ! 109: char mxnmbuf[NMSIZE]; ! 110: int nmsize; ! 111: ! 112: mpxname(cp) ! 113: register struct chan *cp; ! 114: { ! 115: register char *np; ! 116: register c; ! 117: ! 118: np = mxnmbuf; ! 119: u.u_dirp = (caddr_t)u.u_arg[0]; ! 120: ! 121: while (np < &mxnmbuf[NMSIZE]) { ! 122: c = uchar(); ! 123: if (c <= 0) ! 124: break; ! 125: *np++ = c; ! 126: } ! 127: *np++ = '\0'; ! 128: nmsize = np - mxnmbuf; ! 129: ! 130: cp->c_flags |= NMBUF; ! 131: } ! 132: ! 133: ! 134: mxclose(dev, flag, cp) ! 135: dev_t dev; ! 136: register struct chan *cp; ! 137: { ! 138: register struct group *gp; ! 139: register struct inode *ip; ! 140: register struct file *fp; ! 141: int i, fmp; ! 142: ! 143: fmp = flag&FMP; ! 144: if ((gp=getmpx(dev)) == NULL) ! 145: return; ! 146: ! 147: ip = gp->g_inode; ! 148: if (ip==NULL || (ip->i_mode&IFMT)!=IFMPC) { ! 149: return; ! 150: } ! 151: ! 152: /* ! 153: * close a channel ! 154: */ ! 155: if (cp!=NULL && fmp && fmp!=FMP) { ! 156: for(fp=file; fp< FPEND; fp++) ! 157: if(fp->f_count && fp->f_flag&FMP && fp->f_un.f_chan==cp){ ! 158: return; ! 159: } ! 160: chdrain(cp); ! 161: if ((cp->c_flags&WCLOSE)==0) { ! 162: scontrol(cp, M_CLOSE, 0); ! 163: cp->c_flags |= WCLOSE; ! 164: } else { ! 165: chfree(cp); ! 166: } ! 167: goto out; ! 168: } ! 169: ! 170: ! 171: for(fp=file; fp < FPEND; fp++) { ! 172: if (fp->f_count && (fp->f_flag&FMP)==FMP && fp->f_inode==ip) ! 173: return; ! 174: } ! 175: ! 176: if (ip == mpxip) { ! 177: mpxip = NULL; ! 178: prele(ip); ! 179: } ! 180: ! 181: for(i=0;i<NINDEX;i++) ! 182: (void) detach(gp->g_chans[i]); ! 183: ! 184: out: ! 185: if (ip->i_count == 1) { ! 186: groups[minor(dev)] = NULL; ! 187: plock(ip); ! 188: zero((caddr_t)gp, sizeof (struct group)); ! 189: ip->i_mode = IFREG + 0666; ! 190: ip->i_un.i_rdev = 0; ! 191: ip->i_flag |= IUPD|ICHG; ! 192: iput(ip); ! 193: } ! 194: } ! 195: ! 196: zero(s, cc) ! 197: register char *s; ! 198: register cc; ! 199: { ! 200: while (cc--) ! 201: *s++ = 0; ! 202: } ! 203: ! 204: char m_eot[] ={ M_EOT, 0, 0, 0}; ! 205: ! 206: /* ! 207: * Mxread + mxwrite are entered from cdevsw ! 208: * for all read/write calls. Operations on ! 209: * an mpx file are handled here. ! 210: * Calls are made through linesw to handle actual ! 211: * data movement. ! 212: */ ! 213: mxread(dev) ! 214: { ! 215: register struct group *gp; ! 216: register struct chan *cp; ! 217: register esc; ! 218: struct rh h; ! 219: caddr_t base; ! 220: unsigned count; ! 221: int s, xfr, more, fmp; ! 222: ! 223: if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) { ! 224: u.u_error = ENXIO; ! 225: return; ! 226: } ! 227: ! 228: fmp = FP->f_flag & FMP; ! 229: if (fmp != FMP) { ! 230: if (u.u_count == 0) ! 231: return; ! 232: msread(fmp, FP->f_un.f_chan); ! 233: return; ! 234: } ! 235: ! 236: if ((int)u.u_base & 1) { ! 237: u.u_error = ENXIO; ! 238: return; ! 239: } ! 240: ! 241: s = spl6(); ! 242: if (u.u_count == 0) ! 243: { ! 244: if (gp->g_datq == 0) ! 245: u.u_error = ENXIO; ! 246: splx(s); ! 247: return; ! 248: } ! 249: while (gp->g_datq == 0) { ! 250: sleep((caddr_t)&gp->g_datq, TTIPRI); ! 251: } ! 252: splx(s); ! 253: ! 254: while (gp->g_datq && u.u_count >= CNTLSIZ + 2) { ! 255: esc = 0; ! 256: cp = nextcp(gp); ! 257: if (cp==NULL) { ! 258: continue; ! 259: } ! 260: h.index = cpx(cp); ! 261: if (count = cp->c_ctlx.c_cc) { ! 262: count += CNTLSIZ; ! 263: if (cp->c_flags&NMBUF) ! 264: count += nmsize; ! 265: if (count > u.u_count) { ! 266: (void) sdata(cp); ! 267: return; ! 268: } ! 269: esc++; ! 270: } ! 271: base = u.u_base; ! 272: count = u.u_count; ! 273: u.u_base += sizeof h; ! 274: u.u_count -= sizeof h; ! 275: xfr = u.u_count; ! 276: if (esc) { ! 277: more = mcread(cp); ! 278: } else { ! 279: more = (*linesw[cp->c_line].l_read)(cp->c_ttyp); ! 280: } ! 281: if (more > 0) ! 282: (void) sdata(cp); ! 283: if (more < 0) ! 284: scontrol(cp, M_CLOSE, 0); ! 285: (void) spl0(); ! 286: if (xfr == u.u_count) { ! 287: esc++; ! 288: IOMOVE((caddr_t)m_eot, sizeof m_eot, B_READ); ! 289: } ! 290: xfr -= u.u_count; ! 291: if (esc) { ! 292: h.count = 0; ! 293: h.ccount = xfr; ! 294: } else { ! 295: h.count = xfr; ! 296: h.ccount = 0; ! 297: mxrstrt(cp, &cp->cx.datq, BLOCK|ALT); ! 298: } ! 299: if (u.u_count && (xfr&1)) { ! 300: u.u_base++; ! 301: u.u_count--; ! 302: } ! 303: (void) copyout((caddr_t)&h, base, sizeof h); ! 304: ! 305: } ! 306: } ! 307: ! 308: ! 309: mxwrite(dev) ! 310: { ! 311: register struct chan *cp; ! 312: struct wh h; ! 313: struct group *gp; ! 314: int ucount, esc, fmp, burpcount; ! 315: caddr_t ubase, hbase; ! 316: ! 317: if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) { ! 318: return; ! 319: } ! 320: fmp = FP->f_flag & FMP; ! 321: if (fmp != FMP) { ! 322: mswrite(fmp, FP->f_un.f_chan); ! 323: return; ! 324: } ! 325: ! 326: burpcount = 0; ! 327: while (u.u_count >= sizeof h) { ! 328: hbase = u.u_base; ! 329: IOMOVE((caddr_t)&h, sizeof h, B_WRITE); ! 330: if (u.u_error) ! 331: return; ! 332: esc = 0; ! 333: if (h.count==0) { ! 334: esc++; ! 335: h.count = h.ccount; ! 336: } ! 337: cp = xcp(gp, h.index); ! 338: if (cp==NULL || cp->c_flags&ISGRP) { ! 339: u.u_error = ENXIO; ! 340: return; ! 341: } ! 342: ucount = u.u_count; ! 343: ubase = u.u_base; ! 344: u.u_count = h.count; ! 345: u.u_base = h.data; ! 346: ! 347: if (esc==0) { ! 348: struct tty *tp; ! 349: caddr_t waddr; ! 350: int line; ! 351: ! 352: if (cp->c_flags&PORT) { ! 353: line = cp->c_line; ! 354: tp = cp->c_ttyp; ! 355: } else { ! 356: line = cp->c_oline; ! 357: tp = cp->c_ottyp; ! 358: } ! 359: loop: ! 360: waddr = (caddr_t)(*linesw[line].l_write)(tp); ! 361: if (u.u_count) { ! 362: if (gp->g_state&ENAMSG) { ! 363: burpcount++; ! 364: cp->c_flags |= BLKMSG; ! 365: /* ! 366: scontrol(cp, M_BLK, u.u_count); ! 367: */ ! 368: h.ccount = -1; ! 369: h.count = u.u_count; ! 370: h.data = u.u_base; ! 371: (void) copyout((caddr_t)&h, hbase, sizeof h); ! 372: } else { ! 373: if(waddr == 0) { ! 374: u.u_error = ENXIO; ! 375: return; ! 376: } ! 377: sleep(waddr, TTOPRI); ! 378: goto loop; ! 379: } ! 380: } ! 381: } else { ! 382: mxwcontrol(cp); ! 383: } ! 384: u.u_count = ucount; ! 385: u.u_base = ubase; ! 386: } ! 387: u.u_count = burpcount; ! 388: } ! 389: ! 390: ! 391: ! 392: /* ! 393: * Mcread and mcwrite move data on an mpx file. ! 394: * Transfer addr and length is controlled by mxread/mxwrite. ! 395: * Kernel-to-Kernel and other special transfers are not ! 396: * yet in. ! 397: */ ! 398: mcread(cp) ! 399: register struct chan *cp; ! 400: { ! 401: register struct clist *q; ! 402: register char *np; ! 403: ! 404: ! 405: q = (cp->c_ctlx.c_cc) ? &cp->c_ctlx : &cp->cx.datq; ! 406: (void) mxmove(q, B_READ); ! 407: ! 408: if (cp->c_flags&NMBUF && q == &cp->c_ctlx) { ! 409: np = mxnmbuf; ! 410: while (nmsize--) ! 411: (void) passc(*np++); ! 412: cp->c_flags &= ~NMBUF; ! 413: prele(mpxip); ! 414: } ! 415: if (cp->c_flags&PORT) ! 416: return(cp->c_ctlx.c_cc + cp->c_ttyp->t_rawq.c_cc); else ! 417: return(cp->c_ctlx.c_cc + cp->cx.datq.c_cc); ! 418: ! 419: } ! 420: ! 421: ! 422: caddr_t ! 423: mcwrite(cp) ! 424: register struct chan *cp; ! 425: { ! 426: register struct clist *q; ! 427: int s; ! 428: ! 429: q = &cp->cy.datq; ! 430: while (u.u_count) { ! 431: s = spl6(); ! 432: if (q->c_cc > HIQ || (cp->c_flags&EOTMARK)) { ! 433: cp->c_flags |= SIGBLK; ! 434: splx(s); ! 435: break; ! 436: } ! 437: splx(s); ! 438: (void) mxmove(q, B_WRITE); ! 439: } ! 440: wakeup((caddr_t)q); ! 441: return((caddr_t)q); ! 442: } ! 443: ! 444: ! 445: /* ! 446: * Msread and mswrite move bytes ! 447: * between user and non-multiplexed channel. ! 448: */ ! 449: msread(fmp, cp) ! 450: register struct chan *cp; ! 451: { ! 452: register struct clist *q; ! 453: int s; ! 454: ! 455: q = (fmp&FMPX) ? &cp->cx.datq : &cp->cy.datq; ! 456: s = spl6(); ! 457: while (q->c_cc == 0) { ! 458: if (cp->c_flags&WCLOSE) { ! 459: u.u_error = ENXIO; ! 460: goto out; ! 461: } ! 462: if (cp->c_flags & EOTMARK) { ! 463: cp->c_flags &= ~EOTMARK; ! 464: if(msgenab(cp)) ! 465: scontrol(cp, M_UBLK, 0); ! 466: else { ! 467: wakeup((caddr_t)cp); ! 468: wakeup((caddr_t)q); ! 469: } ! 470: goto out; ! 471: } ! 472: sleep((caddr_t)q,TTIPRI); ! 473: } ! 474: if (cp->c_flags&WCLOSE) { ! 475: u.u_error = ENXIO; ! 476: goto out; ! 477: } ! 478: splx(s); ! 479: while (mxmove(q, B_READ) > 0) ! 480: ; ! 481: mxrstrt(cp, q, SIGBLK); ! 482: return; ! 483: out: ! 484: splx(s); ! 485: } ! 486: ! 487: ! 488: mswrite(fmp, cp) ! 489: register struct chan *cp; ! 490: { ! 491: register struct clist *q; ! 492: register int cc; ! 493: ! 494: q = (fmp&FMPX) ? &cp->cy.datq : &cp->cx.datq; ! 495: while (u.u_count) { ! 496: (void) spl6(); ! 497: if (cp->c_flags&WCLOSE) { ! 498: gsignal(cp->c_pgrp, SIGPIPE); ! 499: (void) spl0(); ! 500: return; ! 501: } ! 502: if (q->c_cc>= HIQ || cp->c_flags&FBLOCK) { ! 503: if (cp->c_flags&WCLOSE) { ! 504: gsignal(cp->c_pgrp, SIGPIPE); ! 505: (void) spl0(); ! 506: return; ! 507: } ! 508: (void) sdata(cp); ! 509: cp->c_flags |= BLOCK; ! 510: sleep((caddr_t)q+1,TTOPRI); ! 511: (void) spl0(); ! 512: continue; ! 513: } ! 514: (void) spl0(); ! 515: cc = mxmove(q, B_WRITE); ! 516: if (cc < 0) ! 517: break; ! 518: } ! 519: if (fmp&FMPX) { ! 520: if (cp->c_flags&YGRP) (void) sdata(cp); ! 521: else wakeup((caddr_t)q); ! 522: } else { ! 523: if (cp->c_flags&XGRP) (void) sdata(cp); ! 524: else wakeup((caddr_t)q); ! 525: } ! 526: } ! 527: ! 528: ! 529: /* ! 530: * move chars between clist and user space. ! 531: */ ! 532: ! 533: mxmove(q, dir) ! 534: register struct clist *q; ! 535: register dir; ! 536: { ! 537: register cc; ! 538: char cbuf[HIQ]; ! 539: ! 540: cc = MIN(u.u_count, sizeof cbuf); ! 541: if (dir == B_READ) ! 542: cc = q_to_b(q, cbuf, cc); ! 543: if (cc <= 0) ! 544: return(cc); ! 545: IOMOVE((caddr_t)cbuf, (unsigned)cc, dir); ! 546: if (dir == B_WRITE) ! 547: cc = b_to_q(cbuf, cc, q); ! 548: return(cc); ! 549: } ! 550: ! 551: ! 552: ! 553: mxrstrt(cp, q, b) ! 554: register struct chan *cp; ! 555: register struct clist *q; ! 556: register b; ! 557: { ! 558: int s; ! 559: ! 560: s = spl6(); ! 561: if (cp->c_flags&b && q->c_cc<LOQ) { ! 562: cp->c_flags &= ~b; ! 563: if (b&ALT) ! 564: wakeup((caddr_t)q+1); else ! 565: mcstart(cp, (caddr_t)q); ! 566: } ! 567: if (cp->c_flags&WFLUSH) ! 568: wakeup((caddr_t)q+2); ! 569: splx(s); ! 570: } ! 571: ! 572: ! 573: ! 574: /* ! 575: * called from driver start or xint routines ! 576: * to wakeup output sleeper. ! 577: */ ! 578: mcstart(cp, q) ! 579: register struct chan *cp; ! 580: register caddr_t q; ! 581: { ! 582: ! 583: if (cp->c_flags&(BLKMSG)) { ! 584: cp->c_flags &= ~BLKMSG; ! 585: scontrol(cp, M_UBLK, 0); ! 586: } else ! 587: wakeup((caddr_t)q); ! 588: } ! 589: ! 590: ! 591: mxwcontrol(cp) ! 592: register struct chan *cp; ! 593: { ! 594: short cmd; ! 595: struct sgttyb vec; ! 596: int s; ! 597: ! 598: IOMOVE((caddr_t)&cmd, sizeof cmd, B_WRITE); ! 599: if (u.u_error) ! 600: return; ! 601: switch(cmd) { ! 602: /* ! 603: * not ready to queue this up yet. ! 604: */ ! 605: case M_EOT: ! 606: s = spl6(); ! 607: while (cp->c_flags & EOTMARK) ! 608: if(msgenab(cp)){ ! 609: scontrol(cp, M_BLK, 0); ! 610: goto out; ! 611: } else ! 612: sleep((caddr_t)cp, TTOPRI); ! 613: cp->c_flags |= EOTMARK; ! 614: out: ! 615: wakeup((caddr_t)&cp->cy.datq); ! 616: splx(s); ! 617: break; ! 618: case M_IOCTL: ! 619: break; ! 620: case M_IOANS: ! 621: if (cp->c_flags&SIOCTL) { ! 622: IOMOVE((caddr_t)&vec, sizeof vec, B_WRITE); ! 623: (void) b_to_q((caddr_t)&vec, sizeof vec, &cp->c_ctly); ! 624: cp->c_flags &= ~SIOCTL; ! 625: wakeup((caddr_t)cp); ! 626: } ! 627: break; ! 628: case M_BLK: ! 629: cp->c_flags |= FBLOCK; ! 630: break; ! 631: case M_UBLK: ! 632: cp->c_flags &= ~FBLOCK; ! 633: chwake(cp); ! 634: break; ! 635: default: ! 636: u.u_error = ENXIO; ! 637: } ! 638: } ! 639: ! 640: ! 641: ! 642: /*ARGSUSED*/ ! 643: mxioctl(dev, cmd, addr, flag) ! 644: caddr_t addr; ! 645: { ! 646: struct group *gp; ! 647: int fmp; ! 648: struct file *fp; ! 649: struct { ! 650: short c_ctl; ! 651: short c_cmd; ! 652: struct sgttyb c_vec; ! 653: } ctlbuf; ! 654: ! 655: if ((gp=getmpx(dev))==NULL || (fp=getf(u.u_arg[0]))==NULL) { ! 656: return; ! 657: } ! 658: ! 659: fmp = fp->f_flag & FMP; ! 660: if (fmp == FMP) { ! 661: switch(cmd) { ! 662: ! 663: case MXLSTN: ! 664: if (mpxip == NULL) { ! 665: mpxip = gp->g_inode; ! 666: } else { ! 667: u.u_error = ENXIO; ! 668: return; ! 669: } ! 670: break; ! 671: ! 672: case MXNBLK: ! 673: gp->g_state |= ENAMSG; ! 674: break; ! 675: ! 676: default: ! 677: u.u_error = ENXIO; ! 678: return; ! 679: } ! 680: } else { ! 681: ctlbuf.c_ctl = M_IOCTL; ! 682: ctlbuf.c_cmd = cmd; ! 683: (void) copyin(addr, (caddr_t)&ctlbuf.c_vec, sizeof (struct sgttyb)); ! 684: sioctl(fp->f_un.f_chan, (char *)&ctlbuf, sizeof ctlbuf); ! 685: (void) copyout((caddr_t)&ctlbuf, addr, sizeof (struct sgttyb)); ! 686: } ! 687: } ! 688: ! 689: ! 690: chdrain(cp) ! 691: register struct chan *cp; ! 692: { ! 693: register struct tty *tp; ! 694: int wflag; ! 695: ! 696: chwake(cp); ! 697: ! 698: wflag = (cp->c_flags&WCLOSE)==0; ! 699: tp = cp->c_ttyp; ! 700: if (tp == NULL) /* prob not required */ ! 701: return; ! 702: if (cp->c_flags&PORT && tp->t_chan == cp) { ! 703: cp->c_ttyp = NULL; ! 704: tp->t_chan = NULL; ! 705: return; ! 706: } ! 707: if (wflag) ! 708: wflush(cp,&cp->cx.datq); else ! 709: flush(&cp->cx.datq); ! 710: if (!(cp->c_flags&YGRP)) { ! 711: flush(&cp->cy.datq); ! 712: } ! 713: } ! 714: ! 715: chwake(cp) ! 716: register struct chan *cp; ! 717: { ! 718: register char *p; ! 719: ! 720: wakeup((caddr_t)cp); ! 721: flush(&cp->c_ctlx); ! 722: p = (char *)&cp->cx.datq; ! 723: wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p); ! 724: p = (char *)&cp->cy.datq; ! 725: wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p); ! 726: } ! 727: ! 728: ! 729: chfree(cp) ! 730: register struct chan *cp; ! 731: { ! 732: register struct group *gp; ! 733: register i; ! 734: ! 735: gp = cp->c_group; ! 736: if (gp==NULL) ! 737: return; ! 738: i = cp->c_index; ! 739: if (cp == gp->g_chans[i]) { ! 740: gp->g_chans[i] = NULL; ! 741: } ! 742: cp->c_group = NULL; ! 743: wakeup((caddr_t)gp); ! 744: } ! 745: ! 746: ! 747: flush(q) ! 748: register struct clist *q; ! 749: { ! 750: ! 751: while(q->c_cc) ! 752: (void) getc(q); ! 753: } ! 754: ! 755: ! 756: wflush(cp,q) ! 757: register struct chan *cp; ! 758: register struct clist *q; ! 759: { ! 760: register s; ! 761: ! 762: s = spl6(); ! 763: if(q->c_cc && (cp->c_flags&WCLOSE) == 0) { ! 764: cp->c_flags |= WFLUSH; ! 765: (void) sdata(cp); ! 766: (void) tsleep((caddr_t)q+2, TTOPRI, 30); ! 767: } ! 768: flush(q); ! 769: cp->c_flags &= ~WFLUSH; ! 770: splx(s); ! 771: } ! 772: ! 773: ! 774: scontrol(cp,event,value) ! 775: register struct chan *cp; ! 776: short event,value; ! 777: { ! 778: register struct clist *q; ! 779: int s; ! 780: ! 781: q = &cp->c_ctlx; ! 782: s = spl6(); ! 783: if (sdata(cp) == NULL) ! 784: return; ! 785: (void) putw(event,q); ! 786: (void) putw(value,q); ! 787: splx(s); ! 788: } ! 789: ! 790: ! 791: ! 792: sioctl(cp, vec, cc) ! 793: register struct chan *cp; ! 794: char *vec; ! 795: { ! 796: register s; ! 797: register struct clist *q; ! 798: ! 799: s = spl6(); ! 800: q = &cp->cx.datq; ! 801: while (q->c_cc) { ! 802: cp->c_flags |= BLOCK; ! 803: if (sdata(cp)==NULL) { ! 804: u.u_error = ENXIO; ! 805: return; ! 806: } ! 807: sleep((caddr_t)q+1, TTOPRI); ! 808: } ! 809: (void) b_to_q(vec, cc, &cp->c_ctlx); ! 810: cp->c_flags |= SIOCTL; ! 811: while (cp->c_flags&SIOCTL) { ! 812: if (cp->c_ctlx.c_cc) ! 813: if (sdata(cp)==NULL) { ! 814: u.u_error = ENXIO; ! 815: return; ! 816: } ! 817: sleep((caddr_t)cp, TTOPRI); ! 818: } ! 819: (void) q_to_b(&cp->c_ctly, vec, cp->c_ctly.c_cc); ! 820: splx(s); ! 821: } ! 822: ! 823: sdata(cp) ! 824: struct chan *cp; ! 825: { ! 826: register struct group *gp = (struct group *)cp; ! 827: register struct group *ngp; ! 828: register int s; ! 829: ! 830: ngp = gp->g_group; ! 831: if (ngp==NULL || (ngp->g_state&ISGRP)==0) ! 832: return(NULL); ! 833: ! 834: s = spl6(); ! 835: do { ! 836: ngp->g_datq |= cmask[gp->g_index]; ! 837: wakeup((caddr_t)&ngp->g_datq); ! 838: gp = ngp; ! 839: } while(ngp=ngp->g_group); ! 840: splx(s); ! 841: return((int)gp); ! 842: } ! 843: ! 844: ! 845: ! 846: struct chan * ! 847: xcp(gp, x) ! 848: register struct group *gp; ! 849: register short x; ! 850: { ! 851: register int i; ! 852: ! 853: while (gp->g_group) gp=gp->g_group; ! 854: for (i=0;i<NLEVELS;i++) { ! 855: if ((x&017) >= NINDEX) ! 856: break; ! 857: if (gp==NULL || (gp->g_state&ISGRP)==0) ! 858: return((struct chan *)NULL); ! 859: gp = (struct group *)gp->g_chans[x&017]; ! 860: x >>= 4; ! 861: } ! 862: return((struct chan *)gp); ! 863: } ! 864: ! 865: cpx(cp) ! 866: register struct chan *cp; ! 867: { ! 868: register x; ! 869: register struct group *gp; ! 870: ! 871: x = (-1<<4) + cp->c_index; ! 872: gp = cp->c_group; ! 873: while (gp->g_group) { ! 874: x <<= 4; ! 875: x |= gp->g_index; ! 876: gp = gp->g_group; ! 877: } ! 878: return(x); ! 879: } ! 880: ! 881: ! 882: struct chan * ! 883: nextcp(gp) ! 884: register struct group *gp; ! 885: { ! 886: register struct group *lgp, *ngp; ! 887: ! 888: do { ! 889: while ((gp->g_datq & cmask[gp->g_rot]) == 0) { ! 890: gp->g_rot = (gp->g_rot+1)%NINDEX; ! 891: } ! 892: lgp = gp; ! 893: gp = (struct group *)gp->g_chans[gp->g_rot]; ! 894: } while (gp!=NULL && gp->g_state&ISGRP); ! 895: ! 896: lgp->g_datq &= ~cmask[lgp->g_rot]; ! 897: lgp->g_rot = (lgp->g_rot+1)%NINDEX; ! 898: ! 899: while (ngp=lgp->g_group) { ! 900: ngp->g_datq &= ~cmask[lgp->g_index]; ! 901: if (ngp->g_datq) ! 902: break; ! 903: lgp = ngp; ! 904: } ! 905: return((struct chan *)gp); ! 906: } ! 907: ! 908: ! 909: ! 910: msgenab(cp) ! 911: register struct chan *cp; ! 912: { ! 913: register struct group *gp; ! 914: ! 915: for(gp=cp->c_group;gp;gp=gp->g_group) ! 916: if(gp->g_state & ENAMSG)return(1); ! 917: return(0); ! 918: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.