diff options
Diffstat (limited to 'sysfile.c')
-rw-r--r-- | sysfile.c | 67 |
1 files changed, 36 insertions, 31 deletions
@@ -115,34 +115,41 @@ int sys_open(void) { struct inode *ip, *dp; - char *path; + char *path, *name; + int namelen; int omode; - int fd; + int fd, dev; + uint inum; struct file *f; - char *last; if(argstr(0, &path) < 0 || argint(1, &omode) < 0) return -1; - if(omode & O_CREATE){ - dp = namei(path, NAMEI_CREATE, 0, &last, &ip); - if(dp){ - ip = mknod1(dp, last, T_FILE, 0, 0); - iput(dp); - if(ip == 0) - return -1; - } else if(ip == 0){ + switch(omode & O_CREATE){ + default: + case 0: // regular open + if((ip = namei(path)) == 0) return -1; - } else if(ip->type == T_DIR){ - iput(ip); + break; + + case O_CREATE: + if((dp = nameiparent(path, &name, &namelen)) == 0) return -1; + if(dirlookup(dp, name, namelen, 0, &inum) >= 0){ + dev = dp->dev; + iput(dp); + ip = iget(dev, inum); + }else{ + if((ip = dircreat(dp, name, namelen, T_FILE, 0, 0)) == 0){ + iput(dp); + return -1; + } + iput(dp); } - } else { - ip = namei(path, NAMEI_LOOKUP, 0, 0, 0); - if(ip == 0) - return -1; + break; } - if(ip->type == T_DIR && ((omode & O_RDWR) || (omode & O_WRONLY))){ + + if(ip->type == T_DIR && (omode & (O_RDWR|O_WRONLY|O_CREATE))){ iput(ip); return -1; } @@ -201,18 +208,22 @@ sys_mkdir(void) { struct inode *nip; struct inode *dp; - char *path; + char *name, *path; struct dirent de; - char *last; + int namelen; if(argstr(0, &path) < 0) return -1; - dp = namei(path, NAMEI_CREATE, 0, &last, 0); + dp = nameiparent(path, &name, &namelen); if(dp == 0) return -1; + if(dirlookup(dp, name, namelen, 0, 0) >= 0){ + iput(dp); + return -1; + } - nip = mknod1(dp, last, T_DIR, 0, 0); + nip = dircreat(dp, name, namelen, T_DIR, 0, 0); if(nip == 0){ iput(dp); return -1; @@ -245,22 +256,17 @@ sys_chdir(void) if(argstr(0, &path) < 0) return -1; - if((ip = namei(path, NAMEI_LOOKUP, 0, 0, 0)) == 0) + if((ip = namei(path)) == 0) return -1; - if(ip == cp->cwd) { - iput(ip); - return 0; - } - if(ip->type != T_DIR) { iput(ip); return -1; } + iunlock(ip); idecref(cp->cwd); cp->cwd = ip; - iunlock(cp->cwd); return 0; } @@ -324,8 +330,7 @@ sys_exec(void) if(argstr(0, &path) < 0 || argint(1, (int*)&argv) < 0) return -1; - ip = namei(path, NAMEI_LOOKUP, 0, 0, 0); - if(ip == 0) + if((ip = namei(path)) == 0) return -1; if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) |