提交 9e698c58 创建 作者: rsc's avatar rsc

Symbolic link implementation (in symlinks branch).

上级 f8ac6396
......@@ -98,11 +98,15 @@ _rm : rm.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o _rm rm.o $(ULIB)
$(OBJDUMP) -S _rm > rm.asm
_ln : ln.o $(ULIB)
$(LD) -N -e main -Ttext 0 -o _ln ln.o $(ULIB)
$(OBJDUMP) -S _ln > ln.asm
mkfs : mkfs.c fs.h
cc -o mkfs mkfs.c
fs.img : mkfs usertests _echo _cat README _init _sh _ls _mkdir _rm
./mkfs fs.img usertests _echo _cat README _init _sh _ls _mkdir _rm
fs.img : mkfs usertests _echo _cat README _init _sh _ls _mkdir _rm _ln
./mkfs fs.img usertests _echo _cat README _init _sh _ls _mkdir _rm _ln
-include *.d
......
......@@ -135,6 +135,7 @@ int readi(struct inode*, char*, uint, uint);
int writei(struct inode*, char*, uint, uint);
struct inode* mknod(char*, short, short, short);
struct inode* mknod1(struct inode*, char*, short, short, short);
int symlink(char*, char*);
int unlink(char*);
void iupdate(struct inode*);
int link(char*, char*);
......@@ -442,7 +442,7 @@ writei(struct inode *ip, char *addr, uint off, uint n)
if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
return -1;
return devsw[ip->major].write(ip->minor, addr, n);
} else if(ip->type == T_FILE || ip->type == T_DIR) {
} else if(ip->type == T_FILE || ip->type == T_DIR || ip->type == T_SYMLINK) {
struct buf *bp;
int r = 0;
int m;
......@@ -493,14 +493,16 @@ namei(char *path, int mode, uint *ret_off,
char **ret_last, struct inode **ret_ip)
{
struct inode *dp;
char link[64];
struct proc *p = curproc[cpu()];
char *cp = path, *cp1;
char *cp, *cp1;
uint off, dev;
struct buf *bp;
struct dirent *ep;
int i, l, atend;
int i, l, atend, n, nlink;
uint ninum;
again:
if(ret_off)
*ret_off = 0xffffffff;
if(ret_last)
......@@ -508,6 +510,7 @@ namei(char *path, int mode, uint *ret_off,
if(ret_ip)
*ret_ip = 0;
cp = path;
if(*cp == '/')
dp = iget(rootdev, 1);
else {
......@@ -516,13 +519,29 @@ namei(char *path, int mode, uint *ret_off,
ilock(dp);
}
nlink = 0;
for(;;){
while(*cp == '/')
cp++;
if(*cp == '\0'){
if(mode == NAMEI_LOOKUP)
if(mode == NAMEI_LOOKUP){
if(dp->type == T_SYMLINK){
if((n=readi(dp, link, 0, sizeof link - 1)) <= 0){
iput(dp);
return 0;
}
link[n] = 0;
path = link;
iput(dp);
if(++nlink > 10){
cprintf("symlink max depth: %s\n", path);
return 0;
}
goto again;
}
return dp;
}
if(mode == NAMEI_CREATE && ret_ip){
*ret_ip = dp;
return 0;
......@@ -698,12 +717,12 @@ unlink(char *cp)
// Create the path new as a link to the same inode as old.
int
link(char *name1, char *name2)
link(char *old, char *new)
{
struct inode *ip, *dp;
char *last;
if((ip = namei(name1, NAMEI_LOOKUP, 0, 0, 0)) == 0)
if((ip = namei(old, NAMEI_LOOKUP, 0, 0, 0)) == 0)
return -1;
if(ip->type == T_DIR){
iput(ip);
......@@ -712,7 +731,7 @@ link(char *name1, char *name2)
iunlock(ip);
if((dp = namei(name2, NAMEI_CREATE, 0, &last, 0)) == 0) {
if((dp = namei(new, NAMEI_CREATE, 0, &last, 0)) == 0) {
idecref(ip);
return -1;
}
......@@ -732,3 +751,30 @@ link(char *name1, char *name2)
return 0;
}
int
strlen(char *s)
{
int n = 0;
while(*s++ != 0)
n++;
return n;
}
// Create the path new as a symlink to old.
int
symlink(char *old, char *new)
{
struct inode *ip, *dp;
char *last;
if((dp = namei(new, NAMEI_CREATE, 0, &last, 0)) == 0)
return -1;
ip = mknod1(dp, last, T_SYMLINK, 0, 0);
iput(dp);
if(ip == 0)
return -1;
writei(ip, old, 0, strlen(old));
iput(ip);
return 0;
}
......@@ -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 // Symbolic link
// Inodes per block.
#define IPB (BSIZE / sizeof(struct dinode))
......
#include "types.h"
#include "user.h"
int
main(int argc, char *argv[])
{
int (*ln)(char*, char*);
ln = link;
if(argc > 1 && strcmp(argv[1], "-s") == 0){
ln = symlink;
argc--;
argv++;
}
if(argc != 3){
printf(2, "usage: ln [-s] old new (%d)\n", argc);
exit();
}
if(ln(argv[1], argv[2]) < 0){
printf(2, "%s failed\n", ln == symlink ? "symlink" : "link");
exit();
}
exit();
}
......@@ -2,6 +2,7 @@
#include "stat.h"
#include "user.h"
int
main(int argc, char *argv[])
{
int i;
......
......@@ -104,6 +104,7 @@ extern int sys_open(void);
extern int sys_pipe(void);
extern int sys_read(void);
extern int sys_sbrk(void);
extern int sys_symlink(void);
extern int sys_unlink(void);
extern int sys_wait(void);
extern int sys_write(void);
......@@ -158,6 +159,9 @@ syscall(void)
case SYS_link:
ret = sys_link();
break;
case SYS_symlink:
ret = sys_symlink();
break;
case SYS_mkdir:
ret = sys_mkdir();
break;
......
......@@ -18,3 +18,4 @@
#define SYS_dup 17
#define SYS_getpid 18
#define SYS_sbrk 19
#define SYS_symlink 20
......@@ -313,6 +313,16 @@ sys_link(void)
}
int
sys_symlink(void)
{
char *old, *new;
if(argstr(0, &old) < 0 || argstr(1, &new) < 0)
return -1;
return symlink(old, new);
}
int
sys_exec(void)
{
struct proc *cp = curproc[cpu()];
......
......@@ -11,8 +11,10 @@ int exec(char*, char**);
int open(char*, int);
int mknod(char*, short, short, short);
int unlink(char*);
struct stat;
int fstat(int fd, struct stat*);
int link(char*, char*);
int symlink(char*, char*);
int mkdir(char*);
int chdir(char*);
int dup(int);
......
......@@ -27,3 +27,4 @@ STUB(chdir)
STUB(dup)
STUB(getpid)
STUB(sbrk)
STUB(symlink)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论