aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_syscall.c1
-rw-r--r--sys/kern/vfs_syscalls.c61
2 files changed, 62 insertions, 0 deletions
diff --git a/sys/kern/kern_syscall.c b/sys/kern/kern_syscall.c
index b36c6af..f4d9cb8 100644
--- a/sys/kern/kern_syscall.c
+++ b/sys/kern/kern_syscall.c
@@ -38,6 +38,7 @@ scret_t(*g_sctab[])(struct syscall_args *) = {
sys_open, /* SYS_open */
sys_read, /* SYS_read */
sys_close, /* SYS_close */
+ sys_stat, /* SYS_stat */
};
const size_t MAX_SYSCALLS = NELEM(g_sctab);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index f4c5c59..0ef3d42 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -28,10 +28,61 @@
*/
#include <sys/vfs.h>
+#include <sys/vnode.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/namei.h>
+#include <sys/stat.h>
+#include <sys/limits.h>
+#include <sys/errno.h>
#include <sys/types.h>
#include <sys/filedesc.h>
#include <string.h>
+static int
+vfs_dostat(const char *path, struct stat *sbuf)
+{
+ char pathbuf[PATH_MAX];
+ struct vattr *attr;
+ struct stat st;
+ struct vnode *vp;
+ struct vop_getattr_args gattr;
+ struct nameidata nd;
+ int error;
+
+ if (sbuf == NULL || path == NULL) {
+ return -EINVAL;
+ }
+
+ if ((copyinstr(path, pathbuf, sizeof(path))) < 0) {
+ return -EFAULT;
+ }
+
+ nd.path = path;
+ nd.flags = 0;
+
+ if ((error = namei(&nd)) != 0) {
+ return error;
+ }
+
+ vp = nd.vp;
+ gattr.vp = vp;
+ 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;
+ copyout(&st, sbuf, sizeof(*sbuf));
+ return 0;
+}
+
/*
* arg0: pathname
* arg1: oflags
@@ -64,3 +115,13 @@ sys_read(struct syscall_args *scargs)
return fd_read(scargs->arg0, (void *)scargs->arg1,
scargs->arg2);
}
+
+/*
+ * arg0: path
+ * arg1: buf
+ */
+scret_t
+sys_stat(struct syscall_args *scargs)
+{
+ return vfs_dostat((const char *)scargs->arg0, (void *)scargs->arg1);
+}