/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

//#define DEBUG
/* proc on plan 9 has lots of capabilities, some of which we might
 * want for akaros:
 * debug control
 * event tracing
 * process control (no need for signal system call, etc.)
 * textual status
 * rather than excise code that won't work, I'm bracketing it with
 * #if 0 until we know we don't want it
 */
#include <assert.h>
#include <cpio.h>
#include <error.h>
#include <kmalloc.h>
#include <kref.h>
#include <pmap.h>
#include <ros/vmm.h>
#include <slab.h>
#include <smp.h>
#include <stdio.h>
#include <string.h>
#include <umem.h>

#include <arch/vmm/vmm.h>

struct dev procdevtab;

static char *devname(void)
{
	return procdevtab.name;
}

enum { Qdir,
       Qtrace,
       Qtracepids,
       Qself,
       Qns,
       Qargs,
       Qctl,
       Qfd,
       Qfpregs,
       Qkregs,
       Qmaps,
       Qmem,
       Qnote,
       Qnoteid,
       Qnotepg,
       Qproc,
       Qregs,
       Quser,
       Qsegment,
       Qstatus,
       Qstrace,
       Qstrace_traceset,
       Qvmstatus,
       Qtext,
       Qwait,
       Qprofile,
       Qsyscall,
       Qcore,
};

enum { CMclose,
       CMclosefiles,
       CMhang,
       CMstraceme,
       CMstraceall,
       CMstrace_drop,
};

enum { Nevents = 0x4000,
       Emask = Nevents - 1,
       Ntracedpids = 1024,
       STATSIZE = 8 + 1 + 10 + 1 + 6 + 2,
};

/*
 * Status, fd, and ns are left fully readable (0444) because of their use in
 * debugging, particularly on shared servers. Arguably, ns and fd shouldn't be
 * readable; if you'd prefer, change them to 0000
 */
struct dirtab procdir[] = {
    {"args", {Qargs}, 0, 0660},
    {"ctl", {Qctl}, 0, 0660},
    {"fd", {Qfd}, 0, 0444},
    {"fpregs", {Qfpregs}, 0, 0000},
    //  {"kregs",   {Qkregs},   sizeof(Ureg),       0600},
    {"maps", {Qmaps}, 0, 0000},
    {"mem", {Qmem}, 0, 0000},
    {"note", {Qnote}, 0, 0000},
    {"noteid", {Qnoteid}, 0, 0664},
    {"notepg", {Qnotepg}, 0, 0000},
    {"ns", {Qns}, 0, 0444},
    {"proc", {Qproc}, 0, 0400},
    //  {"regs",        {Qregs},    sizeof(Ureg),       0000},
    {"user", {Quser}, 0, 0444},
    {"segment", {Qsegment}, 0, 0444},
    {"status", {Qstatus}, STATSIZE, 0444},
    {"strace", {Qstrace}, 0, 0444},
    {"strace_traceset", {Qstrace_traceset}, 0, 0666},
    {"vmstatus", {Qvmstatus}, 0, 0444},
    {"text", {Qtext}, 0, 0000},
    {"wait", {Qwait}, 0, 0400},
    {"profile", {Qprofile}, 0, 0400},
    {"syscall", {Qsyscall}, 0, 0400},
    {"core", {Qcore}, 0, 0444},
};

static struct cmdtab proccmd[] = {
    {CMclose, "close", 2},         {CMclosefiles, "closefiles", 0},
    {CMhang, "hang", 0},           {CMstraceme, "straceme", 0},
    {CMstraceall, "straceall", 0}, {CMstrace_drop, "strace_drop", 2},
};

/*
 * struct qids are, in path:
 *	 5 bits of file type (qids above) (old comment said 4 here)
 *	23 bits of process slot number + 1 (pid + 1 is stored)
 *	     in vers,
 *	32 bits of pid, for consistency checking
 * If notepg, c->pgrpid.path is pgrp slot, .vers is noteid.
 */
#define QSHIFT 5    /* location in qid of proc slot # */
#define SLOTBITS 23 /* number of bits in the slot */
#define QIDMASK ((1 << QSHIFT) - 1)
#define SLOTMASK (((1 << SLOTBITS) - 1) << QSHIFT)

#define QID(q) ((((uint32_t)(q).path) & QIDMASK) >> 0)
#define SLOT(q) (((((uint32_t)(q).path) & SLOTMASK) >> QSHIFT) - 1)
#define PID(q) ((q).vers)
#define NOTEID(q) ((q).vers)

static void procctlreq(struct proc *, char *, size_t);
static int procctlmemio(struct proc *, uintptr_t, int, void *, int);
// static struct chan*   proctext(struct chan*, struct proc*);
// static Segment* txt2data(struct proc*, Segment*);
// static int    procstopped(void*);
static void mntscan(struct mntwalk *, struct proc *);

// static Traceevent *tevents;
static char *tpids, *tpidsc, *tpidse;
static spinlock_t tlock;
static int topens;
static int tproduced, tconsumed;
// static void notrace(struct proc*, int, int64_t);

// void (*proctrace)(struct proc*, int, int64_t) = notrace;

