Fix Plan 9 partial write() return values
[akaros.git] / kern / src / ns / sysfile.c
index 1cd310c..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);
@@ -848,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];
 
@@ -900,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);
@@ -939,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);
@@ -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)
@@ -1138,7 +1140,7 @@ struct dir *sysdirfstat(int fd)
 
 int sysdirwstat(char *name, struct dir *dir)
 {
-       
+
        uint8_t *buf;
        int r;
 
@@ -1152,7 +1154,7 @@ int sysdirwstat(char *name, struct dir *dir)
 
 int sysdirfwstat(int fd, struct dir *dir)
 {
-       
+
        uint8_t *buf;
        int r;
 
@@ -1166,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;
 
@@ -1261,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");
 }
@@ -1284,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()) {
@@ -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)