Skip to content

Commit

Permalink
Add symlink syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
cw00h committed Jan 20, 2023
1 parent 9f1aa19 commit ec32e20
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 28 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ UPROGS=\
$U/_grind\
$U/_wc\
$U/_zombie\
$U/_symlinktest



Expand Down
11 changes: 6 additions & 5 deletions kernel/fcntl.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#define O_RDONLY 0x000
#define O_WRONLY 0x001
#define O_RDWR 0x002
#define O_CREATE 0x200
#define O_TRUNC 0x400
#define O_RDONLY 0x000
#define O_WRONLY 0x001
#define O_RDWR 0x002
#define O_CREATE 0x200
#define O_TRUNC 0x400
#define O_NOFOLLOW 0x008
1 change: 1 addition & 0 deletions kernel/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct inode {
short nlink;
uint size;
uint addrs[NDIRECT+2];
char path[128]; // MAXPATH = 128
};

// map major device number to device functions.
Expand Down
1 change: 1 addition & 0 deletions kernel/stat.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#define T_DIR 1 // Directory
#define T_FILE 2 // File
#define T_DEVICE 3 // Device
#define T_SYMLINK 4 // Symbolic Link

struct stat {
int dev; // File system's disk device
Expand Down
2 changes: 2 additions & 0 deletions kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern uint64 sys_unlink(void);
extern uint64 sys_wait(void);
extern uint64 sys_write(void);
extern uint64 sys_uptime(void);
extern uint64 sys_symlink(void);

static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork,
Expand All @@ -127,6 +128,7 @@ static uint64 (*syscalls[])(void) = {
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_symlink] sys_symlink,
};

void
Expand Down
43 changes: 22 additions & 21 deletions kernel/syscall.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
// System call numbers
#define SYS_fork 1
#define SYS_exit 2
#define SYS_wait 3
#define SYS_pipe 4
#define SYS_read 5
#define SYS_kill 6
#define SYS_exec 7
#define SYS_fstat 8
#define SYS_chdir 9
#define SYS_dup 10
#define SYS_getpid 11
#define SYS_sbrk 12
#define SYS_sleep 13
#define SYS_uptime 14
#define SYS_open 15
#define SYS_write 16
#define SYS_mknod 17
#define SYS_unlink 18
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_fork 1
#define SYS_exit 2
#define SYS_wait 3
#define SYS_pipe 4
#define SYS_read 5
#define SYS_kill 6
#define SYS_exec 7
#define SYS_fstat 8
#define SYS_chdir 9
#define SYS_dup 10
#define SYS_getpid 11
#define SYS_sbrk 12
#define SYS_sleep 13
#define SYS_uptime 14
#define SYS_open 15
#define SYS_write 16
#define SYS_mknod 17
#define SYS_unlink 18
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_symlink 22
41 changes: 40 additions & 1 deletion kernel/sysfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ create(char *path, short type, short major, short minor)
uint64
sys_open(void)
{
char path[MAXPATH];
char path[MAXPATH], symlink_path[MAXPATH];
int fd, omode;
struct file *f;
struct inode *ip;
Expand Down Expand Up @@ -322,6 +322,21 @@ sys_open(void)
return -1;
}

// Follow the symlinks
if((ip->type == T_SYMLINK) && ((omode & O_NOFOLLOW) == 0)) {
safestrcpy(symlink_path, ip->path, sizeof(ip->path));
while(ip->type == T_SYMLINK) {
iunlock(ip);
// If symlinks form a cycle, return -1
if(((ip = namei(symlink_path)) == 0) || (!strncmp(symlink_path, path, MAXPATH))) {
end_op();
return -1;
}
ilock(ip);
safestrcpy(symlink_path, ip->path, sizeof(ip->path));
}
}

if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
if(f)
fileclose(f);
Expand Down Expand Up @@ -484,3 +499,27 @@ sys_pipe(void)
}
return 0;
}

//int symlink(char *target, char *path);
uint64 sys_symlink(void) {
char target[MAXPATH], path[MAXPATH];
struct inode *ip;

if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
return -1;
begin_op();

// Create new symlink file
if((ip = create(path, T_SYMLINK, 0, 0)) == 0) {
end_op();
return -1;
}

safestrcpy(ip->path, target, MAXPATH);

iupdate(ip);
iunlockput(ip);

end_op();
return 0;
}
2 changes: 1 addition & 1 deletion user/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include "kernel/spinlock.h"
#include "kernel/sleeplock.h"
#include "kernel/fs.h"
#include "kernel/file.h"
#include "user/user.h"
#include "kernel/fcntl.h"
#include "kernel/file.h"

char *argv[] = { "sh", 0 };

Expand Down
1 change: 1 addition & 0 deletions user/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,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*);
Expand Down
1 change: 1 addition & 0 deletions user/usys.pl
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ sub entry {
entry("sbrk");
entry("sleep");
entry("uptime");
entry("symlink");

0 comments on commit ec32e20

Please sign in to comment.