152 lines
3.7 KiB
Diff
152 lines
3.7 KiB
Diff
|
diff -r f8a4e40ab1d6 fs.c
|
||
|
--- a/fs.c Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/fs.c Thu Aug 30 14:29:02 2007 -0400
|
||
|
@@ -577,12 +577,18 @@ skipelem(char *path, char *name)
|
||
|
// If parent != 0, return the inode for the parent and copy the final
|
||
|
// path element into name, which must have room for DIRSIZ bytes.
|
||
|
static struct inode*
|
||
|
-_namei(char *path, int parent, char *name)
|
||
|
+_namei(struct inode *root, char *path, int parent, char *name, int depth)
|
||
|
{
|
||
|
struct inode *ip, *next;
|
||
|
+ char buf[100], tname[DIRSIZ];
|
||
|
+
|
||
|
+ if(depth > 5)
|
||
|
+ return 0;
|
||
|
|
||
|
if(*path == '/')
|
||
|
ip = iget(ROOTDEV, 1);
|
||
|
+ else if(root)
|
||
|
+ ip = idup(root);
|
||
|
else
|
||
|
ip = idup(cp->cwd);
|
||
|
|
||
|
@@ -598,10 +604,24 @@ _namei(char *path, int parent, char *nam
|
||
|
return ip;
|
||
|
}
|
||
|
if((next = dirlookup(ip, name, 0)) == 0){
|
||
|
+ cprintf("did not find %s\n", name);
|
||
|
iunlockput(ip);
|
||
|
return 0;
|
||
|
}
|
||
|
- iunlockput(ip);
|
||
|
+ iunlock(ip);
|
||
|
+ ilock(next);
|
||
|
+ if(next->type == T_SYMLINK){
|
||
|
+ if(next->size >= sizeof(buf) || readi(next, buf, 0, next->size) != next->size){
|
||
|
+ iunlockput(next);
|
||
|
+ iput(ip);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ buf[next->size] = 0;
|
||
|
+ iunlockput(next);
|
||
|
+ next = _namei(ip, buf, 0, tname, depth+1);
|
||
|
+ }else
|
||
|
+ iunlock(next);
|
||
|
+ iput(ip);
|
||
|
ip = next;
|
||
|
}
|
||
|
if(parent){
|
||
|
@@ -615,11 +635,11 @@ namei(char *path)
|
||
|
namei(char *path)
|
||
|
{
|
||
|
char name[DIRSIZ];
|
||
|
- return _namei(path, 0, name);
|
||
|
+ return _namei(0, path, 0, name, 0);
|
||
|
}
|
||
|
|
||
|
struct inode*
|
||
|
nameiparent(char *path, char *name)
|
||
|
{
|
||
|
- return _namei(path, 1, name);
|
||
|
-}
|
||
|
+ return _namei(0, path, 1, name, 0);
|
||
|
+}
|
||
|
diff -r f8a4e40ab1d6 fs.h
|
||
|
--- a/fs.h Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/fs.h Thu Aug 30 13:05:43 2007 -0400
|
||
|
@@ -33,6 +33,7 @@ struct dinode {
|
||
|
#define T_DIR 1 // Directory
|
||
|
#define T_FILE 2 // File
|
||
|
#define T_DEV 3 // Special device
|
||
|
+#define T_SYMLINK 4 // Symlink
|
||
|
|
||
|
// Inodes per block.
|
||
|
#define IPB (BSIZE / sizeof(struct dinode))
|
||
|
diff -r f8a4e40ab1d6 syscall.c
|
||
|
--- a/syscall.c Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/syscall.c Thu Aug 30 13:05:29 2007 -0400
|
||
|
@@ -96,6 +96,7 @@ extern int sys_unlink(void);
|
||
|
extern int sys_unlink(void);
|
||
|
extern int sys_wait(void);
|
||
|
extern int sys_write(void);
|
||
|
+extern int sys_symlink(void);
|
||
|
|
||
|
static int (*syscalls[])(void) = {
|
||
|
[SYS_chdir] sys_chdir,
|
||
|
@@ -118,6 +119,7 @@ static int (*syscalls[])(void) = {
|
||
|
[SYS_unlink] sys_unlink,
|
||
|
[SYS_wait] sys_wait,
|
||
|
[SYS_write] sys_write,
|
||
|
+[SYS_symlink] sys_symlink,
|
||
|
};
|
||
|
|
||
|
void
|
||
|
diff -r f8a4e40ab1d6 syscall.h
|
||
|
--- a/syscall.h Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/syscall.h Thu Aug 30 13:02:48 2007 -0400
|
||
|
@@ -19,3 +19,4 @@
|
||
|
#define SYS_getpid 18
|
||
|
#define SYS_sbrk 19
|
||
|
#define SYS_sleep 20
|
||
|
+#define SYS_symlink 21
|
||
|
diff -r f8a4e40ab1d6 sysfile.c
|
||
|
--- a/sysfile.c Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/sysfile.c Thu Aug 30 13:10:31 2007 -0400
|
||
|
@@ -257,6 +257,21 @@ create(char *path, int canexist, short t
|
||
|
}
|
||
|
|
||
|
int
|
||
|
+sys_symlink(void)
|
||
|
+{
|
||
|
+ char *old, *new;
|
||
|
+ struct inode *ip;
|
||
|
+
|
||
|
+ if(argstr(0, &old) < 0 || argstr(1, &new) < 0)
|
||
|
+ return -1;
|
||
|
+ if((ip = create(new, 0, T_SYMLINK, 0, 0)) == 0)
|
||
|
+ return -1;
|
||
|
+ writei(ip, old, 0, strlen(old));
|
||
|
+ iunlockput(ip);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int
|
||
|
sys_open(void)
|
||
|
{
|
||
|
char *path;
|
||
|
@@ -393,3 +408,4 @@ sys_pipe(void)
|
||
|
fd[1] = fd1;
|
||
|
return 0;
|
||
|
}
|
||
|
+
|
||
|
diff -r f8a4e40ab1d6 user.h
|
||
|
--- a/user.h Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/user.h Thu Aug 30 13:02:34 2007 -0400
|
||
|
@@ -21,6 +21,7 @@ int getpid();
|
||
|
int getpid();
|
||
|
char* sbrk(int);
|
||
|
int sleep(int);
|
||
|
+int symlink(int);
|
||
|
|
||
|
// ulib.c
|
||
|
int stat(char*, struct stat*);
|
||
|
diff -r f8a4e40ab1d6 usys.S
|
||
|
--- a/usys.S Thu Aug 30 14:32:06 2007 -0400
|
||
|
+++ b/usys.S Thu Aug 30 13:05:54 2007 -0400
|
||
|
@@ -28,3 +28,4 @@ STUB(getpid)
|
||
|
STUB(getpid)
|
||
|
STUB(sbrk)
|
||
|
STUB(sleep)
|
||
|
+STUB(symlink)
|