make grade 100/100
This commit is contained in:
parent
f187a07854
commit
4368fbf44c
@ -3,3 +3,4 @@
|
||||
#define O_RDWR 0x002
|
||||
#define O_CREATE 0x200
|
||||
#define O_TRUNC 0x400
|
||||
#define O_NOFOLLOW 0x800
|
||||
@ -1,7 +1,7 @@
|
||||
#define T_DIR 1 // Directory
|
||||
#define T_FILE 2 // File
|
||||
#define T_DEVICE 3 // Device
|
||||
|
||||
#define T_SYMLINK 4
|
||||
struct stat {
|
||||
int dev; // File system's disk device
|
||||
uint ino; // Inode number
|
||||
|
||||
@ -101,6 +101,7 @@ extern uint64 sys_unlink(void);
|
||||
extern uint64 sys_link(void);
|
||||
extern uint64 sys_mkdir(void);
|
||||
extern uint64 sys_close(void);
|
||||
extern uint64 sys_symlink(void);
|
||||
|
||||
// An array mapping syscall numbers from syscall.h
|
||||
// to the function that handles the system call.
|
||||
@ -126,6 +127,7 @@ static uint64 (*syscalls[])(void) = {
|
||||
[SYS_link] sys_link,
|
||||
[SYS_mkdir] sys_mkdir,
|
||||
[SYS_close] sys_close,
|
||||
[SYS_symlink] sys_symlink,
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
@ -20,3 +20,4 @@
|
||||
#define SYS_link 19
|
||||
#define SYS_mkdir 20
|
||||
#define SYS_close 21
|
||||
#define SYS_symlink 22
|
||||
@ -335,6 +335,36 @@ sys_open(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (ip->type == T_SYMLINK && !(omode & O_NOFOLLOW)) {
|
||||
int symlink_step = 0;
|
||||
while (ip->type == T_SYMLINK) {
|
||||
if (symlink_step++ > 10) {
|
||||
// printf("\x1b[031mFailed\x1b[0m due to deep symlink\n");
|
||||
iunlockput(ip); // on error, put inode 'cause only success open need to use the file after the syscall
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
int len_target = readi(ip, 0, (uint64)path, 0, MAXPATH);
|
||||
iunlockput(ip); // no more need to use this inode
|
||||
if (len_target == 0) {
|
||||
printf("\x1b[031mFailed\x1b[0m to read symlink %s\n", path);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
// get target's inode
|
||||
if((ip = namei(path)) == 0){
|
||||
// printf("\x1b[031mFailed\x1b[0m open symlink target %s\n", path);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
ilock(ip);
|
||||
if(ip->type == T_DIR && omode != O_RDONLY){
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
@ -503,3 +533,32 @@ sys_pipe(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64
|
||||
sys_symlink(void)
|
||||
{
|
||||
char target[MAXPATH], path[MAXPATH];
|
||||
int len_target, len_path;
|
||||
struct inode* ip;
|
||||
if ((len_target = argstr(0, target, MAXPATH)) < 0)
|
||||
return -1;
|
||||
if ((len_path = argstr(1, path, MAXPATH)) < 0)
|
||||
return -1;
|
||||
// printf("\x1b[033msys_symlink\x1b[0m %s -> %s\n", path, target);
|
||||
begin_op();
|
||||
ip = create(path, T_SYMLINK, 0, 0);
|
||||
if (ip == 0) {
|
||||
end_op();
|
||||
// printf("\x1b[031mFailed\x1b[0m to create path %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
if (writei(ip, 0, (uint64)target, 0, len_target) != len_target) {
|
||||
iunlockput(ip);
|
||||
end_op();
|
||||
printf("\x1b[031mFailed\x1b[0m to write symlink target %s to %s\n", target, path);
|
||||
return -1;
|
||||
}
|
||||
iunlockput(ip); // no need to keep this inode ref, if not put, in-RAM inode pool will run out
|
||||
end_op();
|
||||
return 0;
|
||||
}
|
||||
@ -32,11 +32,8 @@ main()
|
||||
printf("bigfile: file is too small\n");
|
||||
exit(-1);
|
||||
}
|
||||
printf("bef close fd\n");
|
||||
close(fd);
|
||||
printf("aft close fd\n");
|
||||
fd = open("big.file", O_RDONLY);
|
||||
printf("aft open\n");
|
||||
if(fd < 0){
|
||||
printf("bigfile: cannot re-open big.file for reading\n");
|
||||
exit(-1);
|
||||
|
||||
@ -22,6 +22,7 @@ int getpid(void);
|
||||
char* sbrk(int);
|
||||
int sleep(int);
|
||||
int uptime(void);
|
||||
int symlink(char* target, char* path);
|
||||
|
||||
// ulib.c
|
||||
int stat(const char*, struct stat*);
|
||||
|
||||
@ -36,3 +36,4 @@ entry("getpid");
|
||||
entry("sbrk");
|
||||
entry("sleep");
|
||||
entry("uptime");
|
||||
entry("symlink");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user