Skip to content
Snippets Groups Projects
Commit ef218524 authored by rsc's avatar rsc
Browse files

symlink implementation

parent e51ae8a2
No related branches found
No related tags found
No related merge requests found
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)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment