summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c44
1 files changed, 39 insertions, 5 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 990d722..0d51331 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -43,7 +43,7 @@ static int
vfs_dostat(const char *path, struct stat *sbuf)
{
char pathbuf[PATH_MAX];
- struct vattr *attr;
+ struct vattr attr;
struct stat st;
struct vnode *vp;
struct vop_getattr_args gattr;
@@ -58,7 +58,7 @@ vfs_dostat(const char *path, struct stat *sbuf)
return -EFAULT;
}
- nd.path = path;
+ nd.path = pathbuf;
nd.flags = 0;
if ((error = namei(&nd)) != 0) {
@@ -67,19 +67,42 @@ vfs_dostat(const char *path, struct stat *sbuf)
vp = nd.vp;
gattr.vp = vp;
+ gattr.res = &attr;
error = vfs_vop_getattr(vp, &gattr);
if (error != 0) {
return error;
}
- attr = gattr.res;
memset(&st, VNOVAL, sizeof(st));
/* Copy stat data to userspace statbuf */
- st.st_mode = attr->mode;
- st.st_size = attr->size;
+ st.st_mode = attr.mode;
+ st.st_size = attr.size;
copyout(&st, sbuf, sizeof(*sbuf));
+ vfs_release_vnode(vp);
+ return 0;
+}
+
+static int
+vfs_doaccess(const char *path)
+{
+ struct nameidata nd;
+ char pathbuf[PATH_MAX];
+ int error;
+
+ if ((copyinstr(path, pathbuf, sizeof(pathbuf))) < 0) {
+ return -EFAULT;
+ }
+
+ nd.path = pathbuf;
+ nd.flags = 0;
+
+ if ((error = namei(&nd)) != 0) {
+ return error;
+ }
+
+ vfs_release_vnode(nd.vp);
return 0;
}
@@ -149,3 +172,14 @@ sys_stat(struct syscall_args *scargs)
{
return vfs_dostat((const char *)scargs->arg0, (void *)scargs->arg1);
}
+
+/*
+ * Check if a file can be accessed.
+ *
+ * @arg0: path
+ */
+scret_t
+sys_access(struct syscall_args *scargs)
+{
+ return vfs_doaccess((const char *)scargs->arg0);
+}