Пример #1
0
/*
 *  called when a process writes to an interface's 'data'
 */
static void
ipifckick(void *x)
{
	Proc *up = externup();
	Conv *c = x;
	Block *bp;
	Ipifc *ifc;

	bp = qget(c->wq);
	if(bp == nil)
		return;

	ifc = (Ipifc*)c->ptcl;
	if(!canrlock(ifc)){
		freeb(bp);
		return;
	}
	if(waserror()){
		runlock(ifc);
		nexterror();
	}
	if(ifc->medium == nil || ifc->medium->pktin == nil)
		freeb(bp);
	else
		(*ifc->medium->pktin)(c->p->f, ifc, bp);
	runlock(ifc);
	poperror();
}
Пример #2
0
/*
 *  called when a process writes to an interface's 'data'
 */
static void ipifckick(void *x)
{
	ERRSTACK(1);
	struct conv *c = x;
	struct block *bp;
	struct Ipifc *ifc;

	bp = qget(c->wq);
	if (bp == NULL)
		return;

	ifc = (struct Ipifc *)c->ptcl;
	if (!canrlock(&ifc->rwlock)) {
		freeb(bp);
		return;
	}
	if (waserror()) {
		runlock(&ifc->rwlock);
		nexterror();
	}
	if (ifc->m == NULL || ifc->m->pktin == NULL)
		freeb(bp);
	else
		(*ifc->m->pktin) (c->p->f, ifc, bp);
	runlock(&ifc->rwlock);
	poperror();
}
Пример #3
0
static void
loopbackread(void *a)
{
	Ipifc *ifc;
	Block *bp;
	LB *lb;

	ifc = a;
	lb = ifc->arg;
	lb->readp = up;	/* hide identity under a rock for unbind */
	if(waserror()){
		lb->readp = 0;
		pexit("hangup", 1);
	}
	for(;;){
		bp = qbread(lb->q, Maxtu);
		if(bp == nil)
			continue;
		ifc->in++;
		if(!canrlock(ifc)){
			freeb(bp);
			continue;
		}
		if(waserror()){
			runlock(ifc);
			nexterror();
		}
		if(ifc->lifc == nil)
			freeb(bp);
		else
			ipiput4(lb->f, ifc, bp);
		runlock(ifc);
		poperror();
	}
}
Пример #4
0
void
isrwlocked(Memblk *f, int iswr)
{
	if(f->type != DBfile || f->mf == nil)
		fatal("isrwlocked: not a file  at pc %#p", getcallerpc(&f));
	if((iswr && canrlock(f->mf)) || (!iswr && canwlock(f->mf)))
		fatal("is%clocked at pc %#p", iswr?'w':'r', getcallerpc(&f));
}
Пример #5
0
static void pppreader(void *a)
{
	Ipifc *ifc;
	Block *bp;
	PPP *ppp;

	ifc = a;
	ppp = ifc->arg;
	ppp->readp = up;	/* hide identity under a rock for unbind */
	setpri(PriHi);

	if (waserror()) {
		netlog(ppp->f, Logppp, "pppreader: %I: %s\n", ppp->local,
			   up->env->errstr);
		ppp->readp = 0;
		deadremote(ifc);
		pexit("hangup", 1);
	}

	for (;;) {
		bp = pppread(ppp);
		if (bp == nil)
			error("hungup");
		if (!canrlock(ifc)) {
			freeb(bp);
			continue;
		}
		if (waserror()) {
			runlock(ifc);
			nexterror();
		}
		ifc->in++;
		if (ifc->lifc == nil)
			freeb(bp);
		else
			ipiput(ppp->f, ifc, bp);
		runlock(ifc);
		poperror();
	}
}
Пример #6
0
static void loopbackread(void *a)
{
	ERRSTACK(2);
	struct Ipifc *ifc;
	struct block *bp;
	LB *lb;

	ifc = a;
	lb = ifc->arg;
	lb->readp = current;	/* hide identity under a rock for unbind */
	if (waserror()) {
		lb->readp = 0;
		warn("loopbackread exits unexpectedly");
		return;
		poperror();
	}
	for (;;) {
		bp = qbread(lb->q, Maxtu);
		if (bp == NULL)
			continue;
		ifc->in++;
		if (!canrlock(&ifc->rwlock)) {
			freeb(bp);
			continue;
		}
		if (waserror()) {
			runlock(&ifc->rwlock);
			nexterror();
		}
		if (ifc->lifc == NULL)
			freeb(bp);
		else
			ipiput4(lb->f, ifc, bp);
		runlock(&ifc->rwlock);
		poperror();
	}
	poperror();
}
Пример #7
0
/*
 *   Print a string on the console.  Convert \n to \r\n for serial
 *   line consoles.  Locking of the queues is left up to the screen
 *   or uart code.  Multi-line messages to serial consoles may get
 *   interspersed with other messages.
 */
