From: Andy Valencia Date: Mon, 18 Jul 2016 21:41:34 +0000 (-0700) Subject: Address FIXME of _open(); a catch-all ENFILE was returned for any X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=784a56968cd3b5479b0880e76b649cd3ca5006a8;p=FUZIX.git Address FIXME of _open(); a catch-all ENFILE was returned for any 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. --- diff --git a/Kernel/filesys.c b/Kernel/filesys.c index cb5017a3..57ac39c2 100644 --- a/Kernel/filesys.c +++ b/Kernel/filesys.c @@ -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); diff --git a/Kernel/syscall_fs3.c b/Kernel/syscall_fs3.c index 5fccbebc..2f63b4f5 100644 --- a/Kernel/syscall_fs3.c +++ b/Kernel/syscall_fs3.c @@ -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;