#if 0
static void profclock(Ureg * ur, Timer *)
{
	Tos *tos;

	if (up == NULL || current->state != Running)
		return;

	/* user profiling clock */
	if (userureg(ur)) {
		tos = (Tos *) (USTKTOP - sizeof(Tos));
		tos->clock += TK2MS(1);
		segclock(userpc(ur));
	}
}
#endif
static int procgen(struct chan *c, char *name, struct dirtab *tab, int unused,
                   int s, struct dir *dp)
{
	struct qid qid;
	struct proc *p;
	char *ename;

	int pid;
	uint32_t path, perm, len;
	if (s == DEVDOTDOT) {
		mkqid(&qid, Qdir, 0, QTDIR);
		devdir(c, qid, devname(), 0, eve.name, 0555, dp);
		return 1;
	}

	if (c->qid.path == Qdir) {
		if (s == 0) {
			strlcpy(get_cur_genbuf(), "trace", GENBUF_SZ);
			mkqid(&qid, Qtrace, -1, QTFILE);
			devdir(c, qid, get_cur_genbuf(), 0, eve.name, 0444, dp);
			return 1;
		}
		if (s == 1) {
			strlcpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
			mkqid(&qid, Qtracepids, -1, QTFILE);
			devdir(c, qid, get_cur_genbuf(), 0, eve.name, 0444, dp);
			return 1;
		}
		if (s == 2) {
			p = current;
			strlcpy(get_cur_genbuf(), "self", GENBUF_SZ);
			mkqid(&qid, (p->pid + 1) << QSHIFT, p->pid, QTDIR);
			devdir(c, qid, get_cur_genbuf(), 0, p->user.name,
			       DMDIR | 0555, dp);
			return 1;
		}
		s -= 3;
		if (name != NULL) {
			/* ignore s and use name to find pid */
			pid = strtol(name, &ename, 10);
			if (pid <= 0 || ename[0] != '\0')
				return -1;
			p = pid2proc(pid);
			if (!p)
				return -1;
			/* Need to update s, so that it's the correct 'index'
			 * for our proc (aka, the pid).  We use s later when
			 * making the qid. */
			s = pid;
		} else {
			/* This is a shitty iterator, and the list isn't
			 * guaranteed to give you the same ordering twice in a
			 * row. (procs come and go). */
			p = pid_nth(s);
			if (!p)
				return -1;
			pid = p->pid;
		}

		snprintf(get_cur_genbuf(), GENBUF_SZ, "%u", pid);
		/*
		 * String comparison is done in devwalk so
		 * name must match its formatted pid.
		 */
		if (name != NULL && strcmp(name, get_cur_genbuf()) != 0) {
			printk("pid-name mismatch, name: %s, pid %d\n", name,
			       pid);
			proc_decref(p);
			return -1;
		}
		mkqid(&qid, (s + 1) << QSHIFT, pid, QTDIR);
		devdir(c, qid, get_cur_genbuf(), 0, p->user.name, DMDIR | 0555,
		       dp);
		proc_decref(p);
		return 1;
	}
	if (c->qid.path == Qtrace) {
		strlcpy(get_cur_genbuf(), "trace", GENBUF_SZ);
		mkqid(&qid, Qtrace, -1, QTFILE);
		devdir(c, qid, get_cur_genbuf(), 0, eve.name, 0444, dp);
		return 1;
	}
	if (c->qid.path == Qtracepids) {
		strlcpy(get_cur_genbuf(), "tracepids", GENBUF_SZ);
		mkqid(&qid, Qtracepids, -1, QTFILE);
		devdir(c, qid, get_cur_genbuf(), 0, eve.name, 0444, dp);
		return 1;
	}
	if (s >= ARRAY_SIZE(procdir))
		return -1;
	if (tab)
		panic("procgen");

	tab = &procdir[s];
	/* path is everything other than the QID part.  Not sure from the orig
	 * code
	 * if they wanted just the pid part (SLOTMASK) or everything above QID
	 */
	path = c->qid.path & ~QIDMASK; /* slot component */
	if ((p = pid2proc(SLOT(c->qid))) == NULL)
		return -1;
	perm = 0444 | tab->perm;
#if 0
	if (perm == 0)
		perm = p->procmode;
	else	/* just copy read bits */
		perm |= p->procmode & 0444;
#endif

	len = tab->length;
#if 0
	switch (QID(c->qid)) {
		case Qwait:
			len = p->nwait;	/* incorrect size, but >0 means there's something to read */
			break;
		case Qprofile:
			q = p->seg[TSEG];
			if (q && q->profile) {
				len = (q->top - q->base) >> LRESPROF;
				len *= sizeof(*q->profile);
			}
			break;
	}
#endif

	mkqid(&qid, path | tab->qid.path, c->qid.vers, QTFILE);
	devdir(c, qid, tab->name, len, p->user.name, perm, dp);
	proc_decref(p);
	return 1;
}

#if 0
static void notrace(struct proc *, Tevent, int64_t)
{
}

static spinlock_t tlck = SPINLOCK_INITIALIZER_IRQSAVE;

static void _proctrace(struct proc *p, Tevent etype, int64_t ts)
{
	Traceevent *te;
	int tp;

	ilock(&tlck);
	if (p->trace == 0 || topens == 0 || tproduced - tconsumed >= Nevents) {
		iunlock(&tlck);
		return;
	}
	tp = tproduced++;
	iunlock(&tlck);

	te = &tevents[tp & Emask];
	te->pid = p->pid;
	te->etype = etype;
	if (ts == 0)
		te->time = todget(NULL);
	else
		te->time = ts;
	te->core = m->machno;
}

void proctracepid(struct proc *p)
{
	if (p->trace == 1 && proctrace != notrace) {
		p->trace = 2;
		ilock(&tlck);
		tpidsc = seprint(tpidsc, tpidse, "%d %s\n", p->pid, p->text);
		iunlock(&tlck);
	}
}