static void putstrn0(char *str, int n, int usewrite)
{
	int m;
	char *t;
	char buf[PRINTSIZE + 2];
	ERRSTACK(1);

	/*
	 *  if kprint is open, put the message there, otherwise
	 *  if there's an attached bit mapped display,
	 *  put the message there.
	 */
	m = consoleprint;
	if (canrlock(&(&kprintq)->rwlock)) {
		if (kprintq.q != NULL) {
			if (waserror()) {
				runlock(&(&kprintq)->rwlock);
				nexterror();
			}
			if (usewrite)
				qwrite(kprintq.q, str, n);
			else
				qiwrite(kprintq.q, str, n);
			poperror();
			m = 0;
		}
		runlock(&(&kprintq)->rwlock);
	}
	if (m && screenputs != NULL)
		screenputs(str, n);

	/*
	 *  if there's a serial line being used as a console,
	 *  put the message there.
	 */
	if (serwrite != NULL) {
		serwrite(str, n);
		return;
	}

	if (printq == 0)
		return;

	while (n > 0) {
		t = memchr(str, '\n', n);
		if (t && !kbd.raw) {
			m = t - str;
			if (m > sizeof(buf) - 2)
				m = sizeof(buf) - 2;
			memmove(buf, str, m);
			buf[m] = '\r';
			buf[m + 1] = '\n';
			if (usewrite)
				qwrite(printq, buf, m + 2);
			else
				qiwrite(printq, buf, m + 2);
			str = t + 1;
			n -= m + 1;
		} else {
			if (usewrite)
				qwrite(printq, str, n);
			else
				qiwrite(printq, str, n);
			break;
		}
	}
}
Пример #8
0
static uint64_t rxmitsols(struct arp *arp)
{
	unsigned int sflag;
	struct block *next, *xp;
	struct arpent *a, *b, **l;
	struct Fs *f;
	uint8_t ipsrc[IPaddrlen];
	struct Ipifc *ifc = NULL;
	uint64_t nrxt;

	qlock(&arp->qlock);
	f = arp->f;

	a = arp->rxmt;
	if (a == NULL) {
		nrxt = 0;
		goto dodrops;	/* return nrxt; */
	}
	nrxt = a->rtime - NOW;
	if (nrxt > 3 * ReTransTimer / 4)
		goto dodrops;	/* return nrxt; */

	for (; a; a = a->nextrxt) {
		ifc = a->ifc;
		assert(ifc != NULL);
		if ((a->rxtsrem <= 0) || !(canrlock(&ifc->rwlock))
			|| (a->ifcid != ifc->ifcid)) {
			xp = a->hold;
			a->hold = NULL;

			if (xp) {
				if (arp->dropl == NULL)
					arp->dropf = xp;
				else
					arp->dropl->list = xp;
			}

			cleanarpent(arp, a);
		} else
			break;
	}
	if (a == NULL)
		goto dodrops;

	qunlock(&arp->qlock);	/* for icmpns */
	if ((sflag = ipv6anylocal(ifc, ipsrc)) != SRC_UNSPEC)
		icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac);

	runlock(&ifc->rwlock);
	qlock(&arp->qlock);

	/* put to the end of re-transmit chain */
	l = &arp->rxmt;
	for (b = *l; b; b = b->nextrxt) {
		if (b == a) {
			*l = a->nextrxt;
			break;
		}
		l = &b->nextrxt;
	}
	for (b = *l; b; b = b->nextrxt) {
		l = &b->nextrxt;
	}
	*l = a;
	a->rxtsrem--;
	a->nextrxt = NULL;
	a->rtime = NOW + ReTransTimer;

	a = arp->rxmt;
	if (a == NULL)
		nrxt = 0;
	else
		nrxt = a->rtime - NOW;

