Esempio n. 1
0
mblk_t *copymsg(mblk_t *mp)
{
	mblk_t *newm=0,*m;
	m=newm=copyb(mp);
	mp=mp->b_cont;
	while(mp!=NULL){
		m->b_cont=copyb(mp);
		m=m->b_cont;
		mp=mp->b_cont;
	}
	return newm;
}
Esempio n. 2
0
casede(){
	register i, req;
	register filep savoff;
	extern filep finds();

	if(dip != d)wbfl();
	req = '.';
	lgf++;
	skip();
	if((i=getrq())==0)goto de1;
	if((offset=finds(i)) == 0)goto de1;
	if(ds)copys();
		else req = copyb();
	wbfl();
	clrmn(oldmn);
	if(newmn)contab[newmn].rq = i | MMASK;
	if(apptr){
		savoff = offset;
		offset = apptr;
		wbt(IMP);
		offset = savoff;
	}
	offset = dip->op;
	if(req != '.')control(req,1);
de1:
	ds = app = 0;
	return;
}
Esempio n. 3
0
void caseig(void)
{
	int i;
	Offset oldoff = offset;

	offset = 0;
	i = copyb();
	offset = oldoff;
	if (i != '.')
		control(i, 1);
}
Esempio n. 4
0
caseig()
{
	register i;
	register filep oldoff;

	oldoff = offset;
	offset = 0;
	i = copyb();
	offset = oldoff;
	if (i != '.')
		control(i, 1);
}
Esempio n. 5
0
void casede(void)
{
	int i, req;
	Offset savoff;

	req = '.';
	lgf++;
	skip();
	if ((i = getrq()) == 0)
		goto de1;
	if ((offset = finds(i)) == 0)
		goto de1;
	if (newmn)
		savslot = newmn;
	else
		savslot = findmn(i);
	savname = i;
	if (ds)
		copys();
	else
		req = copyb();
	clrmn(oldmn);
	if (newmn) {
		if (contabp[newmn].rq)
			munhash(&contabp[newmn]);
		contabp[newmn].rq = i;
		maddhash(&contabp[newmn]);

	}
	if (apptr) {
		savoff = offset;
		offset = apptr;
		wbf((Tchar) IMP);
		offset = savoff;
	}
	offset = dip->op;
	if (req != '.')
		control(req, 1);
de1:
	ds = app = 0;
}
Esempio n. 6
0
static void
handle_mflush(queue_t *qp, mblk_t *mp)
{
	mblk_t *nmp;
	DBG1("M_FLUSH on %s side", zc_side(qp));

	if (*mp->b_rptr & FLUSHW) {
		DBG1("M_FLUSH, FLUSHW, %s side", zc_side(qp));
		flushq(qp, FLUSHDATA);
		*mp->b_rptr &= ~FLUSHW;
		if ((*mp->b_rptr & FLUSHR) == 0) {
			/*
			 * FLUSHW only. Change to FLUSHR and putnext other side,
			 * then we are done.
			 */
			*mp->b_rptr |= FLUSHR;
			if (zc_switch(RD(qp)) != NULL) {
				putnext(zc_switch(RD(qp)), mp);
				return;
			}
		} else if ((zc_switch(RD(qp)) != NULL) &&
		    (nmp = copyb(mp)) != NULL) {
			/*
			 * It is a FLUSHRW; we copy the mblk and send
			 * it to the other side, since we still need to use
			 * the mblk in FLUSHR processing, below.
			 */
			putnext(zc_switch(RD(qp)), nmp);
		}
	}

	if (*mp->b_rptr & FLUSHR) {
		DBG("qreply(qp) turning FLUSHR around\n");
		qreply(qp, mp);
		return;
	}
	freemsg(mp);
}
Esempio n. 7
0
caseig(){
	register i;

	offset = 0;
	if((i = copyb()) != '.')control(i,1);
}
Esempio n. 8
0
static int
pckt_r_msg(queue_t *q, mblk_t *mp)
{
	mblk_t *bp, *fp;
	struct pckt *p = PCKT_PRIV(q);

	switch (mp->b_datap->db_type) {
	case M_FLUSH:
		/* The pseudo-terminal device, pty(4), slave side reverses the sense of the
		   M_FLUSH(9) flush bits so that they can be used directly by the master side
		   Stream head. This is similar to the pipemod(4) module. To provide an
		   encapsulated message that contains flush bits that are exactly as they were
		   issued by the user of the slave side of the pty(4), pckt reverses the FLUSHR and 
		   FLUSHW bits before packetizing the M_FLUSH(9) message. Also, because every
		   Stream must respond to M_FLUSH(9) by flushing queues, pckt also passes the
		   M_FLUSH(9) message to the Stream head. However, to preserve packetized messages
		   that may be sitting on the Stream head read queue, the read side is not flushed
		   and the FLUSHR bit in any M_FLUSH(9) message passed to the Stream head will be
		   cleared. The result is as follows, depending on the value of the M_FLUSH(9)
		   bits: FLUSHR: The bits are set to FLUSHW and the message is packetized. No
		   M_FLUSH(9) message is sent to the Stream head. FLUSHW: The bits are set to
		   FLUSHR and the message is packetized. An M_FLUSH(9) message is sent to the
		   Stream head containing the FLUSHW flag. FLUSHRW: The bits are set to FLUSHRW and 
		   the message is packetized. An M_FLUSH(9) message is sent to the Stream head
		   containing only the FLUSHW flag.  */
		if (!(bp = allocb(1, BPRI_MED)))
			goto bufcall;
		if ((mp->b_rptr[0] & FLUSHW)) {
			if (!(fp = copyb(mp))) {
				freeb(bp);
				goto bufcall;
			}
			fp->b_rptr[0] &= ~FLUSHR;
			putnext(q, fp);
		} else {
			fp = NULL;
		}
		switch (mp->b_rptr[0] & (FLUSHR | FLUSHW)) {
		case FLUSHR:
			mp->b_rptr[0] &= ~FLUSHR;
			mp->b_rptr[0] |= FLUSHW;
			break;
		case FLUSHW:
			mp->b_rptr[0] &= ~FLUSHW;
			mp->b_rptr[0] |= FLUSHR;
			break;
		}
		goto finish_it;
	case M_IOCTL:
		/* The M_IOCTL(9) message is packetized as normal on 32-bit systems. On 64-bit
		   systems, where the user process that pushed the pckt module on the master side
		   of the pseudo-terminal, pty(4), device is a 32-bit process, the iocblk(9)
		   structure contained in the message block is transformed by the pckt module into
		   a 32-bit representation of the iocblk(9) structure (struct iocblk32) before
		   being packetized.  */
		if ((p->flags & FILP32)) {
			struct iocblk *ioc;
			struct iocblk32 ioc32 = { 0, };

			/* Need to convert from native to ILP32. */
			if ((bp = allocb(1, BPRI_MED)) == NULL)
				goto bufcall;
			ioc = (typeof(ioc)) mp->b_rptr;
			ioc32.ioc_cmd32 = ioc->ioc_cmd;
			ioc32.ioc_cr32 = (uint32_t) (long) ioc->ioc_cr;
			ioc32.ioc_id32 = ioc->ioc_id;
			ioc32.ioc_count32 = ioc->ioc_count;
			ioc32.ioc_error32 = ioc->ioc_error;
			ioc32.ioc_rval32 = ioc->ioc_rval;
			ioc32.ioc_filler32[0] = ioc->ioc_filler[0];
			ioc32.ioc_filler32[1] = ioc->ioc_filler[1];
			ioc32.ioc_filler32[2] = ioc->ioc_filler[2];
			ioc32.ioc_filler32[3] = ioc->ioc_filler[3];
			mp->b_wptr = mp->b_wptr - sizeof(*ioc) + sizeof(ioc32);
			*(struct iocblk32 *) mp->b_rptr = ioc32;
			goto finish_it;
		}
		goto pass_it;
	case M_READ:
		/* The M_READ(9) message is packetized as normal on 32-bit systems.  On 64-bit
		   systems, where the user process that pushed the pckt module on the master side
		   of the pseudo-terminal, pty(4), device is a 32-bit process, the size_t count
		   contained in the message block is transformed by the pckt module into a 32-bit
		   representation of the size_t (size32_t) before being packetized.  */
		if ((p->flags & FILP32)) {
			uint32_t size32;

			/* Need to convert from native to ILP32. */
			if ((bp = allocb(1, BPRI_MED)) == NULL)
				goto bufcall;
			size32 = *(size_t *) mp->b_rptr;
			*(uint32_t *) mp->b_rptr = size32;
			mp->b_wptr = mp->b_wptr - sizeof(size_t) + sizeof(uint32_t);
			goto finish_it;
		}
		goto pass_it;
	case M_PROTO:
	case M_PCPROTO:
	case M_STOP:
	case M_STOPI:
	case M_START:
	case M_STARTI:
	case M_DATA:
	      pass_it:
		/* Problem: UnixWare says 4 bytes.  Solaris says 1 byte.  The user must determine
		   the size and alignment of the message type by the length of the control part.
		   We'll go with 1 byte.  On little endian it should line up. */
		if ((bp = allocb(1, BPRI_MED))) {
		      finish_it:
			bp->b_datap->db_type = M_PROTO;
			bp->b_wptr[0] = mp->b_datap->db_type;
			bp->b_wptr++;
			mp->b_datap->db_type = M_DATA;
			bp->b_cont = mp;
			putnext(q, bp);
			return (1);
		}
	      bufcall:
		noenable(q);
		if (!(p->bufcall = bufcall(1, BPRI_MED, pckt_enable, (long) q)))
			qenable(q);	/* spin through service procedure */
		return (0);
	default:
		putnext(q, mp);
		return (1);
	}
}
Esempio n. 9
0
/*
 * Multidata message block copy routine, called by copyb() when it
 * encounters a M_MULTIDATA data block type.  This routine should
 * not be called by anyone other than copyb(), since it may go away
 * (read: become static to this module) once some sort of copy callback
 * routine is made available.
 */