#endif
static void procinit(void)
{
#if 0
	if (conf.nproc >= (SLOTMASK >> QSHIFT) - 1)
		printd("warning: too many procs for devproc\n");
	addclock0link((void (*)(void))profclock, 113);	/* Relative prime to HZ */
#endif
}

static struct chan *procattach(char *spec)
{
	return devattach(devname(), spec);
}

static struct walkqid *procwalk(struct chan *c, struct chan *nc, char **name,
                                unsigned int nname)
{
	return devwalk(c, nc, name, nname, 0, 0, procgen);
}

static size_t procstat(struct chan *c, uint8_t *db, size_t n)
{
	return devstat(c, db, n, 0, 0, procgen);
}

/*
 *  none can't read or write state on other
 *  processes.  This is to contain access of
 *  servers running as none should they be
 *  subverted by, for example, a stack attack.
 */
static void nonone(struct proc *p)
{
	return;
#if 0
	if (p == up)
		return;
	if (strcmp(current->user.name, "none") != 0)
		return;
	if (iseve())
		return;
	error(EPERM, ERROR_FIXME);
#endif
}

struct bm_helper {
	struct sized_alloc *sza;
	size_t buflen;
};

static void get_needed_sz_cb(struct vm_region *vmr, void *arg)
{
	struct bm_helper *bmh = (struct bm_helper *)arg;

	/* ballpark estimate of a line */
	bmh->buflen += 150;
}

static void build_maps_cb(struct vm_region *vmr, void *arg)
{
	struct bm_helper *bmh = (struct bm_helper *)arg;
	struct sized_alloc *sza = bmh->sza;
	size_t old_sofar;
	char path_buf[MAX_FILENAME_SZ];
	char *path;
	unsigned long inode_nr;

	if (vmr_has_file(vmr)) {
		path = foc_abs_path(vmr->__vm_foc);
		inode_nr = 0; /* TODO: do we care about this? */
	} else {
		strlcpy(path_buf, "[heap]", sizeof(path_buf));
		path = path_buf;
		inode_nr = 0;
	}

	old_sofar = sza->sofar;
	sza_printf(sza, "%08lx-%08lx %c%c%c%c %08x %02d:%02d %d ", vmr->vm_base,
	           vmr->vm_end, vmr->vm_prot & PROT_READ ? 'r' : '-',
	           vmr->vm_prot & PROT_WRITE ? 'w' : '-',
	           vmr->vm_prot & PROT_EXEC ? 'x' : '-',
	           vmr->vm_flags & MAP_PRIVATE ? 'p' : 's',
	           vmr_has_file(vmr) ? vmr->vm_foff : 0,
	           vmr_has_file(vmr) ? 1 : 0, /* VFS == 1 for major */
	           0, inode_nr);
	/* Align the filename to the 74th char, like Linux (73 chars so far) */
	sza_printf(sza, "%*s", 73 - (sza->sofar - old_sofar), "");
	sza_printf(sza, "%s\n", path);
}

static struct sized_alloc *build_maps(struct proc *p)
{
	struct bm_helper bmh[1];

	/* Try to figure out the size needed: start with extra space, then add a
	 * bit for each VMR */
	bmh->buflen = 150;
	enumerate_vmrs(p, get_needed_sz_cb, bmh);
	bmh->sza = sized_kzmalloc(bmh->buflen, MEM_WAIT);
	enumerate_vmrs(p, build_maps_cb, bmh);
	return bmh->sza;
}

static struct chan *procopen(struct chan *c, int omode)
{
	ERRSTACK(2);
	struct proc *p;
	struct pgrp *pg;
	struct chan *tc;
	int pid;

	if (c->qid.type & QTDIR)
		return devopen(c, omode, 0, 0, procgen);

	if (QID(c->qid) == Qtrace) {
		error(ENOSYS, ERROR_FIXME);
#if 0
		if (omode != OREAD)
			error(EPERM, ERROR_FIXME);
		lock(&tlock);
		if (waserror()) {
			unlock(&tlock);
			nexterror();
		}
		if (topens > 0)
			error(EFAIL, "already open");
		topens++;
		if (tevents == NULL) {
			tevents = (Traceevent *) kzmalloc(sizeof(Traceevent) * Nevents,
											  MEM_WAIT);
			if (tevents == NULL)
				error(ENOMEM, ERROR_FIXME);
			tpids = kzmalloc(Ntracedpids * 20, MEM_WAIT);
			if (tpids == NULL) {
				kfree(tpids);
				tpids = NULL;
				error(ENOMEM, ERROR_FIXME);
			}
			tpidsc = tpids;
			tpidse = tpids + Ntracedpids * 20;
			*tpidsc = 0;
			tproduced = tconsumed = 0;
		}
		proctrace = _proctrace;
		poperror();
		unlock(&tlock);

		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
#endif
	}
	if (QID(c->qid) == Qtracepids) {
		error(ENOSYS, ERROR_FIXME);
#if 0
		if (omode != OREAD)
			error(EPERM, ERROR_FIXME);
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
#endif
	}
	if ((p = pid2proc(SLOT(c->qid))) == NULL)
		error(ESRCH, ERROR_FIXME);
	// qlock(&p->debug);
	if (waserror()) {
		// qunlock(&p->debug);
		proc_decref(p);
		nexterror();
	}
	pid = PID(c->qid);
	if (p->pid != pid)
		error(ESRCH, ERROR_FIXME);

	omode = openmode(omode);

