make grade 100/100

This commit is contained in:
ridethepig 2023-02-05 17:35:55 +00:00
parent f187a07854
commit 4368fbf44c
10 changed files with 68 additions and 4 deletions

View File

@ -188,6 +188,7 @@ UPROGS=\
$U/_grind\ $U/_grind\
$U/_wc\ $U/_wc\
$U/_zombie\ $U/_zombie\
$U/_symlinktest\

View File

@ -3,3 +3,4 @@
#define O_RDWR 0x002 #define O_RDWR 0x002
#define O_CREATE 0x200 #define O_CREATE 0x200
#define O_TRUNC 0x400 #define O_TRUNC 0x400
#define O_NOFOLLOW 0x800

View File

@ -1,7 +1,7 @@
#define T_DIR 1 // Directory #define T_DIR 1 // Directory
#define T_FILE 2 // File #define T_FILE 2 // File
#define T_DEVICE 3 // Device #define T_DEVICE 3 // Device
#define T_SYMLINK 4
struct stat { struct stat {
int dev; // File system's disk device int dev; // File system's disk device
uint ino; // Inode number uint ino; // Inode number

View File

@ -101,6 +101,7 @@ extern uint64 sys_unlink(void);
extern uint64 sys_link(void); extern uint64 sys_link(void);
extern uint64 sys_mkdir(void); extern uint64 sys_mkdir(void);
extern uint64 sys_close(void); extern uint64 sys_close(void);
extern uint64 sys_symlink(void);
// An array mapping syscall numbers from syscall.h // An array mapping syscall numbers from syscall.h
// to the function that handles the system call. // to the function that handles the system call.
@ -126,6 +127,7 @@ static uint64 (*syscalls[])(void) = {
[SYS_link] sys_link, [SYS_link] sys_link,
[SYS_mkdir] sys_mkdir, [SYS_mkdir] sys_mkdir,
[SYS_close] sys_close, [SYS_close] sys_close,
[SYS_symlink] sys_symlink,
}; };
void void

View File

@ -20,3 +20,4 @@
#define SYS_link 19 #define SYS_link 19
#define SYS_mkdir 20 #define SYS_mkdir 20
#define SYS_close 21 #define SYS_close 21
#define SYS_symlink 22

View File

@ -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)){ if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){
iunlockput(ip); iunlockput(ip);
end_op(); end_op();
@ -503,3 +533,32 @@ sys_pipe(void)
} }
return 0; 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;
}

1
time.txt Normal file
View File

@ -0,0 +1 @@
7

View File

@ -32,11 +32,8 @@ main()
printf("bigfile: file is too small\n"); printf("bigfile: file is too small\n");
exit(-1); exit(-1);
} }
printf("bef close fd\n");
close(fd); close(fd);
printf("aft close fd\n");
fd = open("big.file", O_RDONLY); fd = open("big.file", O_RDONLY);
printf("aft open\n");
if(fd < 0){ if(fd < 0){
printf("bigfile: cannot re-open big.file for reading\n"); printf("bigfile: cannot re-open big.file for reading\n");
exit(-1); exit(-1);

View File

@ -22,6 +22,7 @@ int getpid(void);
char* sbrk(int); char* sbrk(int);
int sleep(int); int sleep(int);
int uptime(void); int uptime(void);
int symlink(char* target, char* path);
// ulib.c // ulib.c
int stat(const char*, struct stat*); int stat(const char*, struct stat*);

View File

@ -36,3 +36,4 @@ entry("getpid");
entry("sbrk"); entry("sbrk");
entry("sleep"); entry("sleep");
entry("uptime"); entry("uptime");
entry("symlink");