summaryrefslogtreecommitdiff
path: root/kernel/sysfile.c
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2024-02-19 14:10:32 +0800
committerMole Shang <[email protected]>2024-02-19 14:36:21 +0800
commitd86118fc80267649b4791c8c0c72ebd60edf1ef2 (patch)
treeb792b617b4df80a5803a9c1164d0e3fdfe9cfe31 /kernel/sysfile.c
parentb20ef9d0210fd7d9403acde1857eed1b9880c0b2 (diff)
parent0cf897cbe05fd8485162619db4244f4159d0eb52 (diff)
downloadxv6-labs-d86118fc80267649b4791c8c0c72ebd60edf1ef2.tar.gz
xv6-labs-d86118fc80267649b4791c8c0c72ebd60edf1ef2.tar.bz2
xv6-labs-d86118fc80267649b4791c8c0c72ebd60edf1ef2.zip
Merge branch 'fs' into mmap
Conflicts: .gitignore Makefile conf/lab.mk kernel/defs.h user/user.h
Diffstat (limited to 'kernel/sysfile.c')
-rw-r--r--kernel/sysfile.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/kernel/sysfile.c b/kernel/sysfile.c
index 16b668c..9c12d44 100644
--- a/kernel/sysfile.c
+++ b/kernel/sysfile.c
@@ -16,6 +16,15 @@
#include "file.h"
#include "fcntl.h"
+// symlink
+#define SYMLINK_MAXFOLLOW 254
+
+struct symlink {
+ uint len;
+ char target[MAXPATH];
+};
+
+
// Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file.
static int
@@ -258,6 +267,8 @@ create(char *path, short type, short major, short minor)
ilock(ip);
if(type == T_FILE && (ip->type == T_FILE || ip->type == T_DEVICE))
return ip;
+ if(type == T_SYMLINK)
+ return ip;
iunlockput(ip);
return 0;
}
@@ -301,6 +312,37 @@ create(char *path, short type, short major, short minor)
return 0;
}
+// create a symbolic link to path
+uint64
+sys_symlink(void)
+{
+ char path[MAXPATH];
+ struct inode *ip;
+ struct symlink sl = {0};
+
+ if(argstr(0, sl.target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
+ return -1;
+
+ sl.len = strlen(sl.target);
+
+ begin_op();
+ if((ip = create(path, T_SYMLINK, 0, 0)) == 0){
+ end_op();
+ return -1;
+ }
+
+ if(writei(ip, 0, (uint64)&sl.len, 0, sizeof(sl.len)) != sizeof(sl.len) || writei(ip, 0, (uint64)sl.target, sizeof(sl.len), sl.len+1) != sl.len+1){
+ iunlockput(ip);
+ end_op();
+ return -1;
+ }
+
+ iupdate(ip);
+ iunlockput(ip);
+ end_op();
+ return 0;
+}
+
uint64
sys_open(void)
{
@@ -341,6 +383,35 @@ sys_open(void)
return -1;
}
+ if(ip->type == T_SYMLINK && !(omode & O_NOFOLLOW)){
+ int len = 0;
+ uchar i;
+ for(i = 0; i < SYMLINK_MAXFOLLOW; i++){
+ if(readi(ip, 0, (uint64)&len, 0, sizeof(len)) != sizeof(len) ||
+ readi(ip, 0, (uint64)path, sizeof(len), len+1) != len+1) {
+ iunlockput(ip);
+ end_op();
+ return -1;
+ }
+ iunlockput(ip);
+
+ if((ip = namei(path)) == 0) {
+ end_op();
+ return -1;
+ }
+
+ ilock(ip);
+ if(ip->type != T_SYMLINK)
+ break;
+ }
+
+ if (i >= SYMLINK_MAXFOLLOW) {
+ iunlockput(ip);
+ end_op();
+ return -1;
+ }
+ }
+
if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
if(f)
fileclose(f);
@@ -503,3 +574,29 @@ sys_pipe(void)
}
return 0;
}
+
+
+#ifdef LAB_NET
+int
+sys_connect(void)
+{
+ struct file *f;
+ int fd;
+ uint32 raddr;
+ uint32 rport;
+ uint32 lport;
+
+ argint(0, (int*)&raddr);
+ argint(1, (int*)&lport);
+ argint(2, (int*)&rport);
+
+ if(sockalloc(&f, raddr, lport, rport) < 0)
+ return -1;
+ if((fd=fdalloc(f)) < 0){
+ fileclose(f);
+ return -1;
+ }
+
+ return fd;
+}
+#endif