	switch (QID(c->qid)) {
	case Qtext:
		error(ENOSYS, ERROR_FIXME);
		/*
		                        if (omode != OREAD)
		                                error(EPERM, ERROR_FIXME);
		                        tc = proctext(c, p);
		                        tc->offset = 0;
		                        poperror();
		                        qunlock(&p->debug);
		                        proc_decref(p);
		                        cclose(c);
		                        return tc;
		*/
	case Qproc:
	case Qsegment:
	case Qprofile:
	case Qfd:
		if (omode != O_READ)
			error(EPERM, ERROR_FIXME);
		break;

	case Qnote:
		//          if (p->privatemem)
		error(EPERM, ERROR_FIXME);
		break;

	case Qmem:
		//          if (p->privatemem)
		error(EPERM, ERROR_FIXME);
		// nonone(p);
		break;

	case Qargs:
	case Qnoteid:
	case Qwait:
	case Qregs:
	case Qfpregs:
	case Qkregs:
	case Qsyscall:
	case Qcore:
		nonone(p);
		break;

	case Qns:
		if (omode != O_READ)
			error(EPERM, ERROR_FIXME);
		c->aux = kzmalloc(sizeof(struct mntwalk), MEM_WAIT);
		break;
	case Quser:
	case Qstatus:
	case Qvmstatus:
	case Qctl:
		break;

	case Qstrace:
		if (!p->strace)
			error(ENOENT, "Process does not have tracing enabled");
		spin_lock(&p->strace->lock);
		if (p->strace->tracing) {
			spin_unlock(&p->strace->lock);
			error(EBUSY, "Process is already being traced");
		}
		/* It's not critical that we reopen before setting tracing, but
		 * it's a little cleaner (concurrent syscalls could be trying to
		 * use the queue before it was reopened, and they'd throw). */
		qreopen(p->strace->q);
		p->strace->tracing = TRUE;
		spin_unlock(&p->strace->lock);
		/* the ref we are upping is the one we put in __proc_free, which
		 * is the one we got from CMstrace{on,me}.  We have a ref on p,
		 * so we know we won't free until we decref the proc. */
		kref_get(&p->strace->users, 1);
		c->aux = p->strace;
		break;
	case Qstrace_traceset:
		if (!p->strace)
			error(ENOENT, "Process does not have tracing enabled");
		kref_get(&p->strace->users, 1);
		c->aux = p->strace;
		break;
	case Qmaps:
		c->aux = build_maps(p);
		break;
	case Qnotepg:
		error(ENOSYS, ERROR_FIXME);
#if 0
			nonone(p);
			pg = p->pgrp;
			if (pg == NULL)
				error(ESRCH, ERROR_FIXME);
			if (omode != OWRITE || pg->pgrpid == 1)
				error(EPERM, ERROR_FIXME);
			c->pgrpid.path = pg->pgrpid + 1;
			c->pgrpid.vers = p->noteid;
#endif
		break;

	default:
		printk("procopen %#llux\n", c->qid.path);
		error(EINVAL, ERROR_FIXME);
	}

	/* Affix pid to qid */
	//  if (p->state != Dead)
	c->qid.vers = p->pid;
	/* make sure the process slot didn't get reallocated while we were
	 * playing */
	// coherence();
	/* TODO: think about what we really want here.  In akaros, we wouldn't
	 * have our pid changed like that. */
	if (p->pid != pid)
		error(ESRCH, ERROR_FIXME);

	tc = devopen(c, omode, 0, 0, procgen);
	poperror();
	// qunlock(&p->debug);
	proc_decref(p);
	return tc;
}

static size_t procwstat(struct chan *c, uint8_t *db, size_t n)
{
	ERRSTACK(2);
	error(ENOSYS, ERROR_FIXME);
#if 0
	struct proc *p;
	struct dir *d;

	if (c->qid.type & QTDIR)
		error(EPERM, ERROR_FIXME);

	if (QID(c->qid) == Qtrace)
		return devwstat(c, db, n);

	if ((p = pid2proc(SLOT(c->qid))) == NULL)
		error(ESRCH, ERROR_FIXME);
	nonone(p);
	d = NULL;
	qlock(&p->debug);
	if (waserror()) {
		qunlock(&p->debug);
		proc_decref(p);
		kfree(d);
		nexterror();
	}

	if (p->pid != PID(c->qid))
		error(ESRCH, ERROR_FIXME);

	if (strcmp(current->user.name, p->user.name) != 0 && !iseve())
		error(EPERM, ERROR_FIXME);

	d = kzmalloc(sizeof(struct dir) + n, MEM_WAIT);
	n = convM2D(db, n, &d[0], (char *)&d[1]);
	if (n == 0)
		error(ENOENT, ERROR_FIXME);
	if (!emptystr(d->uid) && strcmp(d->uid, p->user.name) != 0) {
		if (!iseve())
			error(EPERM, ERROR_FIXME);
		else
			proc_set_username(p, d->uid);
	}
	if (d->mode != -1)
		p->procmode = d->mode & 0777;

	poperror();
	qunlock(&p->debug);
	proc_decref(p);
	kfree(d);

	return n;
#endif
}

#if 0
static long procoffset(long offset, char *va, int *np)
{
	if (offset > 0) {
		offset -= *np;
		if (offset < 0) {
			memmove(va, va + *np + offset, -offset);
			*np = -offset;
		} else
			*np = 0;
	}
	return offset;
}

static int procqidwidth(struct chan *c)
{
	char buf[32];

	return sprint(buf, "%lu", c->qid.vers);
}

