Пример #1
0
static int32_t
kbinread(Chan *c, void *a, int32_t n, int64_t _)
{
	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, kbintab, nelem(kbintab), devgen);
	return 0;
}
Пример #2
0
static long
pointerread(Chan* c, void* a, long n, vlong)
{
	Pointer mt;
	char tmp[128];
	int l;

	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, a, n, pointertab, nelem(pointertab), devgen);
	case Qpointer:
		qlock(&mouse.q);
		if(waserror()) {
			qunlock(&mouse.q);
			nexterror();
		}
		mt = mouseconsume();
		poperror();
		qunlock(&mouse.q);
		l = sprint(tmp, "m%11d %11d %11d %11lud ", mt.x, mt.y, mt.b, mt.msec);
		if(l < n)
			n = l;
		memmove(a, tmp, n);
		break;
	case Qcursor:
		/* TO DO: interpret data written as Image; give to drawcursor() */
		break;
	default:
		n=0;
		break;
	}
	return n;
}
Пример #3
0
static int32_t
envread(Chan *c, void *a, int32_t n, int64_t off)
{
	Egrp *eg;
	Evalue *e;
	int32_t offset;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, 0, 0, envgen);

	eg = envgrp(c);
	rlock(&eg->rwl);
	e = envlookup(eg, nil, c->qid.path);
	if(e == 0) {
		runlock(&eg->rwl);
		error(Enonexist);
	}

	offset = off;
	if(offset > e->len)	/* protects against overflow converting int64_t to long */
		n = 0;
	else if(offset + n > e->len)
		n = e->len - offset;
	if(n <= 0)
		n = 0;
	else
		memmove(a, e->value+offset, n);
	runlock(&eg->rwl);
	return n;
}
Пример #4
0
static long
eiaread(Chan *c, void *buf, long n, vlong offset)
{
	ssize_t cnt;
	int port = NETID(c->qid.path);

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
	  	osenter(); 
		cnt = read(eia[port].fd, buf, n);
		osleave(); 
		if(cnt == -1)
			oserror();
		return cnt;
	case Nctlqid:
		return readnum(offset, buf, n, port, NUMSIZE);
	case Nstatqid:
		return rdstat(port, buf, n, offset);
	}

	return 0;
}
Пример #5
0
static long
regressread(struct chan *c, void *va, long n, int64_t off)
{
	uint64_t w, *bp;
	char *a, *ea;
	uintptr_t offset = off;
	uint64_t pc;
	int snp_ret, ret = 0;

	switch((int)c->qid.path){
	case Monitordirqid:
		n = devdirread(c, va, n, regresstab, ARRAY_SIZE(regresstab), devgen);
		break;

	case Monitorctlqid:
		n = readstr(off, va, n, ctlcommands);
		break;

	case Monitordataqid:
		if (regress.monitor) {
			printd("monitordataqid: regress.monitor %p len %p\n", regress.monitor, qlen(kprof.monitor));
			if (qlen(regress.monitor) > 0)
				n = qread(regress.monitor, va, n);
			else
				n = 0;
		} else
			error(EFAIL, "no monitor queue");
		break;
	default:
		n = 0;
		break;
	}
	return n;
}
Пример #6
0
static long
wdread(Chan* c, void* a, long n, vlong off)
{
	ulong offset = off;
	char *p;

	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, a, n, wddir, nelem(wddir), devgen);

	case Qwdctl:
		if(wd == nil || wd->stat == nil)
			return 0;

		p = malloc(READSTR);
		if(p == nil)
			error(Enomem);
		if(waserror()){
			free(p);
			nexterror();
		}

		wd->stat(p, p + READSTR);
		n = readstr(offset, a, n, p);
		free(p);
		poperror();
		return n;

	default:
		error(Egreg);
		break;
	}
	return 0;
}
Пример #7
0
static long
eiaread(Chan *c, void *buf, long n, vlong offset)
{
	DWORD cnt;
	int port = NETID(c->qid.path);
	BOOL good;

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
		cnt = 0;
		// if ReadFile timeouts and cnt==0 then just re-read
		// this will give osleave() a chance to detect an
		// interruption (i.e. killprog)
		while(cnt==0) {
  			osenter(); 
			good = ReadFile(eia[port].comfh, buf, n, &cnt, NULL);
			SleepEx(0,FALSE);  //allow another thread access to port
			osleave();
			if(!good)
				oserror();
		}
		return cnt;
	case Nctlqid:
		return readnum(offset, buf, n, eia[port].id, NUMSIZE);
	case Nstatqid:
		return rdstat(port, buf, n, offset);
	}

	return 0;
}
Пример #8
0
static size_t ver_read(struct chan *c, void *va, size_t n, off64_t off)
{
	switch ((int) c->qid.path) {
	case Kverdirqid:
		return devdirread(c, va, n, vertab, ARRAY_SIZE(vertab), devgen);
	case Kverbuildid:
		return read_buildid(va, n, off);
	case Kverdate:
		if (build_info_date)
			return ver_emit_nlstr(va, build_info_date, n,
					      (long) off);
		break;
	case Kvercommitid:
		if (build_info_commitid)
			return ver_emit_nlstr(va, build_info_commitid, n,
					      (long) off);
		break;
	case Kverversion:
		if (build_info_version)
			return ver_emit_nlstr(va, build_info_version, n,
					      (long) off);
		break;
	case Kverversionname:
		if (build_info_version_name)
			return ver_emit_nlstr(va, build_info_version_name, n,
					      (long) off);
		break;
	case Kverkconfig:
		return readstr(off, va, n, __kconfig_str);
	default:
		error(EINVAL, ERROR_FIXME);
	}

	return 0;
}
Пример #9
0
static long
envread(Chan *c, void *a, long n, vlong offset)
{
	Egrp *eg;
	Evalue *e;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, 0, 0, envgen);
	eg = up->env->egrp;
	qlock(&eg->l);
	for(e = eg->entries; e != nil; e = e->next)
		if(e->qid.path == c->qid.path)
			break;
	if(e == nil) {
		qunlock(&eg->l);
		error(Enonexist);
	}
	if(offset > e->len)	/* protects against overflow converting vlong to ulong */
		n = 0;
	else if(offset + n > e->len)
		n = e->len - offset;
	if(n <= 0)
		n = 0;
	else
		memmove(a, e->val+offset, n);
	qunlock(&eg->l);
	return n;
}
Пример #10
0
static long	 
rtcread(Chan *c, void *buf, long n, vlong offset)
{
	ulong t, ot;

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, rtcdir, NRTC, devgen);

	switch((ulong)c->qid.path){
	case Qrtc:
		qlock(&rtclock);
		t = rtctime();
		do{
			ot = t;
			t = rtctime();	/* make sure there's no skew */
		}while(t != ot);
		qunlock(&rtclock);
		n = readnum(offset, buf, n, t, 12);
		return n;
	case Qnvram:
		if(offset > NVREAD)
			return 0;
		if(n > NVREAD - offset)
			n = NVREAD - offset;
		qlock(&rtclock);
		memmove(buf, nvr.ram+offset, n);
		qunlock(&rtclock);
		return n;
	}
	error(Egreg);
	return 0;		/* not reached */
}
Пример #11
0
static long piperead(struct chan *c, void *va, long n, int64_t ignored)
{
	Pipe *p;

	p = c->aux;

	switch (NETTYPE(c->qid.path)) {
		case Qdir:
			return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir),
							  pipegen);
		case Qdata0:
			if (c->flag & O_NONBLOCK)
				return qread_nonblock(p->q[0], va, n);
			else
				return qread(p->q[0], va, n);
		case Qdata1:
			if (c->flag & O_NONBLOCK)
				return qread_nonblock(p->q[1], va, n);
			else
				return qread(p->q[1], va, n);
		default:
			panic("piperead");
	}
	return -1;	/* not reached */
}
Пример #12
0
long
netifread(struct netif *nif, struct chan *c, void *a, long n, uint32_t offset)
{
	int i, j;
	struct netfile *f;
	char *p;

	if (c->qid.type & QTDIR)
		return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen);

	switch (NETTYPE(c->qid.path)) {
		case Ndataqid:
			f = nif->f[NETID(c->qid.path)];
			return qread(f->in, a, n);
		case Nctlqid:
			return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
		case Nstatqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = snprintf(p, READSTR, "in: %d\n", nif->inpackets);
			j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link);
			j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets);
			j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs);
			j += snprintf(p + j, READSTR - j, "overflows: %d\n",
						  nif->overflows);
			j += snprintf(p + j, READSTR - j, "soft overflows: %d\n",
						  nif->soverflows);
			j += snprintf(p + j, READSTR - j, "framing errs: %d\n",
						  nif->frames);
			j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs);
			j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs);
			j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom);
			j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps);
			j += snprintf(p + j, READSTR - j, "addr: ");
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			snprintf(p + j, READSTR - j, "\n");
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Naddrqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = 0;
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Ntypeqid:
			f = nif->f[NETID(c->qid.path)];
			return readnum(offset, a, n, f->type, NUMSIZE);
		case Nifstatqid:
			return 0;
	}
	error(Ebadarg);
	return -1;	/* not reached */
}
Пример #13
0
static long
envread(Chan *c, void *a, long n, vlong off)
{
	Egrp *eg;
	Evalue *e;
	ulong offset = off;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, 0, 0, envgen);

	eg = envgrp(c);
	rlock(eg);
	if(waserror()){
		runlock(eg);
		nexterror();
	}

	e = envlookup(eg, nil, c->qid.path);
	if(e == nil)
		error(Enonexist);
	if(offset >= e->len || e->value == nil)
		n = 0;
	else if(offset + n > e->len)
		n = e->len - offset;
	if(n <= 0)
		n = 0;
	else
		memmove(a, e->value+offset, n);

	runlock(eg);
	poperror();
	return n;
}
Пример #14
0
static long
dupread(Chan *c, void *va, long n, vlong offset)
{
	char *a = va;
	char buf[256];
	int fd, twicefd;

	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, nil, 0, dupgen);
	twicefd = c->qid.path - 1;
	fd = twicefd/2;
	if(twicefd & 1){
		c = fdtochan(up->env->fgrp, fd, -1, 0, 1);
		if(waserror()){
			cclose(c);
			nexterror();
		}
		progfdprint(c, fd, 0, buf, sizeof buf);
		poperror();
		cclose(c);
		return readstr((ulong)offset, va, n, buf);
	}
	panic("dupread");
	return 0;
}
Пример #15
0
static long	 
flashread(Chan *c, void *buf, long n, vlong offset)
{
	Flash *f;
	char *s, *o;
	Flashpart *fp;
	Flashregion *r;
	int i;
	ulong start, end;

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, nil, 0, flashgen);

	f = flash.card[c->dev];
	fp = &f->part[PART(c->qid.path)];
	if(fp->name == nil)
		error(Egreg);
	switch(TYPE(c->qid.path)){
	case Qdata:
		offset += fp->start;
		if(offset >= fp->end)
			return 0;
		if(offset+n > fp->end)
			n = fp->end - offset;
		n = readflash(f, buf, offset, n);
		if(n < 0)
			error(Eio);
		return n;
	case Qctl:
		s = malloc(READSTR);
		if(waserror()){
			free(s);
			nexterror();
		}
		o = seprint(s, s+READSTR, "%#2.2ux %#4.4ux %d %q\n",
			f->id, f->devid, f->width, f->sort!=nil? f->sort: "nor");
		for(i=0; i<f->nr; i++){
			r = &f->regions[i];
			if(r->start < fp->end && fp->start < r->end){
				start = r->start;
				if(fp->start > start)
					start = fp->start;
				end = r->end;
				if(fp->end < end)
					end = fp->end;
				o = seprint(o, s+READSTR, "%#8.8lux %#8.8lux %#8.8lux", start, end, r->erasesize);
				if(r->pagesize)
					o = seprint(o, s+READSTR, " %#8.8lux", r->pagesize);
				o = seprint(o, s+READSTR, "\n");
			}
		}
		n = readstr(offset, buf, n, s);
		poperror();
		free(s);
		return n;
	}
	error(Egreg);
	return 0;		/* not reached */
}
Пример #16
0
static long
audioread(Chan *c, void *a, long n, vlong off)
{
	Audiochan *ac;
	Audio *adev;
	long (*fn)(Audio *, void *, long, vlong);

	ac = c->aux;
	adev = ac->adev;

	fn = nil;
	switch((ulong)c->qid.path){
	case Qdir:
		audiodir[Qaudio].length = adev->buffered ? adev->buffered(adev) : 0;
		return devdirread(c, a, n, audiodir, nelem(audiodir), devgen);
	case Qaudio:
		fn = adev->read;
		break;
	case Qaudiostat:
		fn = adev->status;
		break;
	case Qvolume:
		fn = adev->volread;
		break;
	}
	if(fn == nil)
		error(Egreg);

	eqlock(ac);
	if(waserror()){
		qunlock(ac);
		nexterror();
	}
	switch((ulong)c->qid.path){
	case Qaudiostat:
	case Qvolume:
		/* generate the text on first read */
		if(ac->data == nil || off == 0){
			long l;

			ac->data = nil;
			l = fn(adev, ac->buf, sizeof(ac->buf)-1, 0);
			if(l < 0)
				l = 0;
			ac->buf[l] = 0;
			ac->data = ac->buf;
		}
		/* then serve all requests from buffer */
		n = readstr(off, a, n, ac->data);
		break;

	default:
		n = fn(adev, a, n, off);
	}
	qunlock(ac);
	poperror();
	return n;
}
Пример #17
0
static long
dsoread(Chan *c, void *a, long n, vlong offset)
{
	MyFiles *f;
	char* s;

	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, dsotab, nfichtab+2, devgen);

	if(c->qid.path == Qdata){
		//s = usage();  // Antes en lugar de los comando, mostraba la ayuda
		s = getComandos();
		return readstr(offset, a, n, s);
	}

	f = getMyFile(c);

	if(!f->valido || checkFiles(f) && (f->type != Qmir)){
		f->valido = 0;
		print("Fichero corrupto: %s\n",f->name);
	}

	// Se mantienen los cierres comentados
	// para indicar donde deben ir si fuesen necesarios

	if(!checkCorruptos(f)){
		//qlock(&f->lock); 

		switch(f->type){
			case Qcat:
				n = dsoconcatread(f, a, n, offset);
				break;
			case Qpar:
				n = dsopartread(f, a, n, offset);
				break;
			case Qmir:
				n = dsomirrorread(f, a, n,offset);
				break;
			case Qilv:
				n = dsointerlread(f, a, n, offset);
				break;
			default:
				print("BUG: f->type desconocido\n");
				n = 0;
		}

		//qunlock(&f->lock);
	}else{
		f->valido = 0;
		print("Imposible leer de %s\n",f->name);
		return 0;
	}

	return n;
}
Пример #18
0
static int32_t
srvread(Chan *c, void *va, int32_t n, int64_t m)
{
	int32_t r;

	isdir(c);
	qlock(&srvlk);
	r = devdirread(c, va, n, 0, 0, srvgen);
	qunlock(&srvlk);
	return r;
}
Пример #19
0
static long capread(struct chan *c, void *va, long n, int64_t m)
{
	switch ((uint32_t)c->qid.path) {
	case Qdir:
		return devdirread(c, va, n, capdir, ncapdir, devgen);

	default:
		error(EPERM, "Permission denied: can't read capability files");
		break;
	}
	return n;
}
Пример #20
0
static long
floppyread(Chan *c, void *a, long n, vlong off)
{
	FDrive *dp;
	long rv;
	int sec, head, cyl;
	long len;
	uchar *aa;
	ulong offset = off;

	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, floppydir, 1+fl.ndrive*NFDIR, devgen);

	rv = 0;
	dp = &fl.d[c->qid.path & ~Qmask];
	switch ((int)(c->qid.path & Qmask)) {
	case Qdata:
		islegal(offset, n, dp);
		aa = a;

		qlock(&fl);
		if(waserror()){
			qunlock(&fl);
			nexterror();
		}
		floppyon(dp);
		changed(c, dp);
		for(rv = 0; rv < n; rv += len){
			/*
			 *  all xfers come out of the track cache
			 */
			dp->len = n - rv;
			floppypos(dp, offset+rv);
			cyl = dp->tcyl;
			head = dp->thead;
			len = dp->len;
			sec = dp->tsec;
			if(readtrack(dp, cyl, head) < 0)
				break;
			memmove(aa+rv, dp->cache + (sec-1)*dp->t->bytes, len);
		}
		qunlock(&fl);
		poperror();

		break;
	case Qctl:
		return readstr(offset, a, n, dp->t->name);
	default:
		panic("floppyread: bad qid");
	}

	return rv;
}
Пример #21
0
static int32_t
corebootread(Chan *c, void *va, int32_t n, int64_t off)
{
	switch((uint32_t)c->qid.path){
	case Qdir:
		return devdirread(c, va, n, corebootdir, nelem(corebootdir), corebootdevgen);
	case Qtable:
		/* todo: do something */
		break;
	}
	return 0;
}
Пример #22
0
static long
devlogfsread(Chan *c, void *buf, long n, vlong off)
{
	int instance, qid, qt;

	SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt);
	USED(instance);
