mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-29 05:38:21 +00:00
syscalls: fchmodat
This commit is contained in:
@@ -30,7 +30,8 @@ extern syscall_mkdir
|
||||
extern syscall_munmap
|
||||
extern syscall_umask
|
||||
extern syscall_poll
|
||||
func_count equ 29
|
||||
extern syscall_fchmodat
|
||||
func_count equ 30
|
||||
|
||||
|
||||
func_table:
|
||||
@@ -63,6 +64,7 @@ func_table:
|
||||
dq syscall_munmap
|
||||
dq syscall_umask
|
||||
dq syscall_poll
|
||||
dq syscall_fchmodat
|
||||
section .text
|
||||
global asm_syscall_entry
|
||||
|
||||
|
||||
+7
-1
@@ -77,8 +77,14 @@ static int devfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int devfs_chmod(vnode_t* node, mode_t mode){
|
||||
node->st.st_mode &= ~07777;
|
||||
node->st.st_mode |= mode & 07777;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fscalls_t devfscalls = {
|
||||
devfs_mount, devfs_unmount, devfs_open, devfs_close, devfs_mkdir, devfs_create, devfs_write, devfs_read, devfs_getdirent
|
||||
devfs_mount, devfs_unmount, devfs_open, devfs_close, devfs_mkdir, devfs_create, devfs_write, devfs_read, devfs_getdirent, devfs_chmod
|
||||
};
|
||||
|
||||
void devfs_init(){
|
||||
|
||||
+7
-1
@@ -155,8 +155,14 @@ static int tmpfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmpfs_chmod(vnode_t* node, mode_t mode){
|
||||
node->st.st_mode &= ~07777;
|
||||
node->st.st_mode |= mode & 07777;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fscalls_t funcs = {
|
||||
tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create, tmpfs_write, tmpfs_read, tmpfs_getdirent
|
||||
tmpfs_mount, tmpfs_unmount, tmpfs_open, tmpfs_close, tmpfs_mkdir, tmpfs_create, tmpfs_write, tmpfs_read, tmpfs_getdirent, tmpfs_chmod
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -100,6 +100,21 @@ int vfs_isatty(vnode_t* node){
|
||||
|
||||
}
|
||||
|
||||
int vfs_chmod(vnode_t* node, mode_t mode){
|
||||
|
||||
if(!node->fs->calls->chmod)
|
||||
return ENOSYS;
|
||||
|
||||
spinlock_acquire(&lock);
|
||||
|
||||
int ret = node->fs->calls->chmod(node, mode);
|
||||
|
||||
spinlock_release(&lock);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int vfs_poll(vnode_t* node, pollfd* fd){
|
||||
|
||||
switch(GETTYPE(node->st.st_mode)){
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define O_TMPFILE 020000000
|
||||
|
||||
#define MAX_FD 512
|
||||
#define AT_FDCWD -100
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -61,6 +61,8 @@ typedef struct _fscalls_t {
|
||||
int (*read)(int* error, vnode_t* node, void* buff, size_t count, size_t offset);
|
||||
// get dir ents
|
||||
int (*getdirent)(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount);
|
||||
// change file mode
|
||||
int (*chmod)(vnode_t* node, mode_t mode);
|
||||
} fscalls_t;
|
||||
|
||||
|
||||
@@ -76,6 +78,7 @@ int vfs_isatty(vnode_t* node);
|
||||
int vfs_getdirent(dirnode_t* node, dent_t* buff, size_t count, uintmax_t offset, size_t* readcount);
|
||||
int vfs_ioctl(vnode_t* node, unsigned long request, void* arg, int* result);
|
||||
int vfs_poll(vnode_t* node, pollfd* fd);
|
||||
int vfs_chmod(vnode_t* node, mode_t mode);
|
||||
|
||||
void vfs_init();
|
||||
dirnode_t* vfs_root();
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/vfs.h>
|
||||
#include <sys/types.h>
|
||||
#include <arch/cls.h>
|
||||
#include <kernel/fd.h>
|
||||
#include <kernel/sched.h>
|
||||
|
||||
// flags is ignored for now
|
||||
|
||||
syscallret syscall_fchmodat(int dirfd, const char* path, mode_t mode, int flags){
|
||||
syscallret retv;
|
||||
retv.ret = -1;
|
||||
|
||||
|
||||
if(path > USER_SPACE_END){
|
||||
retv.errno = EFAULT;
|
||||
return retv;
|
||||
}
|
||||
|
||||
size_t len = strlen(path);
|
||||
|
||||
char buff[len+1];
|
||||
|
||||
strcpy(buff, path);
|
||||
|
||||
proc_t* proc = arch_getcls()->thread->proc;
|
||||
|
||||
dirnode_t* target;
|
||||
fd_t* fd;
|
||||
|
||||
if(dirfd != AT_FDCWD){
|
||||
|
||||
int err = fd_access(&proc->fdtable, &fd, dirfd);
|
||||
|
||||
if(err){
|
||||
retv.errno = err;
|
||||
return retv;
|
||||
}
|
||||
|
||||
if(GETTYPE(fd->mode) != TYPE_DIR){
|
||||
retv.errno = ENOTDIR;
|
||||
goto _fail;
|
||||
}
|
||||
|
||||
target = fd->node;
|
||||
}
|
||||
else
|
||||
target = proc->cwd;
|
||||
|
||||
|
||||
vnode_t* node;
|
||||
|
||||
retv.errno = vfs_open(&node, buff[0] == '/' ? proc->root : target, buff);
|
||||
|
||||
if(retv.errno)
|
||||
goto _fail;
|
||||
|
||||
retv.errno = vfs_chmod(node, mode);
|
||||
|
||||
vfs_close(node);
|
||||
|
||||
_fail:
|
||||
|
||||
if(dirfd != AT_FDCWD)
|
||||
fd_release(fd);
|
||||
|
||||
retv.ret = retv.errno ? -1 : 0;
|
||||
|
||||
return retv;
|
||||
|
||||
}
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <arch/spinlock.h>
|
||||
#include <string.h>
|
||||
|
||||
#define AT_FDCWD -100
|
||||
|
||||
syscallret syscall_fstatat(int ifd, char* path, stat* st, int flags){
|
||||
syscallret retv;
|
||||
retv.ret = -1;
|
||||
@@ -67,13 +65,13 @@ syscallret syscall_fstatat(int ifd, char* path, stat* st, int flags){
|
||||
|
||||
vfs_close(node);
|
||||
|
||||
retv.ret = 0;
|
||||
|
||||
_fail:
|
||||
|
||||
if(ifd != AT_FDCWD)
|
||||
fd_release(fd);
|
||||
|
||||
retv.ret = 0;
|
||||
|
||||
return retv;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user