Ejemplo n.º 1
0
/* runs on new char in kbd queue */
void readline(uv_async_t* key_wake)
{
    char ch;

    if(qread(kbdq, &ch, 1) == 0) {
         print("null char\n");
    }
    else {
        lsend = 0;
        if(ch == 0){
            /* flush output on rawoff -> rawon */
            if(kbd.x > 0)
                lsend = !qcanread(kbdq);
        }else if(kbd.raw){
            kbd.line[kbd.x++] = ch;
            lsend = !qcanread(kbdq);
        }else{
            switch(ch){
            case '\b':
                if(kbd.x)
                    kbd.x--;
                break;
            case 0x15:
                kbd.x = 0;
                break;
            case 0x04:
                lsend = 1;
                break;
            case '\n':
                lsend = 1;
            default:
                kbd.line[kbd.x++] = ch;
                break;
            }
        }
        if(lsend || kbd.x == sizeof kbd.line){
            uv_mutex_lock(&line_lock);
            qwrite(lineq, kbd.line, kbd.x);
            // signal the queue consumer
            uv_cond_signal(&line_ready);
            uv_mutex_unlock(&line_lock);
            
            kbd.x = 0;
        }
    }
}
Ejemplo n.º 2
0
static long
consread(Chan *c, void *va, long n, vlong offset)
{
	int send;
	char buf[64], ch;

	if(c->qid.type & QTDIR)
		return devdirread(c, va, n, contab, nelem(contab), devgen);

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

	case Qsysctl:
		return readstr(offset, va, n, VERSION);

	case Qsysname:
		if(ossysname == nil)
			return 0;
		return readstr(offset, va, n, ossysname);

	case Qrandom:
		return randomread(va, n);

	case Qnotquiterandom:
		genrandom(va, n);
		return n;

	case Qhostowner:
		return readstr(offset, va, n, eve);

	case Qhoststdin:
		return read(0, va, n);	/* should be pread */

	case Quser:
		return readstr(offset, va, n, up->env->user);

	case Qjit:
		snprint(buf, sizeof(buf), "%d", cflag);
		return readstr(offset, va, n, buf);

	case Qtime:
		snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime());
		return readstr(offset, va, n, buf);

	case Qdrivers:
		return devtabread(c, va, n, offset);

	case Qmemory:
		return poolread(va, n, offset);

	case Qnull:
		return 0;

	case Qmsec:
		return readnum(offset, va, n, osmillisec(), NUMSIZE);

	case Qcons:
		qlock(&kbd.q);
		if(waserror()){
			qunlock(&kbd.q);
			nexterror();
		}

		if(dflag)
			error(Enonexist);

		while(!qcanread(lineq)) {
			if(qread(kbdq, &ch, 1) == 0)
				continue;
			send = 0;
			if(ch == 0){
				/* flush output on rawoff -> rawon */
				if(kbd.x > 0)
					send = !qcanread(kbdq);
			}else if(kbd.raw){
				kbd.line[kbd.x++] = ch;
				send = !qcanread(kbdq);
			}else{
				switch(ch){
				case '\b':
					if(kbd.x)
						kbd.x--;
					break;
				case 0x15:
					kbd.x = 0;
					break;
				case 0x04:
					send = 1;
					break;
				case '\n':
					send = 1;
				default:
					kbd.line[kbd.x++] = ch;
					break;
				}
			}
			if(send || kbd.x == sizeof kbd.line){
				qwrite(lineq, kbd.line, kbd.x);
				kbd.x = 0;
			}
		}
		n = qread(lineq, va, n);
		qunlock(&kbd.q);
		poperror();
		return n;

	case Qscancode:
		if(offset == 0)
			return readstr(0, va, n, gkscanid);
		return qread(gkscanq, va, n);

	case Qkeyboard:
		return qread(gkbdq, va, n);

	case Qkprint:
		rlock(&kprintq.l);
		if(waserror()){
			runlock(&kprintq.l);
			nexterror();
		}
		n = qread(kprintq.q, va, n);
		poperror();
		runlock(&kprintq.l);
		return n;
	}
}
Ejemplo n.º 3
0
/*
 * move blocks between queues if they are ready.
 * schedule an interrupt for the next interesting time.
 *
 * must be called with the link ilocked.
 */
