symlink implementation

This commit is contained in:
rsc 2007-08-30 18:36:38 +00:00
parent e51ae8a272
commit ef2185247d

151
symlink.patch Normal file
View file

@ -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)