* same with xv6
[mascara-docs.git] / i386 / MIT / src.xv6 / symlink.patch
blobc7caf2323a5ff5cf0159946977be6d486686ba2a
1 diff -r f8a4e40ab1d6 fs.c
2 --- a/fs.c Thu Aug 30 14:32:06 2007 -0400
3 +++ b/fs.c Thu Aug 30 14:29:02 2007 -0400
4 @@ -577,12 +577,18 @@ skipelem(char *path, char *name)
5 // If parent != 0, return the inode for the parent and copy the final
6 // path element into name, which must have room for DIRSIZ bytes.
7 static struct inode*
8 -_namei(char *path, int parent, char *name)
9 +_namei(struct inode *root, char *path, int parent, char *name, int depth)
11 struct inode *ip, *next;
12 + char buf[100], tname[DIRSIZ];
14 + if(depth > 5)
15 + return 0;
17 if(*path == '/')
18 ip = iget(ROOTDEV, 1);
19 + else if(root)
20 + ip = idup(root);
21 else
22 ip = idup(cp->cwd);
24 @@ -598,10 +604,24 @@ _namei(char *path, int parent, char *nam
25 return ip;
27 if((next = dirlookup(ip, name, 0)) == 0){
28 + cprintf("did not find %s\n", name);
29 iunlockput(ip);
30 return 0;
32 - iunlockput(ip);
33 + iunlock(ip);
34 + ilock(next);
35 + if(next->type == T_SYMLINK){
36 + if(next->size >= sizeof(buf) || readi(next, buf, 0, next->size) != next->size){
37 + iunlockput(next);
38 + iput(ip);
39 + return 0;
40 + }
41 + buf[next->size] = 0;
42 + iunlockput(next);
43 + next = _namei(ip, buf, 0, tname, depth+1);
44 + }else
45 + iunlock(next);
46 + iput(ip);
47 ip = next;
49 if(parent){
50 @@ -615,11 +635,11 @@ namei(char *path)
51 namei(char *path)
53 char name[DIRSIZ];
54 - return _namei(path, 0, name);
55 + return _namei(0, path, 0, name, 0);
58 struct inode*
59 nameiparent(char *path, char *name)
61 - return _namei(path, 1, name);
63 + return _namei(0, path, 1, name, 0);
65 diff -r f8a4e40ab1d6 fs.h
66 --- a/fs.h Thu Aug 30 14:32:06 2007 -0400
67 +++ b/fs.h Thu Aug 30 13:05:43 2007 -0400
68 @@ -33,6 +33,7 @@ struct dinode {
69 #define T_DIR 1 // Directory
70 #define T_FILE 2 // File
71 #define T_DEV 3 // Special device
72 +#define T_SYMLINK 4 // Symlink
74 // Inodes per block.
75 #define IPB (BSIZE / sizeof(struct dinode))
76 diff -r f8a4e40ab1d6 syscall.c
77 --- a/syscall.c Thu Aug 30 14:32:06 2007 -0400
78 +++ b/syscall.c Thu Aug 30 13:05:29 2007 -0400
79 @@ -96,6 +96,7 @@ extern int sys_unlink(void);
80 extern int sys_unlink(void);
81 extern int sys_wait(void);
82 extern int sys_write(void);
83 +extern int sys_symlink(void);
85 static int (*syscalls[])(void) = {
86 [SYS_chdir] sys_chdir,
87 @@ -118,6 +119,7 @@ static int (*syscalls[])(void) = {
88 [SYS_unlink] sys_unlink,
89 [SYS_wait] sys_wait,
90 [SYS_write] sys_write,
91 +[SYS_symlink] sys_symlink,
94 void
95 diff -r f8a4e40ab1d6 syscall.h
96 --- a/syscall.h Thu Aug 30 14:32:06 2007 -0400
97 +++ b/syscall.h Thu Aug 30 13:02:48 2007 -0400
98 @@ -19,3 +19,4 @@
99 #define SYS_getpid 18
100 #define SYS_sbrk 19
101 #define SYS_sleep 20
102 +#define SYS_symlink 21
103 diff -r f8a4e40ab1d6 sysfile.c
104 --- a/sysfile.c Thu Aug 30 14:32:06 2007 -0400
105 +++ b/sysfile.c Thu Aug 30 13:10:31 2007 -0400
106 @@ -257,6 +257,21 @@ create(char *path, int canexist, short t
110 +sys_symlink(void)
112 + char *old, *new;
113 + struct inode *ip;
115 + if(argstr(0, &old) < 0 || argstr(1, &new) < 0)
116 + return -1;
117 + if((ip = create(new, 0, T_SYMLINK, 0, 0)) == 0)
118 + return -1;
119 + writei(ip, old, 0, strlen(old));
120 + iunlockput(ip);
121 + return 0;
124 +int
125 sys_open(void)
127 char *path;
128 @@ -393,3 +408,4 @@ sys_pipe(void)
129 fd[1] = fd1;
130 return 0;
133 diff -r f8a4e40ab1d6 user.h
134 --- a/user.h Thu Aug 30 14:32:06 2007 -0400
135 +++ b/user.h Thu Aug 30 13:02:34 2007 -0400
136 @@ -21,6 +21,7 @@ int getpid();
137 int getpid();
138 char* sbrk(int);
139 int sleep(int);
140 +int symlink(int);
142 // ulib.c
143 int stat(char*, struct stat*);
144 diff -r f8a4e40ab1d6 usys.S
145 --- a/usys.S Thu Aug 30 14:32:06 2007 -0400
146 +++ b/usys.S Thu Aug 30 13:05:54 2007 -0400
147 @@ -28,3 +28,4 @@ STUB(getpid)
148 STUB(getpid)
149 STUB(sbrk)
150 STUB(sleep)
151 +STUB(symlink)