int procfdprint(struct chan *c, int fd, int w, char *s, int ns)
{
	int n;

	if (w == 0)
		w = procqidwidth(c);
	n = snprint(s, ns,
				"%3d %.2s %C %4ud (%.16llux %*lud %.2ux) %5ld %8lld %s\n", fd,
				&"r w rw"[(c->mode & 3) << 1], c->dev->dc, c->devno,
				c->qid.path, w, c->qid.vers, c->qid.type, c->iounit, c->offset,
				c->name->s);
	return n;
}

static int procfds(struct proc *p, char *va, int count, long offset)
{
	ERRSTACK(2);
	struct fgrp *f;
	struct chan *c;
	char buf[256];
	int n, i, w, ww;
	char *a;

	/* print to buf to avoid holding fgrp lock while writing to user space */
	if (count > sizeof buf)
		count = sizeof buf;
	a = buf;

	qlock(&p->debug);
	f = p->fgrp;
	if (f == NULL) {
		qunlock(&p->debug);
		return 0;
	}
	lock(f);
	if (waserror()) {
		unlock(f);
		qunlock(&p->debug);
		nexterror();
	}

	n = readstr(0, a, count, p->dot->name->s);
	n += snprint(a + n, count - n, "\n");
	offset = procoffset(offset, a, &n);
	/* compute width of qid.path */
	w = 0;
	for (i = 0; i <= f->maxfd; i++) {
		c = f->fd[i];
		if (c == NULL)
			continue;
		ww = procqidwidth(c);
		if (ww > w)
			w = ww;
	}
	for (i = 0; i <= f->maxfd; i++) {
		c = f->fd[i];
		if (c == NULL)
			continue;
		n += procfdprint(c, i, w, a + n, count - n);
		offset = procoffset(offset, a, &n);
	}
	poperror();
	unlock(f);
	qunlock(&p->debug);

	/* copy result to user space, now that locks are released */
	memmove(va, buf, n);

	return n;
}
#endif
static void procclose(struct chan *c)
{
	if (QID(c->qid) == Qtrace) {
		spin_lock(&tlock);
		if (topens > 0)
			topens--;
		/* ??
		   if(topens == 0)
		   proctrace = notrace;
		 */
		spin_unlock(&tlock);
	}
	if (QID(c->qid) == Qsyscall) {
		if (c->aux)
			qclose(c->aux);
		c->aux = NULL;
	}
	if (QID(c->qid) == Qns && c->aux != 0)
		kfree(c->aux);
	if (QID(c->qid) == Qmaps && c->aux != 0)
		kfree(c->aux);
	if (QID(c->qid) == Qstrace && c->aux != 0) {
		struct strace *s = c->aux;

		assert(c->flag & COPEN); /* only way aux should have been set */
		s->tracing = FALSE;
		qhangup(s->q, NULL);
		kref_put(&s->users);
		c->aux = NULL;
	}
	if (QID(c->qid) == Qstrace_traceset && c->aux != 0) {
		struct strace *s = c->aux;

		assert(c->flag & COPEN);
		kref_put(&s->users);
		c->aux = NULL;
	}
}

void int2flag(int flag, char *s)
{
	if (flag == 0) {
		*s = '\0';
		return;
	}
	*s++ = '-';
	if (flag & MAFTER)
		*s++ = 'a';
	if (flag & MBEFORE)
		*s++ = 'b';
	if (flag & MCREATE)
		*s++ = 'c';
	if (flag & MCACHE)
		*s++ = 'C';
	*s = '\0';
}

#if 0
static char *argcpy(char *s, char *p)
{
	char *t, *tp, *te;
	int n;

	n = p - s;
	if (n > 128)
		n = 128;
	if (n <= 0) {
		t = kzmalloc(1, MEM_WAIT);
		*t = 0;
		return t;
	}
	t = kzmalloc(n, MEM_WAIT);
	tp = t;
	te = t + n;

	while (tp + 1 < te) {
		for (p--; p > s && p[-1] != 0; p--) ;
		tp = seprint(tp, te, "%q ", p);
		if (p == s)
			break;
	}
	if (*tp == ' ')
		*tp = 0;
	return t;
}

static int procargs(struct proc *p, char *buf, int nbuf)
{
	char *s;

	if (p->setargs == 0) {
		s = argcpy(p->args, p->args + p->nargs);
		kfree(p->args);
		p->nargs = strlen(s);
		p->args = s;
		p->setargs = 1;
	}
	return snprint(buf, nbuf, "%s", p->args);
}

static int eventsavailable(void *)
{
	return tproduced > tconsumed;
}
#endif

