summaryrefslogtreecommitdiff
path: root/sysfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysfile.c')
-rw-r--r--sysfile.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/sysfile.c b/sysfile.c
index e5d4eae..cd00494 100644
--- a/sysfile.c
+++ b/sysfile.c
@@ -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))