1: #include "../h/param.h"
   2: #include "../h/systm.h"
   3: #include "../h/dir.h"
   4: #include "../h/user.h"
   5: #include "../h/reg.h"
   6: #include "../h/proc.h"
   7: #include "../h/tty.h"
   8: #include "../h/inode.h"
   9: #define KERNEL  1
  10: #include "../h/mx.h"
  11: #include "../h/file.h"
  12: #include "../h/conf.h"
  13: 
  14: /*
  15:  * Multiplexor:   clist version
  16:  *
  17:  * installation:
  18:  *	requires a line in cdevsw -
  19:  *		mxopen, mxclose, mxread, mxwrite, mxioctl, 0,
  20:  *
  21:  *	also requires a line in linesw -
  22:  *		mxopen, mxclose, mcread, mcwrite, mxioctl, nulldev, nulldev,
  23:  *
  24:  *	The linesw entry for mpx should be the last one in the table.
  25:  *	'nldisp' (number of line disciplines) should not include the
  26:  *	mpx line.  This is to prevent mpx from being enabled by an ioctl.
  27: 
  28:  *	mxtty.c must be loaded instead of tty.c so that certain
  29:  *	sleeps will not be done if a typewriter is connected to
  30:  *	a channel and so that sdata will be called from ttyinput.
  31:  *
  32:  */
  33: struct  chan    chans[NCHANS];
  34: struct  schan   schans[NPORTS];
  35: struct  group   *groups[NGROUPS];
  36: int mpxline;
  37: struct chan *xcp();
  38: dev_t   mpxdev  = -1;
  39: 
  40: 
  41: char    mcdebugs[NDEBUGS];
  42: 
  43: 
  44: /*
  45:  * Allocate a channel, set c_index to index.
  46:  */
  47: struct  chan *
  48: challoc(index, isport)
  49: {
  50: register s;
  51: 
  52:     s = spl6();
  53:     if (isport) {
  54:         register struct schan *cp, *lastcp;
  55:         cp = schans;
  56:         lastcp = &schans[NPORTS];
  57:         for (; cp < lastcp; cp++)
  58:             if (cp->c_group==NULL) {
  59:                 cp->c_index = index;
  60:                 cp->c_pgrp = 0;
  61:                 cp->c_flags = 0;
  62:                 splx(s);
  63:                 return((struct chan *)cp);
  64:             }
  65:         goto out;
  66:     } else {
  67:         register struct chan *cp, *lastcp;
  68:         cp = chans;
  69:         lastcp = &chans[NCHANS];
  70:         for(; cp < lastcp; cp++)
  71:             if(cp->c_group==NULL) {
  72:                 cp->c_index = index;
  73:                 cp->c_pgrp = 0;
  74:                 cp->c_flags = 0;
  75:                 splx(s);
  76:                 return(cp);
  77:             }
  78:     }
  79: out:
  80:     splx(s);
  81:     return(NULL);
  82: }
  83: 
  84: 
  85: 
  86: /*
  87:  * Allocate a group table cell.
  88:  */
  89: gpalloc()
  90: {
  91: register i,s;
  92: 
  93:     s = spl6();
  94:     for(i = NGROUPS-1; i>=0; i--)
  95:         if (groups[i]==NULL) {
  96:             groups[i]++;
  97:             break;
  98:         }
  99:     splx(s);
 100:     return(i);
 101: }
 102: 
 103: 
 104: /*
 105:  * Add a channel to the group in
 106:  * inode ip.
 107:  */
 108: struct chan *
 109: addch(ip, isport)
 110: struct inode *ip;
 111: {
 112: register struct chan *cp;
 113: register struct group *gp;
 114: register i;
 115: 
 116:     plock(ip);
 117:     gp = &ip->i_un.i_group;
 118:     for(i=0;i<NINDEX;i++) {
 119:         cp = (struct chan *)gp->g_chans[i];
 120:         if (cp == NULL) {
 121:             if ((cp=challoc(i, isport)) != NULL) {
 122:                 gp->g_chans[i] = cp;
 123:                 cp->c_group = gp;
 124:             }
 125:             break;
 126:         }
 127:         cp = NULL;
 128:     }
 129:     prele(ip);
 130:     return(cp);
 131: }
 132: 
 133: 
 134: 
 135: 
 136: /*
 137:  * mpxchan system call
 138:  */
 139: mpxchan()
 140: {
 141: struct  inode *ip, *gip;
 142: register int i;
 143: extern  mxopen(), mcread();
 144: extern  sdata(), scontrol();
 145: dev_t   dev;
 146: struct  tty *tp;
 147: struct  file *fp, *chfp, *gfp;
 148: struct  chan *cp;
 149: struct  group *gp, *ngp;
 150: struct  a {
 151:     int cmd;
 152:     int *argvec;
 153: } *uap;
 154: struct mx_args vec;
 155: 
 156: 
 157:     /*
 158: 	 * common setup code.
 159: 	 */
 160:     uap = (struct a *)u.u_ap;
 161:     copyin((caddr_t)uap->argvec, (caddr_t)&vec, sizeof vec);
 162:     gp = NULL;
 163:     switch(uap->cmd) {
 164:     case NPGRP:
 165:         if (vec.m_arg[1] < 0)
 166:             goto sw;
 167:     case CHAN:
 168:     case JOIN:
 169:     case EXTR:
 170:     case ATTACH:
 171:     case DETACH:
 172:     case CSIG:
 173:         gfp = getf(vec.m_arg[1]);
 174:         if (gfp==NULL)
 175:             goto bad;
 176:         gip = gfp->f_inode;
 177:         gp = &gip->i_un.i_group;
 178:         if (gp->g_inode != gip)
 179:             goto bad;
 180:     }
 181: 
 182: sw:
 183:     switch(uap->cmd) {
 184:     /*
 185: 	 * creat an mpx file.
 186: 	 */
 187:     case MPX:
 188:     case MPXN:
 189:         if (mpxdev < 0) {
 190:             for(i=0; linesw[i].l_open; i++)
 191:                 if (linesw[i].l_read == mcread) {
 192:                     mpxline = i;
 193:                     goto found1;
 194:                 }
 195:             goto bad;
 196: 
 197:         found1:
 198:             for(i=0; cdevsw[i].d_open; i++) {
 199:                 if (cdevsw[i].d_open == mxopen)
 200:                     goto found2;
 201:             }
 202:         bad:
 203:             u.u_error = ENXIO;
 204:             return;
 205:         found2:
 206:             mpxdev = (dev_t)(i<<8);
 207:         }
 208:         if (uap->cmd==MPXN) {
 209:             if ((ip=ialloc(rootdev))==NULL)
 210:                 goto bad;
 211:             ip->i_mode = 0666+IFCHR;
 212:             goto merge;
 213:         }
 214:         u.u_dirp = vec.m_name;
 215:         ip = namei(uchar,1);
 216:         if (ip != NULL) {
 217:             u.u_error = EEXIST;
 218:             iput(ip);
 219:             return;
 220:         }
 221:         if (u.u_error)
 222:             return;
 223:         ip = maknode((vec.m_arg[0]&0777)+IFCHR);
 224:         if (ip == NULL)
 225:             return;
 226:     merge:
 227:         if ((i = gpalloc()) < 0) {
 228:             iput(ip);
 229:             goto bad;
 230:         }
 231:         ip->i_un.i_rdev = (daddr_t)(mpxdev+i);
 232:         gp = &ip->i_un.i_group;
 233:         groups[i] = gp;
 234:         gp->g_inode = ip;
 235:         gp->g_state = COPEN;
 236:         gp->g_group = NULL;
 237:         gp->g_index = 0;
 238:         gp->g_rotmask = 1;
 239:         gp->g_rot = 0;
 240:         gp->g_datq = 0;
 241:         open1(ip,FREAD+FWRITE,2);
 242:         if (u.u_error) {
 243:             groups[i] = NULL;
 244:             iput(ip);
 245:             goto bad;
 246:         }
 247:         ip->i_mode = (ip->i_mode & ~IFMT) | IFMPC;
 248:         ip->i_count++;
 249:         ip->i_flag |= IACC|IUPD|ICHG;
 250:         fp = u.u_ofile[u.u_r.r_val1];
 251:         fp->f_flag |= FMP;
 252:         fp->f_un.f_chan = NULL;
 253:         gp->g_file = fp;
 254:         for(i=0;i<NINDEX;)
 255:             gp->g_chans[i++] = NULL;
 256:         return;
 257:     /*
 258: 	 * join file descriptor (arg 0) to group (arg 1)
 259: 	 * return channel number
 260: 	 */
 261:     case JOIN:
 262:         if ((fp=getf(vec.m_arg[0]))==NULL)
 263:             goto bad;
 264:         ip = fp->f_inode;
 265:         i = ip->i_mode & IFMT;
 266:         if (i == IFMPC) {
 267:             if ((fp->f_flag&FMP) != FMP) {
 268:                 goto bad;
 269:             }
 270:             ngp = &ip->i_un.i_group;
 271:             mlink (ngp, gp);
 272:             fp->f_count++;
 273:             return;
 274:         }
 275:         if (i != IFCHR)
 276:             goto bad;
 277:         dev = (dev_t)ip->i_un.i_rdev;
 278:         tp = cdevsw[major(dev)].d_ttys;
 279:         if (tp==NULL)
 280:             goto bad;
 281:         tp = &tp[minor(dev)];
 282:         if (tp->t_chan)
 283:             goto bad;
 284:         if ((cp=addch(gip, 1))==NULL)
 285:             goto bad;
 286:         tp->t_chan = cp;
 287:         cp->c_fy = fp;
 288:         fp->f_count++;
 289:         cp->c_ttyp = tp;
 290:         cp->c_line = tp->t_line;
 291:         cp->c_flags = XGRP+PORT;
 292:         u.u_r.r_val1 = cpx(cp);
 293:         return;
 294:     /*
 295: 	 * attach channel (arg 0) to group (arg 1)
 296: 	 */
 297:     case ATTACH:
 298:         cp = xcp(gp, vec.m_arg[0]);
 299:         if (cp==NULL)
 300:             goto bad;
 301:         u.u_r.r_val1 = cpx(cp);
 302:         wakeup((caddr_t)cp);
 303:         return;
 304:     case DETACH:
 305:         cp = xcp(gp, vec.m_arg[0]);
 306:         if (cp==NULL)
 307:             goto bad;
 308:         detach(cp);
 309:         return;
 310:     /*
 311: 	 * extract channel (arg 0) from group (arg 1).
 312: 	 */
 313:     case EXTR:
 314:         cp = xcp(gp, vec.m_arg[0]);
 315:         if (cp==NULL) {
 316:             goto bad;
 317:         }
 318:         if (cp->c_flags & ISGRP) {
 319:             mxfalloc(((struct group *)cp)->g_file);
 320:             return;
 321:         }
 322:         if ((fp = cp->c_fy) != NULL) {
 323:             mxfalloc(fp);
 324:             return;
 325:         }
 326:         if ((fp = falloc()) == NULL) {
 327:             return;
 328:         }
 329:         fp->f_inode = gip;
 330:         gip->i_count++;
 331:         fp->f_un.f_chan = cp;
 332:         fp->f_flag = (vec.m_arg[2]) ?
 333:                 (FREAD|FWRITE|FMPY) : (FREAD|FWRITE|FMPX);
 334:         cp->c_fy = fp;
 335:         return;
 336:     /*
 337: 	 * make new chan on group (arg 1)
 338: 	 */
 339:     case CHAN:
 340:         if ((cp=addch(gip, 0))==NULL)
 341:             goto bad;
 342:         cp->c_flags = XGRP;
 343:         cp->c_fy = NULL;
 344:         cp->c_ttyp = cp->c_ottyp = (struct tty *)cp;
 345:         cp->c_line = cp->c_oline = mpxline;
 346:         u.u_r.r_val1 = cpx(cp);
 347:         return;
 348:     /*
 349: 	 * connect fd (arg 0) to channel fd (arg 1)
 350: 	 * (arg 2 <  0) => fd to chan only
 351: 	 * (arg 2 >  0) => chan to fd only
 352: 	 * (arg 2 == 0) => both directions
 353: 	 */
 354:     case CONNECT:
 355:         if ((fp=getf(vec.m_arg[0]))==NULL)
 356:             goto bad;
 357:         if ((chfp=getf(vec.m_arg[1]))==NULL)
 358:             goto bad;
 359:         ip = fp->f_inode;
 360:         i = ip->i_mode&IFMT;
 361:         if (i!=IFCHR)
 362:             goto bad;
 363:         dev = (dev_t)ip->i_un.i_rdev;
 364:         tp = cdevsw[major(dev)].d_ttys;
 365:         if (tp==NULL)
 366:             goto bad;
 367:         tp = &tp[minor(dev)];
 368:         if (!(chfp->f_flag&FMPY)) {
 369:             goto bad;
 370:         }
 371:         cp = chfp->f_un.f_chan;
 372:         if (cp==NULL || cp->c_flags&PORT) {
 373:             goto bad;
 374:         }
 375:         i = vec.m_arg[2];
 376:         if (i>=0) {
 377:             cp->c_ottyp = tp;
 378:             cp->c_oline = tp->t_line;
 379:         }
 380:         if (i<=0)  {
 381:             tp->t_chan = cp;
 382:             cp->c_ttyp = tp;
 383:             cp->c_line = tp->t_line;
 384:         }
 385:         return;
 386:     case NPGRP: {
 387:         register struct proc *pp;
 388: 
 389:         if (gp != NULL) {
 390:             cp = xcp(gp, vec.m_arg[0]);
 391:             if (cp==NULL)
 392:                 goto bad;
 393:         }
 394:         pp = u.u_procp;
 395:         pp->p_pgrp = pp->p_pid;
 396:         if (vec.m_arg[2])
 397:             pp->p_pgrp = vec.m_arg[2];
 398:         if (gp != NULL)
 399:             cp->c_pgrp = pp->p_pgrp;
 400:         return;
 401:     }
 402:     case CSIG:
 403:         cp = xcp(gp, vec.m_arg[0]);
 404:         if (cp==NULL)
 405:             goto bad;
 406:         signal(cp->c_pgrp, vec.m_arg[2]);
 407:         return;
 408:     case DEBUG:
 409:         i = vec.m_arg[0];
 410:         if (i<0 || i>NDEBUGS)
 411:             return;
 412:         mcdebugs[i] = vec.m_arg[1];
 413:         if (i==ALL)
 414:             for(i=0;i<NDEBUGS;i++)
 415:                 mcdebugs[i] = vec.m_arg[1];
 416:         return;
 417:     default:
 418:         goto bad;
 419:     }
 420: }
 421: 
 422: detach(cp)
 423: register struct chan *cp;
 424: {
 425:     register struct group *gp;
 426:     register int i;
 427: 
 428:     if (cp->c_flags&ISGRP) {
 429:         gp = (struct group *)cp;
 430:         closef(gp->g_file);
 431:         i = ((struct group *)cp)->g_index;
 432:         gp->g_chans[i] = NULL;
 433:         return;
 434:     } else if (cp->c_flags&PORT && cp->c_ttyp != NULL) {
 435:         closef(cp->c_fy);
 436:         chdrain(cp);
 437:         chfree(cp);
 438:         return;
 439:     }
 440:     if (cp->c_fy && (cp->c_flags&WCLOSE)==0) {
 441:         cp->c_flags |= WCLOSE;
 442:         chwake(cp);
 443:     } else {
 444:         chdrain(cp);
 445:         chfree(cp);
 446:     }
 447: }
 448: 
 449: 
 450: mxfalloc(fp)
 451: register struct file *fp;
 452: {
 453: register i;
 454: 
 455:     if (fp==NULL) {
 456:         u.u_error = ENXIO;
 457:         return;
 458:     }
 459: 
 460:     i = ufalloc();
 461:     if (i < 0)
 462:         return;
 463:     u.u_ofile[i] = fp;
 464:     fp->f_count++;
 465:     u.u_r.r_val1 = i;
 466:     return;
 467: }
 468: 
 469: 
 470: 
 471: 
 472: mlink(sub,master)
 473: struct group *sub, *master;
 474: {
 475: register i;
 476: 
 477: 
 478:     for(i=0;i<NINDEX;i++) {
 479:         if (master->g_chans[i] != NULL)
 480:             continue;
 481:         master->g_chans[i] = (struct chan *)sub;
 482:         sub->g_group = master;
 483:         sub->g_index = i;
 484:         u.u_r.r_val1 = i;
 485:         return;
 486:     }
 487:     u.u_error = ENXIO;
 488:     return;
 489: }

Defined functions

addch defined in line 108; used 4 times
challoc defined in line 47; used 1 times
detach defined in line 422; used 2 times
gpalloc defined in line 89; used 1 times
mlink defined in line 472; used 1 times
mpxchan defined in line 139; never used
mxfalloc defined in line 450; used 2 times

Defined variables

chans defined in line 33; used 2 times
groups defined in line 35; used 4 times
mcdebugs defined in line 41; used 2 times
mpxdev defined in line 38; used 3 times
mpxline defined in line 36; used 2 times
schans defined in line 34; used 2 times

Defined struct's

a defined in line 150; used 2 times
  • in line 160(2)

Defined macros

KERNEL defined in line 9; never used
Last modified: 1979-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1184
Valid CSS Valid XHTML 1.0 Strict