A loopback driver service rutinja visszaküldi az M_DATA, M_PROTO, M_PCPROTO üzeneteket, az M_IOCTL üzenetekben megkapott "parancsokat" végrehajtja, kezeli az M_FLUSH üzeneteket, és az egyéb üzeneteket eldobja. Az M_IOCTL üzenetek feldolgozását egy külön eljárás végzi.
lpbksrv(q)
queue_t *q;
{
mblk_t *bp;
/* A q pointer mindenkeppen a write queuera mutasson */
q = ((q)->q_flag&QREADR ? WR(q) : q);
while ((bp = getq(q)) != NULL) {
if ((bp->b_datap->db_type) < QPCTL && !canput(RD(q)->q_next) ) {
putbq(q, bp); /* Nincs hely az alacsony priotitasu uzenetnek */
return;
}
switch(bp->b_datap->db_type) {
case M_IOCTL: /* ioctl uzenetek */
lpbkioctl(q, bp);
break;
case M_DATA:
case M_PROTO:
case M_PCPROTO:
qreply(q, bp); /* Vissza a masik queuen */
break;
case M_FLUSH:
if (*bp->b_rptr & FLUSHW) {
flushq(q, FLUSHALL);
*bp->b_rptr &= \verb! !FLUSHW;
}
if (*bp->b_rptr & FLUSHR)
qreply(q,bp);
else freemsg(bp);
break;
default:
freemsg(bp);
break;
}
}
}
lpbkioctl(q, bp)
queue_t *q;
mblk_t *bp;
{
struct iocblk *iocbp;
iocbp = (struct iocblk *)bp->b_rptr;
switch(iocbp->ioc_cmd) {
case I_NOARG:
/*
* Minden OK, csak kuldjunk vissza egy visszajelzo uzenetet
*/
bp->b_datap->db_type = M_IOCACK;
qreply(q, bp);
return;
case I_ERROR:
/*
* Hibakodot is adjunk vissza
*/
iocbp->ioc_error = EPERM;
bp->b_datap->db_type = M_IOCACK;
qreply(q, bp);
return;
case I_ERRNAK:
/*
* Negativ visszajelzest kell generalni ...
*/
iocbp->ioc_error = EPERM;
bp->b_datap->db_type = M_IOCNAK;
qreply(q, bp);
return;
case I_SETHANG:
/*
* Kuldjunk fel egy visszajelzest, majd egy olyan uzenetet,
* amely M_HANGUP tipusu - be fog "fagyni" a stream.
*/
bp->b_datap->db_type = M_IOCACK;
qreply(q, bp);
putctl(RD(q)->q_next, M_HANGUP);
return;
default:
/*
* Negativ visszajelzes - ismeretlen ioctl hivas miatt
*/
bp->b_datap->db_type = M_IOCNAK;
qreply(q, bp);
return;
}
}