diff --git a/symlink.patch b/symlink.patch new file mode 100644 index 0000000..c7caf23 --- /dev/null +++ b/symlink.patch @@ -0,0 +1,151 @@ +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)