mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-28 13:18:22 +00:00
91 lines
1.5 KiB
C
91 lines
1.5 KiB
C
#include <kernel/syscalls.h>
|
|
#include <kernel/sched.h>
|
|
#include <arch/cls.h>
|
|
#include <kernel/fd.h>
|
|
#include <sys/types.h>
|
|
#include <arch/spinlock.h>
|
|
#include <errno.h>
|
|
#include <kernel/alloc.h>
|
|
#include <stddef.h>
|
|
|
|
|
|
syscallret syscall_open(const char* pathname, int flags, mode_t mode){
|
|
|
|
syscallret retv;
|
|
retv.ret = -1;
|
|
|
|
if(pathname > USER_SPACE_END){
|
|
retv.errno = EFAULT;
|
|
return retv;
|
|
}
|
|
|
|
const char* name = alloc(strlen(pathname) + 1); // XXX use an user specific strlen func
|
|
if(!name){
|
|
retv.errno = ENOMEM;
|
|
return retv;
|
|
}
|
|
|
|
strcpy(name, pathname); // XXX use an user specific strcpy
|
|
|
|
proc_t* proc = arch_getcls()->thread->proc;
|
|
|
|
int ifd;
|
|
fd_t* fd;
|
|
|
|
int err = fd_alloc(&proc->fdtable, &fd, &ifd);
|
|
|
|
if(err){
|
|
retv.errno = err;
|
|
free(name);
|
|
return retv;
|
|
}
|
|
|
|
fd->flags = flags + 1; // 1 is added to make O_RDONLY etc easier to lookup
|
|
fd->offset = 0;
|
|
|
|
vnode_t* file = NULL;
|
|
|
|
size_t ret = vfs_open(&file,
|
|
*name == '/' ? proc->root : proc->cwd,
|
|
*name == '/' ? name + 1 : name
|
|
);
|
|
|
|
if(ret == ENOENT && (flags & O_CREAT)){
|
|
printf("O_CREAT NOT SUPPORTED YET!\n");
|
|
retv.errno = ENOENT;
|
|
goto _fail;
|
|
}
|
|
else if(ret){
|
|
retv.errno = ret;
|
|
goto _fail;
|
|
}
|
|
|
|
if((flags & O_DIRECTORY) && (file->st.st_mode & MAKETYPE(TYPE_DIR)) == 0){
|
|
retv.errno = ENOTDIR;
|
|
goto _fail;
|
|
}
|
|
|
|
|
|
fd->node = file;
|
|
|
|
fd_release(fd);
|
|
|
|
free(name);
|
|
retv.errno = 0;
|
|
retv.ret = ifd;
|
|
|
|
return retv;
|
|
|
|
_fail:
|
|
|
|
if(file)
|
|
vfs_close(file);
|
|
|
|
fd_release(fd);
|
|
fd_free(&proc->fdtable, fd);
|
|
fd->node = NULL;
|
|
free(name);
|
|
return retv;
|
|
|
|
}
|