cap: Fix openmode issue
[akaros.git] / kern / drivers / dev / proc.c
index 59d9c89..ea35586 100644 (file)
@@ -57,6 +57,7 @@ enum {
        Qnotepg,
        Qproc,
        Qregs,
+       Quser,
        Qsegment,
        Qstatus,
        Qstrace,
@@ -120,6 +121,7 @@ struct dirtab procdir[] = {
        {"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, 0666},
@@ -222,7 +224,7 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
        uint32_t path, perm, len;
        if (s == DEVDOTDOT) {
                mkqid(&qid, Qdir, 0, QTDIR);
-               devdir(c, qid, devname(), 0, eve, 0555, dp);
+               devdir(c, qid, devname(), 0, eve.name, 0555, dp);
                return 1;
        }
 
@@ -230,20 +232,20 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
                if (s == 0) {
                        strlcpy(get_cur_genbuf(), "trace", GENBUF_SZ);
                        mkqid(&qid, Qtrace, -1, QTFILE);
-                       devdir(c, qid, get_cur_genbuf(), 0, eve, 0444, dp);
+                       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, 0444, dp);
+                       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, DMDIR | 0555, dp);
+                       devdir(c, qid, get_cur_genbuf(), 0, p->user.name, DMDIR | 0555, dp);
                        return 1;
                }
                s -= 3;
@@ -274,24 +276,24 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
                 */
                if (name != NULL && strcmp(name, get_cur_genbuf()) != 0) {
                        printk("pid-name mismatch, name: %s, pid %d\n", name, pid);
-                       kref_put(&p->p_kref);
+                       proc_decref(p);
                        return -1;
                }
                mkqid(&qid, (s + 1) << QSHIFT, pid, QTDIR);
-               devdir(c, qid, get_cur_genbuf(), 0, p->user, DMDIR | 0555, dp);
-               kref_put(&p->p_kref);
+               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, 0444, dp);
+               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, 0444, dp);
+               devdir(c, qid, get_cur_genbuf(), 0, eve.name, 0444, dp);
                return 1;
        }
        if (s >= ARRAY_SIZE(procdir))
@@ -330,8 +332,8 @@ procgen(struct chan *c, char *name, struct dirtab *tab, int unused, int s,
 #endif
 
        mkqid(&qid, path | tab->qid.path, c->qid.vers, QTFILE);
-       devdir(c, qid, tab->name, len, p->user, perm, dp);
-       kref_put(&p->p_kref);
+       devdir(c, qid, tab->name, len, p->user.name, perm, dp);
+       proc_decref(p);
        return 1;
 }
 
@@ -413,7 +415,7 @@ static void nonone(struct proc *p)
 #if 0
        if (p == up)
                return;
-       if (strcmp(current->user, "none") != 0)
+       if (strcmp(current->user.name, "none") != 0)
                return;
        if (iseve())
                return;
@@ -553,7 +555,7 @@ static struct chan *procopen(struct chan *c, int omode)
        //qlock(&p->debug);
        if (waserror()) {
                //qunlock(&p->debug);
-               kref_put(&p->p_kref);
+               proc_decref(p);
                nexterror();
        }
        pid = PID(c->qid);
@@ -572,7 +574,7 @@ static struct chan *procopen(struct chan *c, int omode)
                        tc->offset = 0;
                        poperror();
                        qunlock(&p->debug);
-                       kref_put(&p->p_kref);
+                       proc_decref(p);
                        cclose(c);
                        return tc;
 */
@@ -611,6 +613,7 @@ static struct chan *procopen(struct chan *c, int omode)
                                error(EPERM, ERROR_FIXME);
                        c->aux = kzmalloc(sizeof(struct mntwalk), MEM_WAIT);
                        break;
+               case Quser:
                case Qstatus:
                case Qvmstatus:
                case Qctl:
@@ -660,7 +663,7 @@ static struct chan *procopen(struct chan *c, int omode)
        tc = devopen(c, omode, 0, 0, procgen);
        poperror();
        //qunlock(&p->debug);
-       kref_put(&p->p_kref);
+       proc_decref(p);
        return tc;
 }
 
