static int procgen(Chan *c, char *name, Dirtab *tab, int, int s, Dir *dp) { Qid qid; Proc *p; char *ename; Segment *q; int pid; ulong path, perm, len; if(s == DEVDOTDOT){ mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, "#p", 0, eve, 0555, dp); return 1; } if(c->qid.path == Qdir){ if(s == 0){ strcpy(up->genbuf, "trace"); mkqid(&qid, Qtrace, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } if(name != nil){ /* ignore s and use name to find pid */ pid = strtol(name, &ename, 10); if(pid<=0 || ename[0]!='\0') return -1; s = psindex(pid); if(s < 0) return -1; } else if(--s >= procalloc.nproc) return -1; if((p = psincref(s)) == nil || (pid = p->pid) == 0) return 0; sprint(up->genbuf, "%d", pid); /* * String comparison is done in devwalk so * name must match its formatted pid. */ if(name != nil && strcmp(name, up->genbuf) != 0) return -1; mkqid(&qid, (s+1)<<QSHIFT, pid, QTDIR); devdir(c, qid, up->genbuf, 0, p->user, DMDIR|0555, dp); psdecref(p); return 1; } if(c->qid.path == Qtrace){ strcpy(up->genbuf, "trace"); mkqid(&qid, Qtrace, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } if(s >= nelem(procdir)) return -1; if(tab) panic("procgen"); tab = &procdir[s]; path = c->qid.path&~(((1<<QSHIFT)-1)); /* slot component */ if((p = psincref(SLOT(c->qid))) == nil) return -1; perm = tab->perm; if(perm == 0) perm = p->procmode; else /* just copy read bits */ perm |= p->procmode & 0444; len = tab->length; 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; }
static int procgen(Chan *c, char *name, Dirtab *tab, int j, int s, Dir *dp) { Proc *up = externup(); Qid qid; Proc *p; char *ename; int pid, sno; uint32_t path, perm, len; if(s == DEVDOTDOT){ mkqid(&qid, Qdir, 0, QTDIR); devdir(c, qid, "#p", 0, eve, 0555, dp); return 1; } if(c->qid.path == Qdir){ if(s == 0){ strcpy(up->genbuf, "trace"); mkqid(&qid, Qtrace, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } if(s == 1){ strcpy(up->genbuf, "tracepids"); mkqid(&qid, Qtracepids, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } s -= 2; if(name != nil){ /* ignore s and use name to find pid */ pid = strtol(name, &ename, 10); if(pid<=0 || ename[0]!='\0') return -1; s = psindex(pid); if(s < 0) return -1; } else if(s >= conf.nproc) return -1; if((p = psincref(s)) == nil || (pid = p->pid) == 0) return 0; snprint(up->genbuf, sizeof up->genbuf, "%u", pid); /* * String comparison is done in devwalk so * name must match its formatted pid. */ if(name != nil && strcmp(name, up->genbuf) != 0) return -1; mkqid(&qid, (s+1)<<QSHIFT, pid, QTDIR); devdir(c, qid, up->genbuf, 0, p->user, DMDIR|0555, dp); psdecref(p); return 1; } if(c->qid.path == Qtrace){ strcpy(up->genbuf, "trace"); mkqid(&qid, Qtrace, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } if(c->qid.path == Qtracepids){ strcpy(up->genbuf, "tracepids"); mkqid(&qid, Qtrace, -1, QTFILE); devdir(c, qid, up->genbuf, 0, eve, 0444, dp); return 1; } if(s >= nelem(procdir)) return -1; if(tab) panic("procgen"); tab = &procdir[s]; path = c->qid.path&~(((1<<QSHIFT)-1)); /* slot component */ if((p = psincref(SLOT(c->qid))) == nil) return -1; perm = tab->perm; if(perm == 0) perm = p->procmode; else /* just copy read bits */ perm |= p->procmode & 0444; len = tab->length; switch(QID(c->qid)) { case Qwait: len = p->nwait; /* incorrect size, but >0 means there's something to read */ break; case Qprofile: /* TODO(aki): test this */ len = 0; for(sno = 0; sno < NSEG; sno++){ if(p->seg[sno] != nil && (p->seg[sno]->type & SG_EXEC) != 0){ Segment *s; s = p->seg[sno]; if(s->profile) len += ((s->top-s->base)>>LRESPROF) * sizeof s->profile[0]; } } break; }