Fix Plan 9 partial write() return values
[akaros.git] / kern / src / ns / sysfile.c
index 08dccca..16cd623 100644 (file)
@@ -353,52 +353,6 @@ int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen)
        return m;
 }
 
-int syspipe(int fd[2])
-{
-       ERRSTACK(1);
-       struct dev *d;
-       struct chan *c[2];
-       static char *names[] = { "data", "data1" };
-
-       d = &devtab[devno("pipe", 0)];
-       c[0] = 0;
-       c[1] = 0;
-       fd[0] = -1;
-       fd[1] = -1;
-       if (waserror()) {
-               /* need to remove from the fd table and make sure the chan is closed
-                * exactly once.  if fd[i] >= 0, then the fd is valid (or it was!) and
-                * the fd table has the only ref (newfd() currently decrefs/consumes the
-                * reference).  cclose() doesn't care if you pass it 0 (like kfree()). */
-               if (fd[0] >= 0)
-                       close_fd(&current->open_files, fd[0]);
-               else
-                       cclose(c[0]);
-               if (fd[1] >= 0)
-                       close_fd(&current->open_files, fd[1]);
-               else
-                       cclose(c[1]);
-               poperror();
-               return -1;
-       }
-       c[0] = namec("#pipe", Atodir, 0, 0);
-       c[1] = cclone(c[0]);
-       if (walk(&c[0], &names[0], 1, FALSE, NULL) < 0)
-               error(EINVAL, ERROR_FIXME);
-       if (walk(&c[1], &names[1], 1, FALSE, NULL) < 0)
-               error(EINVAL, ERROR_FIXME);
-       c[0] = d->open(c[0], O_RDWR);
-       c[1] = d->open(c[1], O_RDWR);
-       fd[0] = newfd(c[0], 0);
-       if (fd[0] < 0)
-               error(-fd[0], ERROR_FIXME);
-       fd[1] = newfd(c[1], 0);
-       if (fd[1] < 0)
-               error(-fd[1], ERROR_FIXME);
-       poperror();
-       return 0;
-}
-
 int sysfwstat(int fd, uint8_t * buf, int n)
 {
        ERRSTACK(2);
@@ -568,6 +522,8 @@ int sysopenat(int fromfd, char *path, int vfs_flags)
                 * and give us something new for c.  On error, namec_from will cclose
                 * from. */
                from = fdtochan(&current->open_files, fromfd, -1, FALSE, TRUE);
+               if (!(from->flag & O_PATH))
+                       error(EINVAL, "Cannot openat from a non-O_PATH FD");
                c = namec_from(from, path, Aopen, vfs_flags, 0);
        }
        fd = newfd(c, vfs_flags);
@@ -840,12 +796,6 @@ int64_t sysseek(int fd, int64_t off, int whence)
                cclose(c);
                nexterror();
        }
-
-       /* TODO: WTF is this?  Is pipe magically the only device that isn't
-        * seekable? */
-       if (!strcmp(devtab[c->type].name, "pipe"))
-               error(EINVAL, ERROR_FIXME);
-
        switch (whence) {
                case 0:
                        if (c->qid.type & QTDIR) {
@@ -900,7 +850,7 @@ int64_t sysseek(int fd, int64_t off, int whence)
 
 void validstat(uint8_t * s, int n, int slashok)
 {
-       
+
        int m;
        char buf[64];
 
@@ -952,7 +902,7 @@ int sysfstat(int fd, uint8_t *buf, int n)
 
 int sysfstatakaros(int fd, struct kstat *ks)
 {
-       
+
        int n = 4096;
        uint8_t *buf;
        buf = kmalloc(n, MEM_WAIT);
@@ -991,7 +941,7 @@ int sysstat(char *path, uint8_t *buf, int n)
 
 int sysstatakaros(char *path, struct kstat *ks)
 {
-       
+
        int n = 4096;
        uint8_t *buf;
        buf = kmalloc(n, MEM_WAIT);
@@ -1069,7 +1019,7 @@ static long rwrite(int fd, void *va, long n, int64_t * offp)
        cclose(c);
 
        poperror();
-       return n;
+       return m;
 }
 
 long syswrite(int fd, void *va, long n)
@@ -1190,7 +1140,7 @@ struct dir *sysdirfstat(int fd)
 
 int sysdirwstat(char *name, struct dir *dir)
 {
-       
+
        uint8_t *buf;
        int r;
 
@@ -1204,7 +1154,7 @@ int sysdirwstat(char *name, struct dir *dir)
 
 int sysdirfwstat(int fd, struct dir *dir)
 {
-       
+
        uint8_t *buf;
        int r;
 
@@ -1218,7 +1168,7 @@ int sysdirfwstat(int fd, struct dir *dir)
 
 static long dirpackage(uint8_t * buf, long ts, struct kdirent **d)
 {
-       
+
        char *s;
        long ss, i, n, nn, m = 0;
 
@@ -1313,20 +1263,18 @@ int sysiounit(int fd)
 
 void print_chaninfo(struct chan *c)
 {
-       
-       char buf[64] = { 0 };
+
+       char buf[128] = { 0 };
        bool has_dev = c->type != -1;
-       if (has_dev && !devtab[c->type].chaninfo) {
-               printk("Chan type %d has no chaninfo!\n", c->type);
-               has_dev = FALSE;
-       }
+       bool has_chaninfo = has_dev && devtab[c->type].chaninfo;
+
        printk("Chan flags: %p, pathname: %s, ref: %d, Dev: %s, Devinfo: %s",
                   c->flag,
                   c->name ? c->name->s : "no cname",
                   kref_refcnt(&c->ref),
                   has_dev ? devtab[c->type].name : "no dev",
-                  has_dev ? devtab[c->type].chaninfo(c, buf, sizeof(buf)) : "");
-       if (!has_dev)
+                  has_chaninfo ? devtab[c->type].chaninfo(c, buf, sizeof(buf)) : "");
+       if (!has_chaninfo)
                printk("qid.path: %p\n", c->qid.path);
        printk("\n");
 }
@@ -1336,7 +1284,7 @@ void print_chaninfo(struct chan *c)
  * the pgrp. */
 int plan9setup(struct proc *new_proc, struct proc *parent, int flags)
 {
-       
+
        struct kref *new_dot_ref;
        ERRSTACK(1);
        if (waserror()) {
@@ -1452,6 +1400,8 @@ int fd_setfl(int fd, int flags)
                /* TODO: The whole CCEXEC / O_CLOEXEC on 9ns needs work */
                error(EINVAL, "can't toggle O_CLOEXEC with setfl");
        }
+       if (cexternal_flags_differ(flags, c->flag, O_REMCLO))
+               error(EINVAL, "can't toggle O_REMCLO with setfl");
        if (cexternal_flags_differ(flags, c->flag, O_PATH))
                error(EINVAL, "can't toggle O_PATH with setfl");
        /* Devices can do various prep work, including RPCs to other servers (#mnt)