struct chan chans
[NCHANS
];
struct group
*groups
[NGROUPS
];
010000, 020000, 040000, 0100000
#define FPEND &file[NFILE]
struct chan
*xcp(),*addch(),*nextcp();
#define FP ((struct file *)cp)
register struct group
*gp
;
register struct file
*fp
;
register struct chan
*cp
;
if ((gp
=getmpx(dev
)) == NULL
) {
if (!(gp
->g_state
&INUSE
)) {
fp
= u
.u_ofile
[u
.u_r
.r_val1
];
if (fp
->f_inode
!= gp
->g_inode
) {
if ((cp
=addch(gp
->g_inode
,0)) == NULL
) {
cp
->c_ottyp
= cp
->c_ttyp
= (struct tty
*)cp
;
cp
->c_line
= cp
->c_oline
= mpxline
;
fp
->f_flag
|= FREAD
+FWRITE
;
if (gp
->g_inode
== mpxip
) {
scontrol(cp
, msg
+(cp
->c_index
<<8), u
.u_uid
);
sleep((caddr_t
)cp
,TTIPRI
);
if (cp
->c_flags
& WCLOSE
) {
cp
->c_pgrp
= u
.u_procp
->p_pgrp
;
register struct chan
*cp
;
u
.u_dirp
= (caddr_t
)u
.u_arg
[0];
while (np
< &mxnmbuf
[NMSIZE
]) {
register struct chan
*cp
;
register struct group
*gp
;
register struct inode
*ip
;
register struct file
*fp
;
if ((gp
=getmpx(dev
)) == NULL
)
if (ip
==NULL
|| (ip
->i_mode
&IFMT
)!=IFMPC
) {
if (cp
!=NULL
&& fmp
&& fmp
!=FMP
) {
for(fp
=file
; fp
< FPEND
; fp
++)
if(fp
->f_count
&& fp
->f_flag
&FMP
&& fp
->f_un
.f_chan
==cp
){
if ((cp
->c_flags
&WCLOSE
)==0) {
scontrol(cp
, M_CLOSE
, 0);
for(fp
=file
; fp
< FPEND
; fp
++) {
if (fp
->f_count
&& (fp
->f_flag
&FMP
)==FMP
&& fp
->f_inode
==ip
)
(void) detach(gp
->g_chans
[i
]);
groups
[minor(dev
)] = NULL
;
zero((caddr_t
)gp
, sizeof (struct group
));
ip
->i_mode
= IFREG
+ 0666;
char m_eot
[] ={ M_EOT
, 0, 0, 0};
* Mxread + mxwrite are entered from cdevsw
* for all read/write calls. Operations on
* an mpx file are handled here.
* Calls are made through linesw to handle actual
register struct group
*gp
;
register struct chan
*cp
;
if ((gp
=getmpx(dev
))==NULL
|| (FP
=getf(u
.u_arg
[0]))==NULL
) {
msread(fmp
, FP
->f_un
.f_chan
);
while (gp
->g_datq
== 0) {
sleep((caddr_t
)&gp
->g_datq
, TTIPRI
);
while (gp
->g_datq
&& u
.u_count
>= CNTLSIZ
+ 2) {
if (count
= cp
->c_ctlx
.c_cc
) {
more
= (*linesw
[cp
->c_line
].l_read
)(cp
->c_ttyp
);
scontrol(cp
, M_CLOSE
, 0);
IOMOVE((caddr_t
)m_eot
, sizeof m_eot
, B_READ
);
mxrstrt(cp
, &cp
->cx
.datq
, BLOCK
|ALT
);
if (u
.u_count
&& (xfr
&1)) {
(void) copyout((caddr_t
)&h
, base
, sizeof h
);
register struct chan
*cp
;
int ucount
, esc
, fmp
, burpcount
;
if ((gp
=getmpx(dev
))==NULL
|| (FP
=getf(u
.u_arg
[0]))==NULL
) {
mswrite(fmp
, FP
->f_un
.f_chan
);
while (u
.u_count
>= sizeof h
) {
IOMOVE((caddr_t
)&h
, sizeof h
, B_WRITE
);
if (cp
==NULL
|| cp
->c_flags
&ISGRP
) {
waddr
= (caddr_t
)(*linesw
[line
].l_write
)(tp
);
if (gp
->g_state
&ENAMSG
) {
scontrol(cp, M_BLK, u.u_count);
(void) copyout((caddr_t
)&h
, hbase
, sizeof h
);
* Mcread and mcwrite move data on an mpx file.
* Transfer addr and length is controlled by mxread/mxwrite.
* Kernel-to-Kernel and other special transfers are not
register struct chan
*cp
;
register struct clist
*q
;
q
= (cp
->c_ctlx
.c_cc
) ? &cp
->c_ctlx
: &cp
->cx
.datq
;
(void) mxmove(q
, B_READ
);
if (cp
->c_flags
&NMBUF
&& q
== &cp
->c_ctlx
) {
return(cp
->c_ctlx
.c_cc
+ cp
->c_ttyp
->t_rawq
.c_cc
); else
return(cp
->c_ctlx
.c_cc
+ cp
->cx
.datq
.c_cc
);
register struct chan
*cp
;
register struct clist
*q
;
if (q
->c_cc
> HIQ
|| (cp
->c_flags
&EOTMARK
)) {
(void) mxmove(q
, B_WRITE
);
* Msread and mswrite move bytes
* between user and non-multiplexed channel.
register struct chan
*cp
;
register struct clist
*q
;
q
= (fmp
&FMPX
) ? &cp
->cx
.datq
: &cp
->cy
.datq
;
if (cp
->c_flags
&WCLOSE
) {
if (cp
->c_flags
& EOTMARK
) {
sleep((caddr_t
)q
,TTIPRI
);
if (cp
->c_flags
&WCLOSE
) {
while (mxmove(q
, B_READ
) > 0)
register struct chan
*cp
;
register struct clist
*q
;
q
= (fmp
&FMPX
) ? &cp
->cy
.datq
: &cp
->cx
.datq
;
if (cp
->c_flags
&WCLOSE
) {
gsignal(cp
->c_pgrp
, SIGPIPE
);
if (q
->c_cc
>= HIQ
|| cp
->c_flags
&FBLOCK
) {
if (cp
->c_flags
&WCLOSE
) {
gsignal(cp
->c_pgrp
, SIGPIPE
);
sleep((caddr_t
)q
+1,TTOPRI
);
if (cp
->c_flags
&YGRP
) (void) sdata(cp
);
if (cp
->c_flags
&XGRP
) (void) sdata(cp
);
* move chars between clist and user space.
register struct clist
*q
;
cc
= MIN(u
.u_count
, sizeof cbuf
);
cc
= q_to_b(q
, cbuf
, cc
);
IOMOVE((caddr_t
)cbuf
, (unsigned)cc
, dir
);
cc
= b_to_q(cbuf
, cc
, q
);
register struct chan
*cp
;
register struct clist
*q
;
if (cp
->c_flags
&b
&& q
->c_cc
<LOQ
) {
wakeup((caddr_t
)q
+1); else
* called from driver start or xint routines
* to wakeup output sleeper.
register struct chan
*cp
;
if (cp
->c_flags
&(BLKMSG
)) {
register struct chan
*cp
;
IOMOVE((caddr_t
)&cmd
, sizeof cmd
, B_WRITE
);
* not ready to queue this up yet.
while (cp
->c_flags
& EOTMARK
)
sleep((caddr_t
)cp
, TTOPRI
);
wakeup((caddr_t
)&cp
->cy
.datq
);
if (cp
->c_flags
&SIOCTL
) {
IOMOVE((caddr_t
)&vec
, sizeof vec
, B_WRITE
);
(void) b_to_q((caddr_t
)&vec
, sizeof vec
, &cp
->c_ctly
);
mxioctl(dev
, cmd
, addr
, flag
)
if ((gp
=getmpx(dev
))==NULL
|| (fp
=getf(u
.u_arg
[0]))==NULL
) {
(void) copyin(addr
, (caddr_t
)&ctlbuf
.c_vec
, sizeof (struct sgttyb
));
sioctl(fp
->f_un
.f_chan
, (char *)&ctlbuf
, sizeof ctlbuf
);
(void) copyout((caddr_t
)&ctlbuf
, addr
, sizeof (struct sgttyb
));
register struct chan
*cp
;
wflag
= (cp
->c_flags
&WCLOSE
)==0;
if (tp
== NULL
) /* prob not required */
if (cp
->c_flags
&PORT
&& tp
->t_chan
== cp
) {
wflush(cp
,&cp
->cx
.datq
); else
if (!(cp
->c_flags
&YGRP
)) {
register struct chan
*cp
;
p
= (char *)&cp
->cx
.datq
;
wakeup((caddr_t
)p
); wakeup((caddr_t
)++p
); wakeup((caddr_t
)++p
);
p
= (char *)&cp
->cy
.datq
;
wakeup((caddr_t
)p
); wakeup((caddr_t
)++p
); wakeup((caddr_t
)++p
);
register struct chan
*cp
;
register struct group
*gp
;
if (cp
== gp
->g_chans
[i
]) {
register struct clist
*q
;
register struct chan
*cp
;
register struct clist
*q
;
if(q
->c_cc
&& (cp
->c_flags
&WCLOSE
) == 0) {
(void) tsleep((caddr_t
)q
+2, TTOPRI
, 30);
register struct chan
*cp
;
register struct clist
*q
;
register struct chan
*cp
;
register struct clist
*q
;
sleep((caddr_t
)q
+1, TTOPRI
);
(void) b_to_q(vec
, cc
, &cp
->c_ctlx
);
while (cp
->c_flags
&SIOCTL
) {
sleep((caddr_t
)cp
, TTOPRI
);
(void) q_to_b(&cp
->c_ctly
, vec
, cp
->c_ctly
.c_cc
);
register struct group
*gp
= (struct group
*)cp
;
register struct group
*ngp
;
if (ngp
==NULL
|| (ngp
->g_state
&ISGRP
)==0)
ngp
->g_datq
|= cmask
[gp
->g_index
];
wakeup((caddr_t
)&ngp
->g_datq
);
} while(ngp
=ngp
->g_group
);
register struct group
*gp
;
while (gp
->g_group
) gp
=gp
->g_group
;
for (i
=0;i
<NLEVELS
;i
++) {
if (gp
==NULL
|| (gp
->g_state
&ISGRP
)==0)
return((struct chan
*)NULL
);
gp
= (struct group
*)gp
->g_chans
[x
&017];
return((struct chan
*)gp
);
register struct chan
*cp
;
register struct group
*gp
;
x
= (-1<<4) + cp
->c_index
;
register struct group
*gp
;
register struct group
*lgp
, *ngp
;
while ((gp
->g_datq
& cmask
[gp
->g_rot
]) == 0) {
gp
->g_rot
= (gp
->g_rot
+1)%NINDEX
;
gp
= (struct group
*)gp
->g_chans
[gp
->g_rot
];
} while (gp
!=NULL
&& gp
->g_state
&ISGRP
);
lgp
->g_datq
&= ~cmask
[lgp
->g_rot
];
lgp
->g_rot
= (lgp
->g_rot
+1)%NINDEX
;
while (ngp
=lgp
->g_group
) {
ngp
->g_datq
&= ~cmask
[lgp
->g_index
];
return((struct chan
*)gp
);
register struct chan
*cp
;
register struct group
*gp
;
for(gp
=cp
->c_group
;gp
;gp
=gp
->g_group
)
if(gp
->g_state
& ENAMSG
)return(1);