mblk_t *
mmd_copy(mblk_t *bp, int kmflags)
{
	multidata_t *mmd, *n_mmd;
	mblk_t *n_hbuf = NULL, *n_pbuf[MULTIDATA_MAX_PBUFS];
	mblk_t **pmp_last = &n_pbuf[MULTIDATA_MAX_PBUFS - 1];
	mblk_t **pmp;
	mblk_t *n_bp = NULL;
	pdesc_t *pd;
	uint_t n_pbuf_cnt = 0;
	int idx, i;

#define	FREE_PBUFS() {					\
	for (pmp = &n_pbuf[0]; pmp <= pmp_last; pmp++)	\
		if (*pmp != NULL) freeb(*pmp);		\
}

#define	REL_OFF(p, base, n_base)			\
	((uchar_t *)(n_base) + ((uchar_t *)(p) - (uchar_t *)base))

	ASSERT(bp != NULL && DB_TYPE(bp) == M_MULTIDATA);
	mmd = mmd_getmultidata(bp);

	/* copy the header buffer */
	if (mmd->mmd_hbuf != NULL && (n_hbuf = copyb(mmd->mmd_hbuf)) == NULL)
		return (NULL);

	/* copy the payload buffer(s) */
	mutex_enter(&mmd->mmd_pd_slab_lock);
	bzero((void *)&n_pbuf[0], sizeof (mblk_t *) * MULTIDATA_MAX_PBUFS);
	n_pbuf_cnt = mmd->mmd_pbuf_cnt;
	for (i = 0; i < n_pbuf_cnt; i++) {
		ASSERT(mmd->mmd_pbuf[i] != NULL);
		n_pbuf[i] = copyb(mmd->mmd_pbuf[i]);
		if (n_pbuf[i] == NULL) {
			FREE_PBUFS();
			mutex_exit(&mmd->mmd_pd_slab_lock);
			return (NULL);
		}
	}

	/* allocate new Multidata */
	n_mmd = mmd_alloc(n_hbuf, &n_bp, kmflags);
	if (n_mmd == NULL) {
		if (n_hbuf != NULL)
			freeb(n_hbuf);
		if (n_pbuf_cnt != 0)
			FREE_PBUFS();
		mutex_exit(&mmd->mmd_pd_slab_lock);
		return (NULL);
	}

	/*
	 * Add payload buffer(s); upon success, leave n_pbuf array
	 * alone, as the newly-created Multidata had already contained
	 * the mblk pointers stored in the array.  These will be freed
	 * along with the Multidata itself.
	 */
	for (i = 0, pmp = &n_pbuf[0]; i < n_pbuf_cnt; i++, pmp++) {
		idx = mmd_addpldbuf(n_mmd, *pmp);
		if (idx < 0) {
			FREE_PBUFS();
			freeb(n_bp);
			mutex_exit(&mmd->mmd_pd_slab_lock);
			return (NULL);
		}
	}

	/* copy over global attributes */
	if (mmd->mmd_pattbl != NULL &&
	    mmd_copy_pattbl(mmd->mmd_pattbl, n_mmd, NULL, kmflags) < 0) {
		freeb(n_bp);
		mutex_exit(&mmd->mmd_pd_slab_lock);
		return (NULL);
	}

	/* copy over packet descriptors and their atttributes */
	pd = mmd_getpdesc(mmd, NULL, NULL, 1, B_TRUE);	/* first pdesc */
	while (pd != NULL) {
		pdesc_t *n_pd;
		pdescinfo_t *pdi, n_pdi;
		uchar_t *n_base, *base;
		pdesc_t *pd_next;

		/* next pdesc */
		pd_next = mmd_getpdesc(pd->pd_slab->pds_mmd, pd, NULL,
		    1, B_TRUE);

		/* skip if already removed */
		if (pd->pd_flags & PDESC_REM_DEFER) {
			pd = pd_next;
			continue;
		}

		pdi = &(pd->pd_pdi);
		bzero(&n_pdi, sizeof (n_pdi));

		/*
		 * Calculate new descriptor values based on the offset of
		 * each pointer relative to the associated buffer(s).
		 */
		ASSERT(pdi->flags & PDESC_HAS_REF);
		if (pdi->flags & PDESC_HBUF_REF) {
			n_base = n_mmd->mmd_hbuf->b_rptr;
			base = mmd->mmd_hbuf->b_rptr;

			n_pdi.flags |= PDESC_HBUF_REF;
			n_pdi.hdr_base = REL_OFF(pdi->hdr_base, base, n_base);
			n_pdi.hdr_rptr = REL_OFF(pdi->hdr_rptr, base, n_base);
			n_pdi.hdr_wptr = REL_OFF(pdi->hdr_wptr, base, n_base);
			n_pdi.hdr_lim = REL_OFF(pdi->hdr_lim, base, n_base);
		}

		if (pdi->flags & PDESC_PBUF_REF) {
			n_pdi.flags |= PDESC_PBUF_REF;
			n_pdi.pld_cnt = pdi->pld_cnt;

			for (i = 0; i < pdi->pld_cnt; i++) {
				idx = pdi->pld_ary[i].pld_pbuf_idx;
				ASSERT(idx < MULTIDATA_MAX_PBUFS);
				ASSERT(n_mmd->mmd_pbuf[idx] != NULL);
				ASSERT(mmd->mmd_pbuf[idx] != NULL);

				n_base = n_mmd->mmd_pbuf[idx]->b_rptr;
				base = mmd->mmd_pbuf[idx]->b_rptr;

				n_pdi.pld_ary[i].pld_pbuf_idx = idx;

				/*
				 * We can't copy the pointers just like that,
				 * so calculate the relative offset.
				 */
				n_pdi.pld_ary[i].pld_rptr =
				    REL_OFF(pdi->pld_ary[i].pld_rptr,
					base, n_base);
				n_pdi.pld_ary[i].pld_wptr =
				    REL_OFF(pdi->pld_ary[i].pld_wptr,
					base, n_base);
			}
		}

		/* add the new descriptor to the new Multidata */
		n_pd = mmd_addpdesc_int(n_mmd, &n_pdi, NULL, kmflags);

		if (n_pd == NULL || (pd->pd_pattbl != NULL &&
		    mmd_copy_pattbl(pd->pd_pattbl, n_mmd, n_pd, kmflags) < 0)) {
			freeb(n_bp);
			mutex_exit(&mmd->mmd_pd_slab_lock);
			return (NULL);
		}

		pd = pd_next;
	}
#undef REL_OFF
#undef FREE_PBUFS

	mutex_exit(&mmd->mmd_pd_slab_lock);
	return (n_bp);
}