Fix Plan 9 partial write() return values
[akaros.git] / kern / src / ns / sysfile.c
index 72cfeea..16cd623 100644 (file)
@@ -522,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);
@@ -1017,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)
@@ -1262,19 +1264,17 @@ 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");
 }
@@ -1400,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)