@@ -685,7 +688,7 @@ static int procwstat(struct chan *c, uint8_t * db, int n)
        qlock(&p->debug);
        if (waserror()) {
                qunlock(&p->debug);
-               kref_put(&p->p_kref);
+               proc_decref(p);
                kfree(d);
                nexterror();
        }
@@ -693,25 +696,25 @@ static int procwstat(struct chan *c, uint8_t * db, int n)
        if (p->pid != PID(c->qid))
                error(ESRCH, ERROR_FIXME);
 
-       if (strcmp(current->user, p->user) != 0 && strcmp(current->user, eve) != 0)
+       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) != 0) {
-               if (strcmp(current->user, eve) != 0)
+       if (!emptystr(d->uid) && strcmp(d->uid, p->user.name) != 0) {
+               if (!iseve())
                        error(EPERM, ERROR_FIXME);
                else
-                       kstrdup(&p->user, d->uid);
+                       proc_set_username(p, d->uid);
        }
        if (d->mode != ~0UL)
                p->procmode = d->mode & 0777;
 
        poperror();
        qunlock(&p->debug);
-       kref_put(&p->p_kref);
+       proc_decref(p);
        kfree(d);
 
        return n;
@@ -942,14 +945,21 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
        if ((p = pid2proc(SLOT(c->qid))) == NULL)
                error(ESRCH, "%d: no such process", SLOT(c->qid));
        if (p->pid != PID(c->qid)) {
-               kref_put(&p->p_kref);
+               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:
-                       kref_put(&p->p_kref);
+                       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. */
@@ -965,7 +975,7 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                                        s = seprintf(s, e, " %d trace users %d traced procs",
                                                     kref_refcnt(&p->strace->users),
                                                     kref_refcnt(&p->strace->procs));
-                               kref_put(&p->p_kref);
+                               proc_decref(p);
                                i = readstr(off, va, n, buf);
                                kfree(buf);
                                return i;
@@ -987,7 +997,7 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                                        }
                                }
                                offset += snprintf(buf + offset, buflen - offset, "}\n");
-                               kref_put(&p->p_kref);
+                               proc_decref(p);
                                n = readstr(off, va, n, buf);
                                kfree(buf);
                                return n;
@@ -996,7 +1006,7 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                        //qlock(&p->debug);
                        if (waserror()) {
                                //qunlock(&p->debug);
-                               kref_put(&p->p_kref);
+                               proc_decref(p);
                                nexterror();
                        }
                        if (p->pgrp == NULL || p->pid != PID(c->qid))
@@ -1005,7 +1015,7 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                        if (mw->cddone) {
                                poperror();
                                //qunlock(&p->debug);
-                               kref_put(&p->p_kref);
+                               proc_decref(p);
                                return 0;
                        }
                        mntscan(mw, p);
@@ -1014,7 +1024,7 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                                i = snprintf(va, n, "cd %s\n", p->dot->name->s);
                                poperror();
                                //qunlock(&p->debug);
-                               kref_put(&p->p_kref);
+                               proc_decref(p);
                                return i;
                        }
                        int2flag(mw->cm->mflag, flag);
@@ -1030,12 +1040,12 @@ static long procread(struct chan *c, void *va, long n, int64_t off)
                                                         mw->cm->to->name->s, mw->mh->from->name->s);
                        poperror();
                        //qunlock(&p->debug);
-                       kref_put(&p->p_kref);
+                       proc_decref(p);
                        return i;
                case Qmaps:
                        sza = c->aux;
                        i = readmem(off, va, n, sza->buf, sza->size);
-                       kref_put(&p->p_kref);
+                       proc_decref(p);
                        return i;
        }
        error(EINVAL, "QID %d did not match any QIDs for #proc", QID(c->qid));
@@ -1093,7 +1103,7 @@ static long procwrite(struct chan *c, void *va, long n, int64_t off)
                error(ESRCH, ERROR_FIXME);
 
        if (waserror()) {
-               kref_put(&p->p_kref);
+               proc_decref(p);
                nexterror();
        }
        if (p->pid != PID(c->qid))
@@ -1158,7 +1168,7 @@ static long procwrite(struct chan *c, void *va, long n, int64_t off)
                        error(EFAIL, "unknown qid %#llux in procwrite\n", c->qid.path);
        }
        poperror();
-       kref_put(&p->p_kref);
+       proc_decref(p);
        return n;
 }