Address FIXME of _open(); a catch-all ENFILE was returned for any
authorAndy Valencia <ajv-899-334-8894@vsta.org>
Mon, 18 Jul 2016 21:41:34 +0000 (14:41 -0700)
committerAndy Valencia <ajv-899-334-8894@vsta.org>
Mon, 18 Jul 2016 21:41:34 +0000 (14:41 -0700)
 failure leading into newfile() (parent == NULL), or within newfile()
 (and its supporting routines, such as i_open() and ch_link()).
Instead, newfile() uniformly detects and sets errors (or lets errors
 from supporting routines propagate upward).  _open() is restructured
 to leave udata.u_error as set by newfile(), and thus permit the
 actual error code to reach the user.
"touch /x" when you don't have write access to "/" will thus now get
 EPERM, not ENFILE.

Kernel/filesys.c
Kernel/syscall_fs3.c

index cb5017a..57ac39c 100644 (file)
@@ -411,17 +411,27 @@ inoptr newfile(inoptr pino, char *name)
     inoptr nindex;
     uint8_t j;
 
+    /* No parent? */
+    if (!pino) {
+        udata.u_error = ENXIO;
+        goto nogood;
+    }
+
     /* First see if parent is writeable */
     if (pino->c_flags & CRDONLY) {
         udata.u_error = EROFS;
         goto nogood;
     }
 
-    if(!(getperm(pino) & OTH_WR))
+    if (!(getperm(pino) & OTH_WR)) {
+        udata.u_error = EPERM;
         goto nogood;
+    }
 
-    if(!(nindex = i_open(pino->c_dev, 0)))
+    if (!(nindex = i_open(pino->c_dev, 0))) {
+        udata.u_error = ENFILE;
         goto nogood;
+    }
 
     /* This does not implement BSD style "sticky" groups */
     nindex->c_node.i_uid = udata.u_euid;
@@ -430,12 +440,14 @@ inoptr newfile(inoptr pino, char *name)
     nindex->c_node.i_mode = F_REG;   /* For the time being */
     nindex->c_node.i_nlink = 1;
     nindex->c_node.i_size = 0;
-    for(j=0; j <20; j++)
+    for (j = 0; j < 20; j++) {
         nindex->c_node.i_addr[j] = 0;
+    }
     wr_inode(nindex);
 
-    if(!ch_link(pino, "", name, nindex)) {
+    if (!ch_link(pino, "", name, nindex)) {
         i_deref(nindex);
+       /* ch_link sets udata.u_error */
         goto nogood;
     }
     i_deref(pino);
index 5fccbeb..2f63b4f 100644 (file)
@@ -55,24 +55,28 @@ arg_t _open(void)
                /* The n_open failed */
                if (udata.u_error == EFAULT)
                        goto cantopen;
+
                /* New file */
                if (!(flag & O_CREAT)) {
                        udata.u_error = ENOENT;
                        goto cantopen;
                }
                filename(name, fname);
+
                /* newfile drops parent for us */
-               if (parent && (ino = newfile(parent, fname))) {
-                       ino->c_node.i_mode =
-                           (F_REG | (mode & MODE_MASK & ~udata.u_mask));
-                       setftime(ino, A_TIME | M_TIME | C_TIME);
-                       wr_inode(ino);
-               } else {
-                       udata.u_error = ENFILE; /* FIXME, should be set in newfile
-                                                  not bodged to a guessed code */
+               ino = newfile(parent, fname);
+               if (!ino) {
+                       /* on error, newfile sets udata.u_error */
                        goto cantopen;
                }
+
+               /* new inode, successfully created */
+               ino->c_node.i_mode =
+                   (F_REG | (mode & MODE_MASK & ~udata.u_mask));
+               setftime(ino, A_TIME | M_TIME | C_TIME);
+               wr_inode(ino);
        }
+
        /* Book our slot in case we block opening a device */
        of_tab[oftindex].o_inode = ino;