static size_t procread(struct chan *c, void *va, size_t n, off64_t off)
{
	ERRSTACK(1);
	struct proc *p;
	long l, r;
	int i, j, navail, pid, rsize;
	char flag[10], *sps, *srv;
	uintptr_t offset, u;
	int tesz;
	uint8_t *rptr;
	struct mntwalk *mw;
	struct strace *s;
	struct sized_alloc *sza;

	if (c->qid.type & QTDIR) {
		int nn;
		printd("procread: dir\n");
		nn = devdirread(c, va, n, 0, 0, procgen);
		printd("procread: %d\n", nn);
		return nn;
	}

	offset = off;
	/* Some shit in proc doesn't need to grab the reference.  For strace, we
	 * already have the chan open, and all we want to do is read the queue,
	 * which exists because of our kref on it. */
	switch (QID(c->qid)) {
	case Qstrace:
		s = c->aux;
		n = qread(s->q, va, n);
		return n;
	case Qstrace_traceset:
		s = c->aux;
		return readmem(offset, va, n, s->trace_set,
		               bitmap_size(MAX_SYSCALL_NR));
	}

	if ((p = pid2proc(SLOT(c->qid))) == NULL)
		error(ESRCH, "%d: no such process", SLOT(c->qid));
	if (p->pid != PID(c->qid)) {
		proc_decref(p);
		error(ESRCH, "weird: p->pid is %d, PID(c->qid) is %d: mismatch",
		      p->pid, PID(c->qid));
	}
	switch (QID(c->qid)) {
	default:
		proc_decref(p);
		break;
	case Quser: {
		int i;

		i = readstr(off, va, n, p->user.name);
		proc_decref(p);
		return i;
	}
	case Qstatus: {
		/* the old code grew the stack and was hideous.
		 * status is not a high frequency operation; just malloc. */
		char *buf = kmalloc(4096, MEM_WAIT);
		char *s = buf, *e = buf + 4096;
		int i;

		s = seprintf(s, e, "%8d %-*s %-10s %6d", p->pid,
		             PROC_PROGNAME_SZ, p->progname,
		             procstate2str(p->state), p->ppid);
		if (p->strace)
			s = seprintf(s, e, " %d trace users %d traced procs",
			             kref_refcnt(&p->strace->users),
			             kref_refcnt(&p->strace->procs));
		proc_decref(p);
		i = readstr(off, va, n, buf);
		kfree(buf);
		return i;
	}

	case Qvmstatus: {
		size_t buflen = 50 * 65 + 2;
		char *buf = kmalloc(buflen, MEM_WAIT);
		int i, offset;
		offset = 0;
		offset += snprintf(buf + offset, buflen - offset, "{\n");
		for (i = 0; i < 65; i++) {
			if (p->vmm.vmexits[i] != 0) {
				offset +=
				    snprintf(buf + offset, buflen - offset,
				             "\"%s\":\"%lld\",\n",
				             VMX_EXIT_REASON_NAMES[i],
				             p->vmm.vmexits[i]);
			}
		}
		offset += snprintf(buf + offset, buflen - offset, "}\n");
		proc_decref(p);
		n = readstr(off, va, n, buf);
		kfree(buf);
		return n;
	}
	case Qns:
		// qlock(&p->debug);
		if (waserror()) {
			// qunlock(&p->debug);
			proc_decref(p);
			nexterror();
		}
		if (p->pgrp == NULL || p->pid != PID(c->qid))
			error(ESRCH, ERROR_FIXME);
		mw = c->aux;
		if (mw->cddone) {
			poperror();
			// qunlock(&p->debug);
			proc_decref(p);
			return 0;
		}
		mntscan(mw, p);
		if (mw->mh == 0) {
			mw->cddone = 1;
			i = snprintf(va, n, "cd %s\n", p->dot->name->s);
			poperror();
			// qunlock(&p->debug);
			proc_decref(p);
			return i;
		}
		int2flag(mw->cm->mflag, flag);
		if (strcmp(mw->cm->to->name->s, "#mnt") == 0) {
			srv = srvname(mw->cm->to->mchan);
			i = snprintf(va, n, "mount %s %s %s %s\n", flag,
			             srv == NULL ? mw->cm->to->mchan->name->s
			                         : srv,
			             mw->mh->from->name->s,
			             mw->cm->spec ? mw->cm->spec : "");
			kfree(srv);
		} else
			i = snprintf(va, n, "bind %s %s %s\n", flag,
			             mw->cm->to->name->s,
			             mw->mh->from->name->s);
		poperror();
		// qunlock(&p->debug);
		proc_decref(p);
		return i;
	case Qmaps:
		sza = c->aux;
		i = readstr(off, va, n, sza->buf);
		proc_decref(p);
		return i;
	}
	error(EINVAL, "QID %d did not match any QIDs for #proc", QID(c->qid));
	return 0; /* not reached */
}

static void mntscan(struct mntwalk *mw, struct proc *p)
{
	struct pgrp *pg;
	struct mount *t;
	struct mhead *f;
	int best, i, last, nxt;

	pg = p->pgrp;
	rlock(&pg->ns);

	nxt = 0;
	best = (int)(~0U >> 1); /* largest 2's complement int */

	last = 0;
	if (mw->mh)
		last = mw->cm->mountid;

	for (i = 0; i < MNTHASH; i++) {
		for (f = pg->mnthash[i]; f; f = f->hash) {
			for (t = f->mount; t; t = t->next) {
				if (mw->mh == 0 ||
				    (t->mountid > last && t->mountid < best)) {
					mw->cm = t;
					mw->mh = f;
					best = mw->cm->mountid;
					nxt = 1;
				}
			}
		}
	}
	if (nxt == 0)
		mw->mh = 0;

	runlock(&pg->ns);
}