dodrops:
	xp = arp->dropf;
	arp->dropf = NULL;
	arp->dropl = NULL;
	qunlock(&arp->qlock);

	for (; xp; xp = next) {
		next = xp->list;
		icmphostunr(f, ifc, xp, icmp6_adr_unreach, 1);
	}

	return nrxt;

}
Пример #9
0
static long
conswrite(Chan *c, void *va, long n, vlong offset)
{
	char buf[128], *a, ch;
	int x;

	if(c->qid.type & QTDIR)
		error(Eperm);

	switch((ulong)c->qid.path) {
	default:
		error(Egreg);

	case Qcons:
		if(canrlock(&kprintq.l)){
			if(kprintq.q != nil){
				if(waserror()){
					runlock(&kprintq.l);
					nexterror();
				}
				qwrite(kprintq.q, va, n);
				poperror();
				runlock(&kprintq.l);
				return n;
			}
			runlock(&kprintq.l);
		}
		return write(1, va, n);

	case Qsysctl:
		return sysconwrite(va, n);

	case Qconsctl:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = 0;
		for(a = buf; a;){
			if(strncmp(a, "rawon", 5) == 0){
				kbd.raw = 1;
				/* clumsy hack - wake up reader */
				ch = 0;
				qwrite(kbdq, &ch, 1);
			} else if(strncmp(buf, "rawoff", 6) == 0){
				kbd.raw = 0;
			}
			if((a = strchr(a, ' ')) != nil)
				a++;
		}
		break;

	case Qkeyboard:
		for(x=0; x<n; ) {
			Rune r;
			x += chartorune(&r, &((char*)va)[x]);
			gkbdputc(gkbdq, r);
		}
		break;

	case Qnull:
		break;

	case Qtime:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = '\0';
		timeoffset = strtoll(buf, 0, 0)-osusectime();
		break;

	case Qhostowner:
		if(!iseve())
			error(Eperm);
		if(offset != 0 || n >= sizeof(buf))
			error(Ebadarg);
		memmove(buf, va, n);
		buf[n] = '\0';
		if(n > 0 && buf[n-1] == '\n')
			buf[--n] = '\0';
		if(n == 0)
			error(Ebadarg);
		/* renameuser(eve, buf); */
		/* renameproguser(eve, buf); */
		kstrdup(&eve, buf);
		kstrdup(&up->env->user, buf);
		break;

	case Quser:
		if(!iseve())
			error(Eperm);
		if(offset != 0)
			error(Ebadarg);
		if(n <= 0 || n >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, va, n);
		buf[n] = '\0';
		if(n > 0 && buf[n-1] == '\n')
			buf[--n] = '\0';
		if(n == 0)
			error(Ebadarg);
		setid(buf, 0);
		break;

	case Qhoststdout:
		return write(1, va, n);

	case Qhoststderr:
		return write(2, va, n);

	case Qjit:
		if(n >= sizeof(buf))
			n = sizeof(buf)-1;
		strncpy(buf, va, n);
		buf[n] = '\0';
		x = atoi(buf);
		if(x < 0 || x > 9)
			error(Ebadarg);
		cflag = x;
		break;

	case Qsysname:
		if(offset != 0)
			error(Ebadarg);
		if(n < 0 || n >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, va, n);
		buf[n] = '\0';
		if(buf[n-1] == '\n')
			buf[n-1] = 0;
		kstrdup(&ossysname, buf);
		break;
	}
	return n;
}
Пример #10
0
long
conswrite(Chan *c, void *va, long count, vlong offset)
{
	char buf[128], *p;
	int x, y;

	USED(offset);

	if(c->qid.type & QTDIR)
		error(Eperm);

	switch((ulong)c->qid.path) {
	default:
		error(Egreg);
	case Qcons:
		if(canrlock(&kprintq.l)){
			if(kprintq.q != nil){
				if(waserror()){
					runlock(&kprintq.l);
					nexterror();
				}
				qwrite(kprintq.q, va, count);
				poperror();
				runlock(&kprintq.l);
				return count;
			}
			runlock(&kprintq.l);
		}
		return write(1, va, count);
	case Qsysctl:
		return sysconwrite(va, count);
	case Qconsctl:
		if(count >= sizeof(buf))
			count = sizeof(buf)-1;
		strncpy(buf, va, count);
		buf[count] = 0;
		if(strncmp(buf, "rawon", 5) == 0) {
			kbd.raw = 1;
			return count;
		}
		else
		if(strncmp(buf, "rawoff", 6) == 0) {
			kbd.raw = 0;
			return count;
		}
		error(Ebadctl);
	case Qkeyboard:
		for(x=0; x<count; ) {
			Rune r;
			x += chartorune(&r, &((char*)va)[x]);
			gkbdputc(gkbdq, r);
		}
		return count;
	case Qpointer:
		if(count > sizeof buf-1)
			count = sizeof buf -1;
		memmove(buf, va, count);
		buf[count] = 0;
		p = nil;
		x = strtoul(buf+1, &p, 0);
		if(p == nil || p == buf+1)
			error(Eshort);
		y = strtoul(p, 0, 0);
		setpointer(x, y);
		return count;
	case Qnull:
		return count;
	case Qpin:
		if(up->env->pgrp->pin != Nopin)
			error("pin already set");
		if(count >= sizeof(buf))
			count = sizeof(buf)-1;
		strncpy(buf, va, count);
		buf[count] = '\0';
		up->env->pgrp->pin = atoi(buf);
		return count;
	case Qtime:
		if(count >= sizeof(buf))
			count = sizeof(buf)-1;
		strncpy(buf, va, count);
		buf[count] = '\0';
		timeoffset = strtoll(buf, 0, 0)-osusectime();
		return count;
	case Quser:
		if(count >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, va, count);
		buf[count] = '\0';
		if(count > 0 && buf[count-1] == '\n')
			buf[--count] = '\0';
		if(count == 0)
			error(Ebadarg);
		if(strcmp(up->env->user, eve) != 0)
			error(Eperm);
		setid(buf, 0);
		return count;
	case Qhostowner:
		if(count >= sizeof(buf))
			error(Ebadarg);
		strncpy(buf, va, count);
		buf[count] = '\0';
		if(count > 0 && buf[count-1] == '\n')
			buf[--count] = '\0';
		if(count == 0)
			error(Ebadarg);
		if(strcmp(up->env->user, eve) != 0)
			error(Eperm);
		kstrdup(&eve, buf);
		return count;
	case Qhoststdout:
		return write(1, va, count);
	case Qhoststderr:
		return write(2, va, count);
	case Qjit:
		if(count >= sizeof(buf))
			count = sizeof(buf)-1;
		strncpy(buf, va, count);
		buf[count] = '\0';
		x = atoi(buf);
		if (x < 0 || x > 9)
			error(Ebadarg);
		cflag = x;
		return count;
	case Qsysname:
		if(count >= sizeof(buf))
			count = sizeof(buf)-1;
		strncpy(buf, va, count);
		buf[count] = '\0';
		kstrdup(&ossysname, buf);
		return count;
	case Qsnarf:
		if(offset+count >= SnarfSize)
			error(Etoobig);
		snarftab->qid.vers++;
		memmove((uchar*)(c->aux)+offset, va, count);
		return count;
	}
	return 0;
}