Added explicit errno reporting from error() API.
[akaros.git] / kern / drivers / dev / pipe.c
index da2dba8..495a614 100644 (file)
 #include <smp.h>
 #include <ip.h>
 
+struct dev pipedevtab;
+
+static char *devname(void)
+{
+       return pipedevtab.name;
+}
+
 typedef struct Pipe Pipe;
 struct Pipe {
        qlock_t qlock;
@@ -58,7 +65,6 @@ static void freepipe(Pipe * p)
 static void pipe_release(struct kref *kref)
 {
        Pipe *pipe = container_of(kref, Pipe, ref);
-       qunlock(&pipe->qlock);
        freepipe(pipe);
 }
 
@@ -76,17 +82,17 @@ static struct chan *pipeattach(char *spec)
        Pipe *p;
        struct chan *c;
 
-       c = devattach('|', spec);
+       c = devattach(devname(), spec);
        p = kzmalloc(sizeof(Pipe), 0);
        if (p == 0)
-               error(Enomem);
+               error(ENOMEM, NULL);
        if (waserror()) {
                freepipe(p);
                nexterror();
        }
        p->pipedir = kzmalloc(sizeof(pipedir), 0);
        if (p->pipedir == 0)
-               error(Enomem);
+               error(ENOMEM, NULL);
        memmove(p->pipedir, pipedir, sizeof(pipedir));
        kstrdup(&p->user, current->user);
        kref_init(&p->ref, pipe_release, 1);
@@ -94,10 +100,10 @@ static struct chan *pipeattach(char *spec)
 
        p->q[0] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
        if (p->q[0] == 0)
-               error(Enomem);
+               error(ENOMEM, NULL);
        p->q[1] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
        if (p->q[1] == 0)
-               error(Enomem);
+               error(ENOMEM, NULL);
        poperror();
 
        spin_lock(&(&pipealloc)->lock);
@@ -121,7 +127,7 @@ pipegen(struct chan *c, char *unused,
        Pipe *p;
 
        if (i == DEVDOTDOT) {
-               devdir(c, c->qid, "#|", 0, eve, 0555, dp);
+               devdir(c, c->qid, devname(), 0, eve, 0555, dp);
                return 1;
        }
        i++;    /* skip . */
@@ -200,7 +206,7 @@ static int pipestat(struct chan *c, uint8_t * db, int n)
        }
        n = convD2M(&dir, db, n);
        if (n < BIT16SZ)
-               error(Eshortstat);
+               error(ENODATA, NULL);
        return n;
 }
 
@@ -213,8 +219,8 @@ static struct chan *pipeopen(struct chan *c, int omode)
        Pipe *p;
 
        if (c->qid.type & QTDIR) {
-               if (!IS_RDONLY(omode))
-                       error("Can only open directories OREAD, mode is %o oct", omode);
+               if (omode & O_WRITE)
+                       error(EFAIL, "Can only open directories O_READ, mode is %o oct", omode);
                c->mode = openmode(omode);
                c->flag |= COPEN;
                c->offset = 0;
@@ -286,11 +292,11 @@ static void pipeclose(struct chan *c)
                qreopen(p->q[1]);
        }
 
+       qunlock(&p->qlock);
        /*
         *  free the structure on last close
         */
        kref_put(&p->ref);
-       qunlock(&p->qlock);
 }
 
 static long piperead(struct chan *c, void *va, long n, int64_t ignored)
@@ -416,10 +422,10 @@ static int pipewstat(struct chan *c, uint8_t * dp, int n)
        int d1;
 
        if (c->qid.type & QTDIR)
-               error(Eperm);
+               error(EPERM, NULL);
        p = c->aux;
        if (strcmp(current->user, p->user) != 0)
-               error(Eperm);
+               error(EPERM, NULL);
        d = kzmalloc(sizeof(*d) + n, 0);
        if (waserror()) {
                kfree(d);
@@ -427,14 +433,14 @@ static int pipewstat(struct chan *c, uint8_t * dp, int n)
        }
        n = convM2D(dp, n, d, (char *)&d[1]);
        if (n == 0)
-               error(Eshortstat);
+               error(ENODATA, NULL);
        d1 = NETTYPE(c->qid.path) == Qdata1;
        if (!emptystr(d->name)) {
                validwstatname(d->name);
                if (strlen(d->name) >= KNAMELEN)
-                       error(Efilename);
+                       error(ENAMETOOLONG, NULL);
                if (strcmp(p->pipedir[1 + !d1].name, d->name) == 0)
-                       error(Eexist);
+                       error(EEXIST, NULL);
                strncpy(p->pipedir[1 + d1].name, d->name,
                                MIN(KNAMELEN, sizeof(p->pipedir[1 + d1].name, d->name)));
        }
@@ -446,7 +452,6 @@ static int pipewstat(struct chan *c, uint8_t * dp, int n)
 }
 
 struct dev pipedevtab __devtab = {
-       '|',
        "pipe",
 
        devreset,