static size_t procwrite(struct chan *c, void *va, size_t n, off64_t off)
{
	ERRSTACK(2);

	struct proc *p, *t;
	int i, id, l;
	char *args;
	uintptr_t offset = off;
	struct strace *s;

	if (c->qid.type & QTDIR)
		error(EISDIR, ERROR_FIXME);

	if ((p = pid2proc(SLOT(c->qid))) == NULL)
		error(ESRCH, ERROR_FIXME);

	if (waserror()) {
		proc_decref(p);
		nexterror();
	}
	if (p->pid != PID(c->qid))
		error(ESRCH, ERROR_FIXME);

	offset = off;

	switch (QID(c->qid)) {
#if 0
		case Qargs:
			if (n == 0)
				error(EINVAL, ERROR_FIXME);
			if (n >= sizeof buf - strlen(p->text) - 1)
				error(E2BIG, ERROR_FIXME);
			l = snprintf(buf, sizeof buf, "%s [%s]", p->text, (char *)va);
			args = kzmalloc(l + 1, MEM_WAIT);
			if (args == NULL)
				error(ENOMEM, ERROR_FIXME);
			memmove(args, buf, l);
			args[l] = 0;
			kfree(p->args);
			p->nargs = l;
			p->args = args;
			p->setargs = 1;
			break;

		case Qmem:
			if (p->state != Stopped)
				error(EINVAL, ERROR_FIXME);

			n = procctlmemio(p, offset, n, va, 0);
			break;

		case Qregs:
			if (offset >= sizeof(Ureg))
				n = 0;
			else if (offset + n > sizeof(Ureg))
				n = sizeof(Ureg) - offset;
			if (p->dbgreg == 0)
				error(ENODATA, ERROR_FIXME);
			setregisters(p->dbgreg, (char *)(p->dbgreg) + offset, va, n);
			break;

		case Qfpregs:
			n = fpudevprocio(p, va, n, offset, 1);
			break;
#endif
	case Qctl:
		procctlreq(p, va, n);
		break;
	case Qstrace_traceset:
		s = c->aux;
		if (n + offset > bitmap_size(MAX_SYSCALL_NR))
			error(EINVAL,
			      "strace_traceset: Short write (%llu at off %llu)",
			      n, offset);
		if (memcpy_from_user(current, (void *)s->trace_set + offset, va,
		                     n))
			error(EFAULT, "strace_traceset: Bad addr (%p + %llu)",
			      va, n);
		break;
	default:
		error(EFAIL, "unknown qid %#llux in procwrite\n", c->qid.path);
	}
	poperror();
	proc_decref(p);
	return n;
}

struct dev procdevtab __devtab = {
    .name = "proc",

    .reset = devreset,
    .init = procinit,
    .shutdown = devshutdown,
    .attach = procattach,
    .walk = procwalk,
    .stat = procstat,
    .open = procopen,
    .create = devcreate,
    .close = procclose,
    .read = procread,
    .bread = devbread,
    .write = procwrite,
    .bwrite = devbwrite,
    .remove = devremove,
    .wstat = procwstat,
    .power = devpower,
    .chaninfo = devchaninfo,
};

#if 0
static struct chan *proctext(struct chan *c, struct proc *p)
{
	ERRSTACK(2);
	struct chan *tc;
	Image *i;
	Segment *s;

	s = p->seg[TSEG];
	if (s == 0)
		error(ENOENT, ERROR_FIXME);
	if (p->state == Dead)
		error(ESRCH, ERROR_FIXME);

	lock(s);
	i = s->image;
	if (i == 0) {
		unlock(s);
		error(ESRCH, ERROR_FIXME);
	}
	unlock(s);

	lock(i);
	if (waserror()) {
		unlock(i);
		nexterror();
	}

	tc = i->c;
	if (tc == 0)
		error(ESRCH, ERROR_FIXME);

	/* TODO: what do you want here?  you can't get a kref and have the new val
	 * be 1.  Here is the old code: if (kref_get(&tc->ref, 1) == 1 || ... ) */
	if (kref_refcnt(&tc->ref, 1) == 1 || (tc->flag & COPEN) == 0
		|| tc->mode != OREAD) {
		cclose(tc);
		error(ESRCH, ERROR_FIXME);
	}

	if (p->pid != PID(c->qid)) {
		cclose(tc);
		error(ESRCH, ERROR_FIXME);
	}

	poperror();
	unlock(i);

	return tc;
}

/* TODO: this will fail at compile time, since we don't have a proc-wide rendez,
 * among other things, and we'll need to rewrite this for akaros */
void procstopwait(struct proc *p, int ctl)
{
	ERRSTACK(2);
	int pid;

	if (p->pdbg)
		error(EBUSY, ERROR_FIXME);
	if (procstopped(p) || p->state == Broken)
		return;

	if (ctl != 0)
		p->procctl = ctl;
	p->pdbg = up;
	pid = p->pid;
	qunlock(&p->debug);
	current->psstate = "Stopwait";
	if (waserror()) {
		p->pdbg = 0;
		qlock(&p->debug);
		nexterror();
	}
	rendez_sleep(&current->sleep, procstopped, p);
	poperror();
	qlock(&p->debug);
	if (p->pid != pid)
		error(ESRCH, ERROR_FIXME);
}

#endif
static void procctlcloseone(struct proc *p, int fd)
{
	// TODO: resolve this and sys_close
	sysclose(fd);
	return;
}

void procctlclosefiles(struct proc *p, int all, int fd)
{
	int i;

	if (all)
		for (i = 0; i < NR_FILE_DESC_MAX; i++)
			procctlcloseone(p, i);
	else
		procctlcloseone(p, fd);
}

static void strace_shutdown(struct kref *a)
{
	struct strace *strace = container_of(a, struct strace, procs);
	static const char base_msg[] = "# Traced ~%lu syscs, Dropped %lu";
	size_t msg_len = NUMSIZE64 * 2 + sizeof(base_msg);
	char *msg = kmalloc(msg_len, 0);

	if (msg)
		snprintf(msg, msg_len, base_msg, strace->appx_nr_sysc,
		         atomic_read(&strace->nr_drops));
	qhangup(strace->q, msg);
	kfree(msg);
}

static void strace_release(struct kref *a)
{
	struct strace *strace = container_of(a, struct strace, users);

	qfree(strace->q);
	kfree(strace);
}