#ifdef CALLTRACE
	print("devlogfsread(c = 0x%.8lux, buf = 0x%.8lux, n = %ld, instance = %d, qid = %d, qt = %d) - start\n",
		(ulong)c, (ulong)buf, n, instance, qid, qt);
#endif
	if(qt & QTDIR) {
#ifdef CALLTRACE
		print("devlogfsread(c = 0x%.8lux, buf = 0x%.8lux, n = %ld, instance = %d, qid = %d, qt = %d) - calling devdirread\n",
			(ulong)c, (ulong)buf, n, instance, qid, qt);
#endif
		return devdirread(c, buf, n, 0, 0, devlogfsgen);
	}

	if(DATAQID(qid, qt)) {
		if (qid == Qfsboot) {
			Devlogfs *l = c->aux;
			qlock(&l->bootqlock);
			if (waserror()) {
				qunlock(&l->bootqlock);
				nexterror();
			}
			smartio((SMARTIOFN *)logfsbootio, l->lb, buf, n, off, logfsbootgetiosize(l->lb), 0);
			poperror();
			qunlock(&l->bootqlock);
			return n;
		}
		else if (qid == Qfs) {
			Devlogfs *d = c->aux;
			return lfsrvread(d, buf, n);
		}
		error(Eio);
	}

	if (qid == Qusers) {
		long nr;
		errorany(logfsisusersread(is, buf, n, (ulong)off, &nr));
		return nr;
	}
	else if (qid == Qdump)
		return devlogfsdumpread(buf, n);

	if (qid != Qctl)
		error(Egreg);

	return 0;
}
Пример #23
0
static int32_t
capread(Chan *c, void *va, int32_t n, int64_t m)
{
    switch((uint32_t)c->qid.path) {
    case Qdir:
        return devdirread(c, va, n, capdir, ncapdir, devgen);

    default:
        error(Eperm);
        break;
    }
    return n;
}
Пример #24
0
static long
capread(Chan *c, void *va, long n, vlong vl)
{
	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, va, n, capdir, ncapdir, devgen);

	default:
		error(Eperm);
		break;
	}
	return n;
}
Пример #25
0
static long
rtcread(Chan *c, void *a, long n, vlong offset)
{
	if(c->qid.type & QTDIR)
		return devdirread(c, a, n, rtcdir, nelem(rtcdir), devgen);

	switch((ulong)c->qid.path){
	case Qrtc:
		return readnum((ulong)offset, a, n, rtcsecs, 12);
	}
	error(Ebadarg);
	return 0;
}
Пример #26
0
static long
cmdread(Chan *ch, void *a, long n, vlong offset)
{
	Conv *c;
	char *p, *cmds;
	int fd;

	USED(offset);

	p = a;
	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qcmd:
	case Qtopdir:
	case Qconvdir:
		return devdirread(ch, a, n, 0, 0, cmdgen);
	case Qctl:
		sprint(up->genbuf, "%ld", CONV(ch->qid));
		return readstr(offset, p, n, up->genbuf);
	case Qstatus:
		c = cmd.conv[CONV(ch->qid)];
		cmds = "";
		if(c->cmd != nil)
			cmds = c->cmd->f[1];
		snprint(up->genbuf, sizeof(up->genbuf), "cmd/%d %d %s %q %q\n",
			c->x, c->inuse, c->state, c->dir, cmds);
		return readstr(offset, p, n, up->genbuf);
	case Qdata:
	case Qstderr:
		fd = 1;
		if(TYPE(ch->qid) == Qstderr)
			fd = 2;
		c = cmd.conv[CONV(ch->qid)];
		qlock(&c->l);
		if(c->fd[fd] == -1){
			qunlock(&c->l);
			return 0;
		}
		qunlock(&c->l);
		osenter();
		n = read(c->fd[fd], a, n);
		osleave();
		if(n < 0)
			oserror();
		return n;
	case Qwait:
		c = cmd.conv[CONV(ch->qid)];
		return qread(c->waitq, a, n);
	}
}
Пример #27
0
static int32_t
pmcread(Chan *c, void *a, int32_t n, int64_t offset)
{
	Proc *up = externup();
	uint32_t type, id;
	PmcCtl p;
	char *s;
	uint64_t v;
	uint64_t coreno;

	type = PMCTYPE(c->qid.path);
	id = PMCID(c->qid.path);

	switch(type){
	case Qcore:
	case Qdir:
	case Qctr:
		return devdirread(c, a, n, nil, 0, pmcgen);
	}

	s = malloc(PmcCtlRdStr);
	if(waserror()){
		free(s);
		nexterror();
	}
	coreno = (uint64_t)c->aux;
	p._coreno = coreno;
	switch(type){
	case Qdata:
		v = pmcgetctr(coreno, id);
		snprint(s, PmcCtlRdStr, "%#ullx", v);
		break;
	case Qctl:
		if (pmcgetctl(coreno, &p, id) < 0)
			error("bad ctr");
		if (pmcctlstr(s, PmcCtlRdStr, &p) < 0)
			error("bad pmc");
		break;
	case Qgctl:
		if (pmcdescstr(s, PmcCtlRdStr) < 0)
			error("bad pmc");
		break;
	default:
		error(Eperm);
	}
	n = readstr(offset, a, n, s);
	free(s);
	poperror();
	return n;
}
Пример #28
0
long
ipread(Chan *ch, void *a, long n, vlong offset)
{
	int r;
	Conv *c;
	Proto *x;
	uchar ip[4];
	char buf[128], *p;

/*print("ipread %s %lux\n", c2name(ch), (long)ch->qid.path);*/
	p = a;
	switch(TYPE(ch->qid)) {
	default:
		error(Eperm);
	case Qcs:
		return csread(ch, a, n, offset);
	case Qprotodir:
	case Qtopdir:
	case Qconvdir:
		return devdirread(ch, a, n, 0, 0, ipgen);
	case Qctl:
		sprint(buf, "%d", CONV(ch->qid));
		return readstr(offset, p, n, buf);
	case Qremote:
		c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
		hnputl(ip, c->raddr);
		sprint(buf, "%I!%d\n", ip, c->rport);
		return readstr(offset, p, n, buf);
	case Qlocal:
		c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
		hnputl(ip, c->laddr);
		sprint(buf, "%I!%d\n", ip, c->lport);
		return readstr(offset, p, n, buf);
	case Qstatus:
		x = &proto[PROTO(ch->qid)];
		c = x->conv[CONV(ch->qid)];
		sprint(buf, "%s/%d %d %s \n",
			c->p->name, c->x, c->r.ref, c->state);
		return readstr(offset, p, n, buf);
	case Qdata:
		c = proto[PROTO(ch->qid)].conv[CONV(ch->qid)];
		r = so_recv(c->sfd, a, n, 0);
		if(r < 0){
			oserrstr();
			nexterror();
		}
		return r;
	}
}
Пример #29
0
static int32_t
vconread(Chan *c, void *va, int32_t n, int64_t offset)
{
	int vdidx = DEV(c->qid);
	if(vdidx >= nvcon)
		error(Ebadarg);
	switch(TYPE(c->qid)) {
	case Qtopdir:
	case Qvirtcon:
		return devdirread(c, va, n, (Dirtab *)0, 0L, vcongen);
	case Qvcpipe:
		return rwcommon(vcons[vdidx], va, n, 0);
	}
	return -1;
}
Пример #30
0
static long
dlread(Chan *c, void *a, long n, vlong voffset)
{
	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, a, n, dltab, nelem(dltab), devgen);
	case Qdynld:
		return readdl(a, n, (ulong)voffset);
	case Qdynsyms:
		return readsyms(a, n, (ulong)voffset);
	default:
		error(Egreg);
	}
	return n;
}