static void
pushlink(Link *link, vlong now)
{
	Block *bp;
	vlong tout, tin;

	/*
	 * put another block in the link queue
	 */
	ilock(link);
	if(link->iq == nil || link->oq == nil){
		iunlock(link);
		return;

	}
	timerdel(&link->ci);

	/*
	 * put more blocks into the xmit queue
	 * use the time the last packet was supposed to go out
	 * as the start time for the next packet, rather than
	 * the current time.  this more closely models a network
	 * device which can queue multiple output packets.
	 */
	tout = link->tout;
	if(!tout)
		tout = now;
	while(tout <= now){
		bp = qget(link->oq);
		if(bp == nil){
			tout = 0;
			break;
		}

		/*
		 * can't send the packet before it gets queued
		 */
		tin = gtime(bp->rp);
		if(tin > tout)
			tout = tin;
		tout = tout + (BLEN(bp) - Tmsize) * link->delayn;

		/*
		 * drop packets
		 */
		if(link->droprate && nrand(link->droprate) == 0)
			link->drops++;
		else{
			ptime(bp->rp, tout + link->delay0ns);
			if(link->tq == nil)
				link->tq = bp;
			else
				link->tqtail->next = bp;
			link->tqtail = bp;
		}
	}

	/*
	 * record the next time a packet can be sent,
	 * but don't schedule an interrupt if none is waiting
	 */
	link->tout = tout;
	if(!qcanread(link->oq))
		tout = 0;

	/*
	 * put more blocks into the receive queue
	 */
	tin = 0;
	while(bp = link->tq){
		tin = gtime(bp->rp);
		if(tin > now)
			break;
		bp->rp += Tmsize;
		link->tq = bp->next;
		bp->next = nil;
		if(!link->indrop)
			qpassnolim(link->iq, bp);
		else if(qpass(link->iq, bp) < 0)
			link->soverflows++;
		tin = 0;
	}
	if(bp == nil && qisclosed(link->oq) && !qcanread(link->oq) && !qisclosed(link->iq))
		qhangup(link->iq, nil);
	link->tin = tin;
	if(!tin || tin > tout && tout)
		tin = tout;

	link->ci.ns = tin - now;
	if(tin){
		if(tin < now)
			panic("loopback unfinished business");
		timeradd(&link->ci);
	}
	iunlock(link);
}
Ejemplo n.º 4
0
Archivo: devcons.c Proyecto: 8l/inferno
static long
consread(Chan *c, void *buf, long n, vlong offset)
{
	int l;
	Osenv *o;
	int ch, eol, i;
	char *p, tmp[128];
	char *cbuf = buf;

	if(n <= 0)
		return n;
	o = up->env;
	switch((ulong)c->qid.path){
	case Qdir:
		return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
	case Qsysctl:
		return readstr(offset, buf, n, VERSION);
	case Qcons:
	case Qkeyboard:
		qlock(&kbd);
		if(waserror()) {
			qunlock(&kbd);
			nexterror();
		}
		if(kbd.raw || kbd.kbdr) {
			if(qcanread(lineq))
				n = qread(lineq, buf, n);
			else {
				/* read as much as possible */
				do {
					i = qread(kbdq, cbuf, n);
					cbuf += i;
					n -= i;
				} while(n>0 && qcanread(kbdq));
				n = cbuf - (char*)buf;
			}
		} else {
			while(!qcanread(lineq)) {
				qread(kbdq, &kbd.line[kbd.x], 1);
				ch = kbd.line[kbd.x];
				eol = 0;
				switch(ch){
				case '\b':
					if(kbd.x)
						kbd.x--;
					break;
				case 0x15:
					kbd.x = 0;
					break;
				case '\n':
				case 0x04:
					eol = 1;
				default:
					kbd.line[kbd.x++] = ch;
					break;
				}
				if(kbd.x == sizeof(kbd.line) || eol) {
					if(ch == 0x04)
						kbd.x--;
					qwrite(lineq, kbd.line, kbd.x);
					kbd.x = 0;
				}
			}
			n = qread(lineq, buf, n);
		}
		qunlock(&kbd);
		poperror();
		return n;

	case Qscancode:
		if(offset == 0)
			return readstr(0, buf, n, kscanid);
		else
			return qread(kscanq, buf, n);

	case Qtime:
		snprint(tmp, sizeof(tmp), "%.lld", (vlong)mseconds()*1000);
		return readstr(offset, buf, n, tmp);

	case Qhostowner:
		return readstr(offset, buf, n, eve);

	case Quser:
		return readstr(offset, buf, n, o->user);

	case Qjit:
		snprint(tmp, sizeof(tmp), "%d", cflag);
		return readstr(offset, buf, n, tmp);

	case Qnull:
		return 0;

	case Qmsec:
		return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);

	case Qsysname:
		if(sysname == nil)
			return 0;
		return readstr(offset, buf, n, sysname);

	case Qnotquiterandom:
		genrandom(buf, n);
		return n;

	case Qrandom:
		return randomread(buf, n);

	case Qmemory:
		return poolread(buf, n, offset);

	case Qdrivers:
		p = malloc(READSTR);
		if(p == nil)
			error(Enomem);
		l = 0;
		for(i = 0; devtab[i] != nil; i++)
			l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc,  devtab[i]->name);
		if(waserror()){
			free(p);
			nexterror();
		}
		n = readstr(offset, buf, n, p);
		free(p);
		poperror();
		return n;

	case Qklog:
		return qread(klogq, buf, n);

	case Qkprint:
		rlock(&kprintq);
		if(waserror()){
			runlock(&kprintq);
			nexterror();
		}
		n = qread(kprintq.q, buf, n);
		poperror();
		runlock(&kprintq);
		return n;

	default:
		print("consread %llud\n", c->qid.path);
		error(Egreg);
	}
	return -1;		/* never reached */
}
Ejemplo n.º 5
0
static long consread(struct chan *c, void *buf, long n, int64_t off)
{
    ERRSTACK(1);
    uint32_t l;
#if 0
    Mach *mp;
#endif
    char *b, *bp, ch;
    char tmp[256];				/* must be >= 18*NUMSIZE (Qswap) */
    int i, k, id, send;
    int64_t offset = off;
#if 0
    extern char configfile[];
#endif

    if (n <= 0)
        return n;

    switch ((uint32_t) c->qid.path) {
    case Qdir:
        return devdirread(c, buf, n, consdir, ARRAY_SIZE(consdir), devgen);

    case Qcons:
        qlock(&(&kbd)->qlock);
        if (waserror()) {
            qunlock(&(&kbd)->qlock);
            nexterror();
        }
        while (!qcanread(lineq)) {
            if (qread(kbdq, &ch, 1) == 0)
                continue;
            send = 0;
            if (ch == 0) {
                /* flush output on rawoff -> rawon */
                if (kbd.x > 0)
                    send = !qcanread(kbdq);
            } else if (kbd.raw) {
                kbd.line[kbd.x++] = ch;
                send = !qcanread(kbdq);
            } else {
                switch (ch) {
                case '\b':
                    if (kbd.x > 0)
                        kbd.x--;
                    break;
                case 0x15:	/* ^U */
                    kbd.x = 0;
                    break;
                case '\n':
                case 0x04:	/* ^D */
                    send = 1;
                default:
                    if (ch != 0x04)
                        kbd.line[kbd.x++] = ch;
                    break;
                }
            }
            if (send || kbd.x == sizeof kbd.line) {
                qwrite(lineq, kbd.line, kbd.x);
                kbd.x = 0;
            }
        }
        n = qread(lineq, buf, n);
        qunlock(&(&kbd)->qlock);
        poperror();
        return n;

#if 0
    case Qcputime:
        k = offset;
        if (k >= 6 * NUMSIZE)
            return 0;
        if (k + n > 6 * NUMSIZE)
            n = 6 * NUMSIZE - k;
        /* easiest to format in a separate buffer and copy out */
        for (i = 0; i < 6 && NUMSIZE * i < k + n; i++) {
            l = current->time[i];
            if (i == TReal)
                l = MACHP(0)->ticks - l;
            l = TK2MS(l);
            consreadnum(0, tmp + NUMSIZE * i, NUMSIZE, l, NUMSIZE);
        }
        memmove(buf, tmp + k, n);
        return n;
#endif

    case Qkmesg:
        /*
         * This is unlocked to avoid tying up a process
         * that's writing to the buffer.  kmesg.n never
         * gets smaller, so worst case the reader will
         * see a slurred buffer.
         */
        if (off >= kmesg.n)
            n = 0;
        else {
            if (off + n > kmesg.n)
                n = kmesg.n - off;
            memmove(buf, kmesg.buf + off, n);
        }
        return n;

    case Qkprint:
        return qread(kprintoq, buf, n);

    case Qpgrpid:
        return consreadnum((uint32_t) offset, buf, n, current->pgrp->pgrpid,
                           NUMSIZE);

    case Qpid:
        return consreadnum((uint32_t) offset, buf, n, current->pid,
                           NUMSIZE);

    case Qppid:
        return consreadnum((uint32_t) offset, buf, n, current->ppid,
                           NUMSIZE);

    case Qtime:
        return readtime((uint32_t) offset, buf, n);

    case Qbintime:
        return readbintime(buf, n);

    case Qhostowner:
        return consreadstr((uint32_t) offset, buf, n, eve);

    case Qhostdomain:
        return consreadstr((uint32_t) offset, buf, n, hostdomain);

    case Quser:
        return consreadstr((uint32_t) offset, buf, n, current->user);

    case Qnull:
        return 0;

#if 0
    case Qconfig:
        return consreadstr((uint32_t) offset, buf, n, configfile);

    case Qsysstat:
        b = kzmalloc(conf.nmach * (NUMSIZE * 11 + 1) + 1, 0);	/* +1 for NUL */
        bp = b;
        for (id = 0; id < 32; id++) {
            if (active.machs & (1 << id)) {
                mp = MACHP(id);
                consreadnum(0, bp, NUMSIZE, id, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE,
                            (mp->perf.avg_inidle * 100) / mp->perf.period,
                            NUMSIZE);
                bp += NUMSIZE;
                consreadnum(0, bp, NUMSIZE,
                            (mp->perf.avg_inintr * 100) / mp->perf.period,
                            NUMSIZE);
                bp += NUMSIZE;
                *bp++ = '\n';
            }
        }
        if (waserror()) {
            kfree(b);
            nexterror();
        }
        n = consreadstr((uint32_t) offset, buf, n, b);
        kfree(b);
        poperror();
        return n;

    case Qswap:
        snprintf(tmp, sizeof tmp,
                 "%lud memory\n"
                 "%d pagesize\n"
                 "%lud kernel\n"
                 "%lud/%lud user\n"
                 "%lud/%lud swap\n"
                 "%lud/%lud kernel malloc\n"
                 "%lud/%lud kernel draw\n",
                 conf.npage * BY2PG,
                 BY2PG,
                 conf.npage - conf.upages,
                 palloc.user - palloc.freecount, palloc.user,
                 conf.nswap - swapalloc.free, conf.nswap,
                 mainmem->cursize, mainmem->maxsize,
                 imagmem->cursize, imagmem->maxsize);

        return consreadstr((uint32_t) offset, buf, n, tmp);
#endif

    case Qsysname:
        if (sysname == NULL)
            return 0;
        return consreadstr((uint32_t) offset, buf, n, sysname);

    case Qdrivers:
        b = kzmalloc(READSTR, 0);
        if (b == NULL)
            error(ENOMEM, "allocation for /dev/drivers read failed");
        k = 0;
        for (int i = 0; &devtab[i] < __devtabend; i++)
            k += snprintf(b + k, READSTR - k, "#%s\n", devtab[i].name);
        if (waserror()) {
            kfree(b);
            nexterror();
        }
        n = consreadstr((uint32_t) offset, buf, n, b);
        kfree(b);
        poperror();
        return n;

    case Qklog:
        //return qread(klogq, buf, n);
        /* the queue gives us some elasticity for log reading. */
        if (!logqueue)
            logqueue = qopen(1 << 20, 0, 0, 0);
        if (logqueue) {
            int ret;
            /* atomic sets/gets are not that important in this case. */
            reading_kmesg = 1;
            qwrite(logqueue, logbuffer, index);
            index = 0;
            ret = qread(logqueue, buf, n);
            reading_kmesg = 0;
            return ret;
        }
        break;

    case Qzero:
        memset(buf, 0, n);
        return n;

    case Qosversion:
        snprintf(tmp, sizeof tmp, "2000");
        n = consreadstr((uint32_t) offset, buf, n, tmp);
        return n;

    default:
        printd("consread %#llux\n", c->qid.path);
        error(EINVAL, "bad QID in consread");
    }
    return -1;	/* never reached */
}
Ejemplo n.º 6
0
long
consread(Chan *c, void *va, long count, vlong offset)
{
	int i, n, ch, eol;
	Pointer m;
	char *p, buf[64];

	if(c->qid.type & QTDIR)
		return devdirread(c, va, count, contab, nelem(contab), devgen);

	switch((ulong)c->qid.path) {
	default:
		error(Egreg);
	case Qsysctl:
		return readstr(offset, va, count, VERSION);
	case Qsysname:
		if(ossysname == nil)
			return 0;
		return readstr(offset, va, count, ossysname);
	case Qrandom:
		return randomread(va, count);
	case Qnotquiterandom:
		pseudoRandomBytes(va, count);
		return count;
	case Qpin:
		p = "pin set";
		if(up->env->pgrp->pin == Nopin)
			p = "no pin";
		return readstr(offset, va, count, p);
	case Qhostowner:
		return readstr(offset, va, count, eve);
	case Qhoststdin:
		return read(0, va, count);	/* should be pread */
	case Quser:
		return readstr(offset, va, count, up->env->user);
	case Qjit:
		snprint(buf, sizeof(buf), "%d", cflag);
		return readstr(offset, va, count, buf);
	case Qtime:
		snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime());
		return readstr(offset, va, count, buf);
	case Qdrivers:
		p = malloc(READSTR);
		if(p == nil)
			error(Enomem);
		n = 0;
		for(i = 0; devtab[i] != nil; i++)
			n += snprint(p+n, READSTR-n, "#%C %s\n", devtab[i]->dc,  devtab[i]->name);
		n = readstr(offset, va, count, p);
		free(p);
		return n;
	case Qmemory:
		return poolread(va, count, offset);

	case Qnull:
		return 0;
	case Qmsec:
		return readnum(offset, va, count, osmillisec(), NUMSIZE);
	case Qcons:
		qlock(&kbd.q);
		if(waserror()){
			qunlock(&kbd.q);
			nexterror();
		}

		if(dflag)
			error(Enonexist);

		while(!qcanread(lineq)) {
			qread(kbdq, &kbd.line[kbd.x], 1);
			ch = kbd.line[kbd.x];
			if(kbd.raw){
				qiwrite(lineq, &kbd.line[kbd.x], 1);
				continue;
			}
			eol = 0;
			switch(ch) {
			case '\b':
				if(kbd.x)
					kbd.x--;
				break;
			case 0x15:
				kbd.x = 0;
				break;
			case '\n':
			case 0x04:
				eol = 1;
			default:
				kbd.line[kbd.x++] = ch;
				break;
			}
			if(kbd.x == sizeof(kbd.line) || eol){
				if(ch == 0x04)
					kbd.x--;
				qwrite(lineq, kbd.line, kbd.x);
				kbd.x = 0;
			}
		}
		n = qread(lineq, va, count);
		qunlock(&kbd.q);
		poperror();
		return n;
	case Qscancode:
		if(offset == 0)
			return readstr(0, va, count, gkscanid);
		else
			return qread(gkscanq, va, count);
	case Qkeyboard:
		return qread(gkbdq, va, count);
	case Qpointer:
		m = mouseconsume();
		n = sprint(buf, "m%11d %11d %11d %11lud ", m.x, m.y, m.b, m.msec);
		if (count < n)
			n = count;
		memmove(va, buf, n);
		return n;
	case Qkprint:
		rlock(&kprintq.l);
		if(waserror()){
			runlock(&kprintq.l);
			nexterror();
		}
		n = qread(kprintq.q, va, count);
		poperror();
		runlock(&kprintq.l);
		return n;
	case Qsnarf: 
		if(offset == 0) {
			free(c->aux);
			c->aux = clipread();
		}
		if(c->aux == nil)
			return 0;
		return readstr(offset, va, count, c->aux);
	}
}
Ejemplo n.º 7
0
static long
consread(Chan *c, void *buf, long n, vlong off)
{
	ulong l;
	Mach *mp;
	char *b, *bp, ch;
	char tmp[256];		/* must be >= 18*NUMSIZE (Qswap) */
	int i, k, id, send;
	vlong offset = off;

	if(n <= 0)
		return n;

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

	case Qcons:
		qlock(&kbd.lk);
		if(waserror()) {
			qunlock(&kbd.lk);
			nexterror();
		}
		while(!qcanread(lineq)){
			if(qread(kbdq, &ch, 1) == 0)
				continue;
			send = 0;
			if(ch == 0){
				/* flush output on rawoff -> rawon */
				if(kbd.x > 0)
					send = !qcanread(kbdq);
			}else if(kbd.raw){
				kbd.line[kbd.x++] = ch;
				send = !qcanread(kbdq);
			}else{
				switch(ch){
				case '\b':
					if(kbd.x > 0)
						kbd.x--;
					break;
				case 0x15:	/* ^U */
					kbd.x = 0;
					break;
				case '\n':
				case 0x04:	/* ^D */
					send = 1;
				default:
					if(ch != 0x04)
						kbd.line[kbd.x++] = ch;
					break;
				}
			}
			if(send || kbd.x == sizeof kbd.line){
				qwrite(lineq, kbd.line, kbd.x);
				kbd.x = 0;
			}
		}
		n = qread(lineq, buf, n);
		qunlock(&kbd.lk);
		poperror();
		return n;

	case Qcputime:
		k = offset;
		if(k >= 6*NUMSIZE)
			return 0;
		if(k+n > 6*NUMSIZE)
			n = 6*NUMSIZE - k;
		/* easiest to format in a separate buffer and copy out */
		for(i=0; i<6 && NUMSIZE*i<k+n; i++){
			l = up->time[i];
			if(i == TReal)
				l = msec() - l;
			l = TK2MS(l);
			readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE);
		}
		memmove(buf, tmp+k, n);
		return n;

	case Qkmesg:
		/*
		 * This is unlocked to avoid tying up a process
		 * that's writing to the buffer.  kmesg.n never 
		 * gets smaller, so worst case the reader will
		 * see a slurred buffer.
		 */
		if(off >= kmesg.n)
			n = 0;
		else{
			if(off+n > kmesg.n)
				n = kmesg.n - off;
			memmove(buf, kmesg.buf+off, n);
		}
		return n;
		
	case Qkprint:
		return qread(kprintoq, buf, n);

	case Qpgrpid:
		return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE);

	case Qpid:
		return readnum((ulong)offset, buf, n, up->pid, NUMSIZE);

	case Qppid:
		return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE);

	case Qtime:
		return readtime((ulong)offset, buf, n);

	case Qbintime:
		return readbintime(buf, n);

	case Qhostowner:
		return readstr((ulong)offset, buf, n, eve);

	case Qhostdomain:
		return readstr((ulong)offset, buf, n, hostdomain);

	case Quser:
		return readstr((ulong)offset, buf, n, up->user);

	case Qnull:
		return 0;

	case Qsysstat:
		b = smalloc(conf.nmach*(NUMSIZE*11+1) + 1);	/* +1 for NUL */
		bp = b;
		for(id = 0; id < 32; id++) {
			if(active.machs & (1<<id)) {
				mp = MACHP(id);
				readnum(0, bp, NUMSIZE, id, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE, mp->load, NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE,
					(mp->perf.avg_inidle*100)/mp->perf.period,
					NUMSIZE);
				bp += NUMSIZE;
				readnum(0, bp, NUMSIZE,
					(mp->perf.avg_inintr*100)/mp->perf.period,
					NUMSIZE);
				bp += NUMSIZE;
				*bp++ = '\n';
			}
		}
		if(waserror()){
			free(b);
			nexterror();
		}
		n = readstr((ulong)offset, buf, n, b);
		free(b);
		poperror();
		return n;

	case Qswap:
		tmp[0] = 0;

		return readstr((ulong)offset, buf, n, tmp);

	case Qsysname:
		if(sysname == nil)
			return 0;
		return readstr((ulong)offset, buf, n, sysname);

	case Qrandom:
		return randomread(buf, n);

	case Qdrivers:
		b = malloc(READSTR);
		if(b == nil)
			error(Enomem);
		n = 0;
		for(i = 0; devtab[i] != nil; i++)
			n += snprint(b+n, READSTR-n, "#%C %s\n", devtab[i]->dc,  devtab[i]->name);
		if(waserror()){
			free(b);
			nexterror();
		}
		n = readstr((ulong)offset, buf, n, b);
		free(b);
		poperror();
		return n;

	case Qzero:
		memset(buf, 0, n);
		return n;

	case Qosversion:
		snprint(tmp, sizeof tmp, "2000");
		n = readstr((ulong)offset, buf, n, tmp);
		return n;

	default:
		print("consread 0x%llux\n", c->qid.path);
		error(Egreg);
	}
	return -1;		/* never reached */
}
Ejemplo n.º 8
0
Archivo: devcons.c Proyecto: 8l/inferno
static long
consread(Chan *c, void *va, long n, vlong offset)
{
	int send;
	char *p, buf[64], ch;
	FILE * battery;
	FILE * brightness;
	int size;

	if(c->qid.type & QTDIR)
		return devdirread(c, va, n, contab, nelem(contab), devgen);

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

	case Qsysctl:
		return readstr(offset, va, n, VERSION);

	case Qsysname:
		if(ossysname == nil)
			return 0;
		return readstr(offset, va, n, ossysname);

	case Qrandom:
		return randomread(va, n);

	case Qnotquiterandom:
		genrandom(va, n);
		return n;

	case Qhostowner:
		return readstr(offset, va, n, eve);

	case Qhoststdin:
		return read(0, va, n);	/* should be pread */

	case Quser:
		return readstr(offset, va, n, up->env->user);

	case Qjit:
		snprint(buf, sizeof(buf), "%d", cflag);
		return readstr(offset, va, n, buf);

	case Qtime:
		snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime());
		return readstr(offset, va, n, buf);

	case Qdrivers:
		return devtabread(c, va, n, offset);

	case Qmemory:
		return poolread(va, n, offset);

	case Qnull:
		return 0;

	case Qmsec:
		return readnum(offset, va, n, osmillisec(), NUMSIZE);

	case Qcons:
		qlock(&kbd.q);
		if(waserror()){
			qunlock(&kbd.q);
			nexterror();
		}

		if(dflag)
			error(Enonexist);

		while(!qcanread(lineq)) {
			if(qread(kbdq, &ch, 1) == 0)
				continue;
			send = 0;
			if(ch == 0){
				/* flush output on rawoff -> rawon */
				if(kbd.x > 0)
					send = !qcanread(kbdq);
			}else if(kbd.raw){
				kbd.line[kbd.x++] = ch;
				send = !qcanread(kbdq);
			}else{
				switch(ch){
				case '\b':
					if(kbd.x)
						kbd.x--;
					break;
				case 0x15:
					kbd.x = 0;
					break;
				case 0x04:
					send = 1;
					break;
				case '\n':
					send = 1;
				default:
					kbd.line[kbd.x++] = ch;
					break;
				}
			}
			if(send || kbd.x == sizeof kbd.line){
				qwrite(lineq, kbd.line, kbd.x);
				kbd.x = 0;
			}
		}
		n = qread(lineq, va, n);
		qunlock(&kbd.q);
		poperror();
		return n;

	case Qscancode:
		if(offset == 0)
			return readstr(0, va, n, gkscanid);
		return qread(gkscanq, va, n);

	case Qkeyboard:
		return qread(gkbdq, va, n);

	case Qevents:
		return qread(c->aux, va, n);

	case Qkprint:
		rlock(&kprintq.l);
		if(waserror()){
			runlock(&kprintq.l);
			nexterror();
		}
		n = qread(kprintq.q, va, n);
		poperror();
		runlock(&kprintq.l);
		return n;
	case Qbattery:
		if(type == 's')
			battery = fopen("/sys/class/power_supply/battery/capacity", "r");
		else if(type == 'c')
			battery = fopen("/sys/class/power_supply/max17042-0/capacity", "r");
		else
			battery = fopen("/sys/class/power_supply/battery/capacity", "r");
		size = fread(buf, 1, sizeof(buf), battery);
		fclose(battery);
		buf[size - 1] = '\0';
		return readstr(offset, va, n, buf);
	case Qtype:
		if(type == 's')
			strncpy(buf, "nexus s", sizeof(buf));
		else if(type == 'c')
			strncpy(buf, "nook color", sizeof(buf));
		else if(type == 'e')
			strncpy(buf, "emulator", sizeof(buf));
		else
			strncpy(buf, "nexus s", sizeof(buf));
		return readstr(offset, va, n, buf);
	case Qbrightness:
		if(type == 'c')
			brightness = fopen("/sys/devices/platform/omap_pwm_led/leds/lcd-backlight/brightness", "r");
		else if(type == 'e')
			return;
		else
			brightness = fopen("/sys/class/backlight/s5p_bl/brightness", "r");
		size = fread(buf, 1, sizeof(buf), brightness);
		fclose(brightness);
		buf[size - 1] = '\0';
		return readstr(offset, va, n, buf);
	}
}