* Multiplexor: clist version
* requires a line in cdevsw -
* mxopen, mxclose, mxread, mxwrite, mxioctl, 0,
* also requires a line in linesw -
* mxopen, mxclose, mcread, mcwrite, mxioctl, nulldev, nulldev,
* The linesw entry for mpx should be the last one in the table.
* 'nldisp' (number of line disciplines) should not include the
* mpx line. This is to prevent mpx from being enabled by an ioctl.
struct chan chans
[NCHANS
];
struct schan schans
[NPORTS
];
struct group
*groups
[NGROUPS
];
* Allocate a channel, set c_index to index.
register struct chan
*cp
;
for(i
=0;i
<((isport
)?NPORTS
:NCHANS
);i
++) {
cp
= (isport
)? (struct chan
*)(schans
+i
): chans
+i
;
if(cp
->c_group
== NULL
) {
* Allocate a group table cell.
for (i
=NGROUPS
-1; i
>=0; i
--)
* Add a channel to the group in
register struct chan
*cp
;
register struct group
*gp
;
cp
= (struct chan
*)gp
->g_chans
[i
];
if ((cp
=challoc(i
, isport
)) != NULL
) {
extern mxopen(), mcread(), sdata(), scontrol();
struct file
*fp
, *chfp
, *gfp
;
uap
= (struct a
*)u
.u_ap
;
(void) copyin((caddr_t
)uap
->argvec
, (caddr_t
)&vec
, sizeof vec
);
gp
= NULL
; gfp
= NULL
; cp
= NULL
;
gfp
= getf(vec
.m_arg
[1]);
if (gp
->g_inode
!= gip
) {
for (i
=0; linesw
[i
].l_open
; i
++) {
if (linesw
[i
].l_read
==mcread
) {
for (i
=0; cdevsw
[i
].d_open
; i
++) {
if (cdevsw
[i
].d_open
==mxopen
) {
if ((ip
=ialloc(pipedev
))==NULL
)
ip
->i_mode
= ((vec
.m_arg
[1]&0777)+IFMPC
) & ~u
.u_cmask
;
ip
->i_flag
= IACC
|IUPD
|ICHG
;
if (i
==IFMPC
|| i
==IFMPB
) {
i
= minor(ip
->i_un
.i_rdev
);
if (gp
&& gp
->g_inode
==ip
)
ip
= maknode((vec
.m_arg
[1]&0777)+IFMPC
);
if ((fp
=falloc()) == NULL
) {
ip
->i_un
.i_rdev
= (daddr_t
)(mpxdev
+i
);
gp
->g_state
= INUSE
|ISGRP
;
fp
->f_flag
= FREAD
|FWRITE
|FMP
;
* join file descriptor (arg 0) to group (arg 1)
if ((fp
=getf(vec
.m_arg
[0]))==NULL
)
switch (ip
->i_mode
& IFMT
) {
if ((fp
->f_flag
&FMP
) != FMP
) {
if (mtree(ngp
, gp
) == NULL
)
u
.u_r
.r_val1
= cpx((struct chan
*)ngp
);
dev
= (dev_t
)ip
->i_un
.i_rdev
;
tp
= cdevsw
[major(dev
)].d_ttys
;
if ((cp
=addch(gip
, 1))==NULL
) {
* Attach channel (arg 0) to group (arg 1).
cp
= xcp(gp
, vec
.m_arg
[0]);
if (cp
==NULL
|| cp
->c_flags
&ISGRP
) {
cp
= xcp(gp
, vec
.m_arg
[0]);
* Extract channel (arg 0) from group (arg 1).
cp
= xcp(gp
, vec
.m_arg
[0]);
if (cp
->c_flags
& ISGRP
) {
(void) mxfalloc(((struct group
*)cp
)->g_file
);
if ((fp
=cp
->c_fy
) != NULL
) {
if ((fp
=falloc()) == NULL
)
fp
->f_flag
= (vec
.m_arg
[2]) ?
(FREAD
|FWRITE
|FMPY
) : (FREAD
|FWRITE
|FMPX
);
* Make new chan on group (arg 1).
if((gfp
->f_flag
&FMP
)==FMP
)cp
= addch(gip
, 0);
cp
->c_ttyp
= cp
->c_ottyp
= (struct tty
*)cp
;
cp
->c_line
= cp
->c_oline
= mpxline
;
* Connect fd (arg 0) to channel fd (arg 1).
* (arg 2 < 0) => fd to chan only
* (arg 2 > 0) => chan to fd only
* (arg 2 == 0) => both directions
if ((fp
=getf(vec
.m_arg
[0]))==NULL
)
if ((chfp
=getf(vec
.m_arg
[1]))==NULL
)
dev
= (dev_t
)ip
->i_un
.i_rdev
;
tp
= cdevsw
[major(dev
)].d_ttys
;
if (!(chfp
->f_flag
&FMPY
)) {
if (cp
==NULL
|| cp
->c_flags
&PORT
) {
cp
->c_oline
= tp
->t_line
;
register struct proc
*pp
;
cp
= xcp(gp
, vec
.m_arg
[0]);
pp
->p_pgrp
= vec
.m_arg
[2];
u
.u_r
.r_val1
= pp
->p_pgrp
;
cp
= xcp(gp
, vec
.m_arg
[0]);
gsignal(cp
->c_pgrp
, vec
.m_arg
[2]);
u
.u_r
.r_val1
= vec
.m_arg
[2];
mcdebugs
[i
] = vec
.m_arg
[1];
mcdebugs
[i
] = vec
.m_arg
[1];
register struct chan
*cp
;
register struct group
*master
,*sub
;
sub
= (struct group
*)cp
;
master
= sub
->g_group
; index
= sub
->g_index
;
master
->g_chans
[index
] = NULL
;
} else if (cp
->c_flags
&PORT
&& cp
->c_ttyp
!= NULL
) {
if (cp
->c_flags
& WCLOSE
) {
register struct file
*fp
;
* Grow a branch on a tree.
register struct group
*sub
, *master
;
if ((mtresiz
=mup(master
,sub
)) == NULL
) {
if ((stresiz
=mdown(sub
,master
)) <= 0) {
if (sub
->g_group
!= NULL
) {
if (stresiz
+mtresiz
> NLEVELS
) {
if (master
->g_chans
[i
] != NULL
)
master
->g_chans
[i
] = (struct chan
*)sub
;
struct group
*master
, *sub
;
register struct group
*top
;
struct group
*sub
, *master
;
register int maxdepth
, i
, depth
;
if(sub
== (struct group
*)NULL
|| (sub
->g_state
&ISGRP
) == 0)
for(i
=0; i
<NINDEX
; i
++) {
if((depth
=mdown((struct group
*)sub
->g_chans
[i
],master
)) == -1)
maxdepth
= (depth
>maxdepth
) ? depth
: maxdepth
;