static void procctlreq(struct proc *p, char *va, size_t n)
{
	ERRSTACK(1);
	int8_t irq_state = 0;
	int npc, pri, core;
	struct cmdbuf *cb;
	struct cmdtab *ct;
	int64_t time;
	char *e;
	struct strace *strace;

	cb = parsecmd(va, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}

	ct = lookupcmd(cb, proccmd, ARRAY_SIZE(proccmd));

	switch (ct->index) {
	case CMstraceall:
	case CMstraceme:
	case CMstrace_drop:
		/* common allocation.  if we inherited, we might have one
		 * already */
		if (!p->strace) {
			strace = kzmalloc(sizeof(*p->strace), MEM_WAIT);
			spinlock_init(&strace->lock);
			bitmap_set(strace->trace_set, 0, MAX_SYSCALL_NR);
			strace->q = qopen(65536, Qmsg, NULL, NULL);
			/* The queue is reopened and hungup whenever we open the
			 * Qstrace file.  This hangup might not be necessary,
			 * but is safer. */
			qhangup(strace->q, NULL);
			/* both of these refs are put when the proc is freed.
			 * procs is for every process that has this p->strace.
			 * users is procs + every user (e.g. from open()).
			 *
			 * it is possible to kref_put the procs kref in
			 * proc_destroy, which would make strace's job easier
			 * (no need to do an async wait on the child), and we
			 * wouldn't need to decref p in procread(Qstrace).  But
			 * the downside is that proc_destroy races
			 * with us here with the kref initialization. */
			kref_init(&strace->procs, strace_shutdown, 1);
			kref_init(&strace->users, strace_release, 1);
			if (!atomic_cas_ptr((void **)&p->strace, 0, strace)) {
				/* someone else won the race and installed
				 * strace. */
				qfree(strace->q);
				kfree(strace);
				error(EAGAIN,
				      "Concurrent strace init, try again");
			}
		}
		break;
	}

	/* actually do the command. */
	switch (ct->index) {
	default:
		error(EFAIL, "Command not implemented");
		break;
	case CMclose:
		procctlclosefiles(p, 0, atoi(cb->f[1]));
		break;
	case CMclosefiles:
		procctlclosefiles(p, 1, 0);
		break;
#if 0
		we may want this.Let us pause a proc.case CMhang:p->hang = 1;
		break;
#endif
	case CMstraceme:
		p->strace->inherit = FALSE;
		break;
	case CMstraceall:
		p->strace->inherit = TRUE;
		break;
	case CMstrace_drop:
		if (!strcmp(cb->f[1], "on"))
			p->strace->drop_overflow = TRUE;
		else if (!strcmp(cb->f[1], "off"))
			p->strace->drop_overflow = FALSE;
		else
			error(EINVAL, "strace_drop takes on|off %s", cb->f[1]);
		break;
	}
	poperror();
	kfree(cb);
}

#if 0
static int procstopped(void *a)
{
	struct proc *p = a;
	return p->state == Stopped;
}

static int
procctlmemio(struct proc *p, uintptr_t offset, int n, void *va, int read)
{
	KMap *k;
	Pte *pte;
	Page *pg;
	Segment *s;
	uintptr_t soff, l;			/* hmmmm */
	uint8_t *b;
	uintmem pgsz;

	for (;;) {
		s = seg(p, offset, 1);
		if (s == 0)
			error(EINVAL, ERROR_FIXME);

		if (offset + n >= s->top)
			n = s->top - offset;

		if (!read && (s->type & SG_TYPE) == SG_TEXT)
			s = txt2data(p, s);

		s->steal++;
		soff = offset - s->base;
		if (waserror()) {
			s->steal--;
			nexterror();
		}
		if (fixfault(s, offset, read, 0, s->color) == 0)
			break;
		poperror();
		s->steal--;
	}
	poperror();
	pte = s->map[soff / PTEMAPMEM];
	if (pte == 0)
		panic("procctlmemio");
	pgsz = m->pgsz[s->pgszi];
	pg = pte->pages[(soff & (PTEMAPMEM - 1)) / pgsz];
	if (pagedout(pg))
		panic("procctlmemio1");

	l = pgsz - (offset & (pgsz - 1));
	if (n > l)
		n = l;

	k = kmap(pg);
	if (waserror()) {
		s->steal--;
		kunmap(k);
		nexterror();
	}
	b = (uint8_t *) VA(k);
	b += offset & (pgsz - 1);
	if (read == 1)
		memmove(va, b, n);	/* This can fault */
	else
		memmove(b, va, n);
	poperror();
	kunmap(k);

	/* Ensure the process sees text page changes */
	if (s->flushme)
		memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl));

	s->steal--;

	if (read == 0)
		p->newtlb = 1;

	return n;
}

static Segment *txt2data(struct proc *p, Segment * s)
{
	int i;
	Segment *ps;

	ps = newseg(SG_DATA, s->base, s->size);
	ps->image = s->image;
	kref_get(&ps->image->ref, 1);
	ps->fstart = s->fstart;
	ps->flen = s->flen;
	ps->flushme = 1;

	qlock(&p->seglock);
	for (i = 0; i < NSEG; i++)
		if (p->seg[i] == s)
			break;
	if (i == NSEG)
		panic("segment gone");

	qunlock(&s->lk);
	putseg(s);
	qlock(&ps->lk);
	p->seg[i] = ps;
	qunlock(&p->seglock);

	return ps;
}

Segment *data2txt(Segment * s)
{
	Segment *ps;

	ps = newseg(SG_TEXT, s->base, s->size);
	ps->image = s->image;
	kref_get(&ps->image->ref, 1);
	ps->fstart = s->fstart;
	ps->flen = s->flen;
	ps->flushme = 1;

	return ps;
}
#endif
