diff --git a/arch/amd64/syscall.c b/arch/amd64/syscall.c index b4d807e..29e3fc6 100644 --- a/arch/amd64/syscall.c +++ b/arch/amd64/syscall.c @@ -45,14 +45,18 @@ void *syscall_table[256] = { //SUPERSEDED BY: [SYSCALL_NR_OPENAT] = sys_openat, [SYSCALL_NR_CLOSE] = sys_close, - [SYSCALL_NR_STAT] = sys_stat, - [SYSCALL_NR_FSTAT] = sys_fstat, - [SYSCALL_NR_LSTAT] = sys_lstat, + //[SYSCALL_NR_STAT] = sys_stat, + //[SYSCALL_NR_FSTAT] = sys_fstat, + //[SYSCALL_NR_LSTAT] = sys_lstat, + //SUPERSEDED BY: + [SYSCALL_NR_FSTATAT] = sys_fstatat, [SYSCALL_NR_LSEEK] = sys_lseek, [SYSCALL_NR_MMAP] = sys_mmap, [SYSCALL_NR_MUNMAP] = sys_munmap, [SYSCALL_NR_IOCTL] = sys_ioctl, - [SYSCALL_NR_ACCESS] = sys_access, + //[SYSCALL_NR_ACCESS] = sys_access, + //SUPERSEDED BY: + [SYSCALL_NR_FACCESSAT] = sys_faccessat, [SYSCALL_NR_PIPE] = sys_pipe, [SYSCALL_NR_SELECT] = sys_select, [SYSCALL_NR_DUP] = sys_dup, diff --git a/fs/vfs_ops.c b/fs/vfs_ops.c index 7a3738a..3f967a8 100644 --- a/fs/vfs_ops.c +++ b/fs/vfs_ops.c @@ -508,76 +508,52 @@ void vfs_close(struct vfs_ioctx *ctx, struct ofile *fd) { } } -int vfs_access(struct vfs_ioctx *ctx, const char *path, int accmode) { - struct vnode *node; - int res; - +int vfs_faccessat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, int mode, int flags) { _assert(ctx); _assert(path); - if ((res = vfs_find(ctx, ctx->cwd_vnode, path, 0, &node)) != 0) { + struct vnode *node; + int res; + + if ((res = vfs_find(ctx, at, path, flags & AT_SYMLINK_NOFOLLOW, &node)) != 0) { return res; } - if (accmode == F_OK) { - // Just test that file exists + if (mode == F_OK) { return 0; } - return vfs_access_node(ctx, node, accmode); + return vfs_access_node(ctx, node, mode); } -int vfs_fstat(struct vfs_ioctx *ctx, struct ofile *fd, struct stat *st) { - int res; - - _assert(ctx); - _assert(fd); - _assert(!(fd->flags & OF_SOCKET)); - _assert(st); - - struct vnode *node = fd->file.vnode; - - _assert(node); - - if (!node->op || !node->op->stat) { - return -EINVAL; - } - - return node->op->stat(node, st); -} - -int vfs_lstat(struct vfs_ioctx *ctx, const char *path, struct stat *st) { +int vfs_fstatat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, struct stat *st, int flags) { struct vnode *node; int res; _assert(ctx); - _assert(path); _assert(st); - if ((res = vfs_find(ctx, ctx->cwd_vnode, path, 1, &node)) != 0) { - return res; - } - - if (!node->op || !node->op->stat) { - return -EINVAL; - } - - return node->op->stat(node, st); -} - -int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st) { - struct vnode *node; - int res; - - _assert(ctx); - _assert(path); - _assert(st); - - if ((res = vfs_find(ctx, ctx->cwd_vnode, path, 0, &node)) != 0) { - return res; + if (!at) { + at = ctx->cwd_vnode; + } + kdebug("FSTATAT %s, %s\n", (at ? at->name : "NULL"), path); + + if (flags & AT_EMPTY_PATH) { + node = at; + + if (!node) { + panic("TODO: implement this (use root)\n"); + } + } else { + _assert(path); + + if ((res = vfs_find(ctx, at, path, flags & AT_SYMLINK_NOFOLLOW, &node)) != 0) { + return res; + } } if (!node->op || !node->op->stat) { + kerror("stat() not implemented for node\n"); return -EINVAL; } diff --git a/include/fs/vfs.h b/include/fs/vfs.h index 9b32551..17b2b4c 100644 --- a/include/fs/vfs.h +++ b/include/fs/vfs.h @@ -56,10 +56,12 @@ int vfs_chmod(struct vfs_ioctx *ctx, const char *path, mode_t mode); int vfs_chown(struct vfs_ioctx *ctx, const char *path, uid_t uid, gid_t gid); int vfs_ioctl(struct vfs_ioctx *ctx, struct ofile *fd, unsigned int cmd, void *arg); -int vfs_access(struct vfs_ioctx *ctx, const char *path, int accmode); -int vfs_fstat(struct vfs_ioctx *ctx, struct ofile *fd, struct stat *st); -int vfs_lstat(struct vfs_ioctx *ctx, const char *path, struct stat *st); -int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st); +//int vfs_access(struct vfs_ioctx *ctx, const char *path, int accmode); +int vfs_faccessat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, int accmode, int flags); +//int vfs_fstat(struct vfs_ioctx *ctx, struct ofile *fd, struct stat *st); +//int vfs_lstat(struct vfs_ioctx *ctx, const char *path, struct stat *st); +//int vfs_stat(struct vfs_ioctx *ctx, const char *path, struct stat *st); +int vfs_fstatat(struct vfs_ioctx *ctx, struct vnode *at, const char *path, struct stat *st, int flags); int vfs_access_check(struct vfs_ioctx *ctx, int desm, mode_t mode, uid_t uid, gid_t gid); int vfs_access_node(struct vfs_ioctx *ctx, struct vnode *vn, int mode); diff --git a/include/sys/sys_file.h b/include/sys/sys_file.h index 1a4554f..f324133 100644 --- a/include/sys/sys_file.h +++ b/include/sys/sys_file.h @@ -17,10 +17,14 @@ int sys_getcwd(char *buf, size_t lim); // REMOVED: int sys_open(const char *filename, int flags, int mode); int sys_openat(int dfd, const char *filename, int flags, int mode); void sys_close(int fd); -int sys_stat(const char *filename, struct stat *st); -int sys_fstat(int fd, struct stat *st); -int sys_lstat(const char *filename, struct stat *st); -int sys_access(const char *path, int mode); +//int sys_stat(const char *filename, struct stat *st); +//int sys_fstat(int fd, struct stat *st); +//int sys_lstat(const char *filename, struct stat *st); +//SUPERSEDED BY: +int sys_fstatat(int dfd, const char *pathname, struct stat *st, int flags); +//int sys_access(const char *path, int mode); +//SUPERSEDED BY: +int sys_faccessat(int dfd, const char *pathname, int mode, int flags); int sys_pipe(int *filedes); int sys_select(int n, fd_set *inp, fd_set *outp, fd_set *excp, struct timeval *tv); int sys_dup(int from); diff --git a/include/sys/types.h b/include/sys/types.h index 4e90b57..d8b0064 100644 --- a/include/sys/types.h +++ b/include/sys/types.h @@ -1,11 +1,10 @@ #pragma once -#include +#include "user/types.h" #ifndef NULL #define NULL ((void *) 0) #endif -#if defined(__KERNEL__) struct tm { int tm_sec; int tm_min; @@ -17,18 +16,3 @@ struct tm { int tm_yday; int tm_isdst; }; -typedef uint32_t uid_t; -typedef uint32_t gid_t; -#endif - -typedef uint64_t uintptr_t; -typedef int64_t intptr_t; - -typedef uintptr_t size_t; -typedef intptr_t ssize_t; - -typedef int64_t off_t; - -typedef uint32_t mode_t; - -typedef int32_t pid_t; diff --git a/include/user/fcntl.h b/include/user/fcntl.h index 6e6512b..f0ae7e3 100644 --- a/include/user/fcntl.h +++ b/include/user/fcntl.h @@ -9,7 +9,9 @@ #define X_OK 1 #define F_OK 0 -#define AT_FDCWD (-100) +#define AT_FDCWD (-100) +#define AT_SYMLINK_NOFOLLOW (1 << 0) +#define AT_EMPTY_PATH (1 << 1) // O_EXEC is a special one for opening a node for // execution diff --git a/include/user/syscall.h b/include/user/syscall.h index 3ea12b7..1835124 100644 --- a/include/user/syscall.h +++ b/include/user/syscall.h @@ -6,15 +6,19 @@ // SUPERSEDED BY: #define SYSCALL_NR_OPENAT 2 #define SYSCALL_NR_CLOSE 3 -#define SYSCALL_NR_STAT 4 -#define SYSCALL_NR_FSTAT 5 -#define SYSCALL_NR_LSTAT 6 +//#define SYSCALL_NR_STAT 4 +//#define SYSCALL_NR_FSTAT 5 +//#define SYSCALL_NR_LSTAT 6 +//SUPERSEDED BY: +#define SYSCALL_NR_FSTATAT 4 #define SYSCALL_NR_LSEEK 8 #define SYSCALL_NR_MMAP 9 #define SYSCALL_NR_MUNMAP 11 #define SYSCALL_NRX_SBRK 12 #define SYSCALL_NR_IOCTL 16 -#define SYSCALL_NR_ACCESS 21 +//#define SYSCALL_NR_ACCESS 21 +//SUPERSEDED BY: +#define SYSCALL_NR_FACCESSAT 21 #define SYSCALL_NR_PIPE 22 #define SYSCALL_NR_SELECT 23 #define SYSCALL_NR_DUP 32 diff --git a/include/user/types.h b/include/user/types.h index 04185fa..e6ea7df 100644 --- a/include/user/types.h +++ b/include/user/types.h @@ -1,24 +1,21 @@ #pragma once +#if defined(__KERNEL__) +#include +#else #include - -#if !defined(NULL) -#define NULL ((void *) 0) #endif typedef int sig_atomic_t; - -typedef int32_t pid_t; +typedef int pid_t; typedef int64_t ssize_t; typedef uint64_t size_t; + typedef int64_t off_t; +typedef int mode_t; -typedef uint32_t mode_t; - -typedef uint16_t uid_t; -typedef uint16_t gid_t; +typedef uint32_t uid_t; +typedef uint32_t gid_t; typedef uint64_t clock_t; typedef uint64_t useconds_t; - -typedef int32_t pid_t; diff --git a/sys/execve.c b/sys/execve.c index 0ad4bd9..76b109e 100644 --- a/sys/execve.c +++ b/sys/execve.c @@ -133,7 +133,7 @@ int sys_execve(const char *path, const char **argv, const char **envp) { int res; int was_kernel = 0; - if ((res = vfs_stat(&proc->ioctx, path, &st)) != 0) { + if ((res = vfs_fstatat(&proc->ioctx, NULL, path, &st, 0)) != 0) { kerror("execve(%s): %s\n", path, kstrerror(res)); return res; } diff --git a/sys/mod.c b/sys/mod.c index 862502f..cdc15c4 100644 --- a/sys/mod.c +++ b/sys/mod.c @@ -191,7 +191,7 @@ static int elf_mod_load(struct module *mod, struct vfs_ioctx *ctx, struct ofile int res = 0; // Load the whole module image into memory - if ((res = vfs_fstat(ctx, fd, &st)) != 0) { + if ((res = vfs_fstatat(ctx, fd->file.vnode, NULL, &st, AT_EMPTY_PATH)) != 0) { return res; } diff --git a/sys/sys_file.c b/sys/sys_file.c index f31153d..104a55a 100644 --- a/sys/sys_file.c +++ b/sys/sys_file.c @@ -26,6 +26,23 @@ static inline struct vfs_ioctx *get_ioctx(void) { return &thread_self->proc->ioctx; } +static inline int get_at_vnode(int dfd, struct vnode **at, int flags) { + if (dfd == AT_FDCWD) { + *at = get_ioctx()->cwd_vnode; + return 0; + } else { + struct ofile *fd = get_fd(dfd); + if (!fd) { + return -EBADF; + } + if (!(flags & AT_EMPTY_PATH) && !(fd->flags & OF_DIRECTORY)) { + return -ENOTDIR; + } + *at = fd->file.vnode; + return 0; + } +} + ssize_t sys_read(int fd, void *data, size_t lim) { userptr_check(data); struct ofile *of; @@ -121,14 +138,8 @@ int sys_openat(int dfd, const char *filename, int flags, int mode) { int fd = -1; int res; - if (dfd == AT_FDCWD) { - at = get_ioctx()->cwd_vnode; - } else { - struct ofile *of = get_fd(dfd); - if (of == NULL || !(of->flags & OF_DIRECTORY)) { - return -EBADF; - } - at = of->file.vnode; + if ((res = get_at_vnode(dfd, &at, 0)) != 0) { + return res; } // XXX: This should be atomic @@ -170,38 +181,33 @@ void sys_close(int fd) { proc->fds[fd] = NULL; } -int sys_stat(const char *filename, struct stat *st) { - userptr_check(filename); - _assert(filename); - _assert(st); +int sys_fstatat(int dfd, const char *pathname, struct stat *st, int flags) { + if (!(flags & AT_EMPTY_PATH)) { + userptr_check(pathname); + } + userptr_check(st); - return vfs_stat(get_ioctx(), filename, st); -} + struct vnode *at; + int res; -int sys_lstat(const char *filename, struct stat *st) { - userptr_check(filename); - _assert(filename); - _assert(st); - - return vfs_lstat(get_ioctx(), filename, st); -} - -int sys_fstat(int fd, struct stat *st) { - struct ofile *of; - _assert(st); - - if (!(of = get_fd(fd))) { - return -EBADF; + if ((res = get_at_vnode(dfd, &at, flags)) != 0) { + return res; } - return vfs_fstat(get_ioctx(), of, st); + return vfs_fstatat(get_ioctx(), at, pathname, st, flags); } -int sys_access(const char *path, int mode) { - userptr_check(path); - _assert(path); +int sys_faccessat(int dfd, const char *pathname, int mode, int flags) { + userptr_check(pathname); - return vfs_access(get_ioctx(), path, mode); + struct vnode *at; + int res; + + if ((res = get_at_vnode(dfd, &at, flags)) != 0) { + return res; + } + + return vfs_faccessat(get_ioctx(), at, pathname, mode, flags); } int sys_pipe(int *filedes) {