Kernel, libc: Add stat()
This commit is contained in:
parent
0c04246300
commit
58b01b74e2
@ -25,6 +25,7 @@
|
|||||||
#define SYS_fstat 20
|
#define SYS_fstat 20
|
||||||
#define SYS_pstat 21
|
#define SYS_pstat 21
|
||||||
#define SYS_getdents 22
|
#define SYS_getdents 22
|
||||||
|
#define SYS_stat 23
|
||||||
|
|
||||||
struct stat;
|
struct stat;
|
||||||
struct pstat;
|
struct pstat;
|
||||||
@ -57,4 +58,5 @@ void sys_waitpid(Context* context, long pid, int* wstatus, int options);
|
|||||||
void sys_access(Context* context, const char* path, int amode);
|
void sys_access(Context* context, const char* path, int amode);
|
||||||
void sys_fstat(Context* context, int fd, struct stat* buf);
|
void sys_fstat(Context* context, int fd, struct stat* buf);
|
||||||
void sys_pstat(Context* context, long pid, struct pstat* buf);
|
void sys_pstat(Context* context, long pid, struct pstat* buf);
|
||||||
void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count);
|
void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t count);
|
||||||
|
void sys_stat(Context* context, const char* path, struct stat* buf);
|
@ -1,6 +1,7 @@
|
|||||||
#include "fs/VFS.h"
|
#include "fs/VFS.h"
|
||||||
#include "interrupts/Context.h"
|
#include "interrupts/Context.h"
|
||||||
#include "std/errno.h"
|
#include "std/errno.h"
|
||||||
|
#include "std/stdlib.h"
|
||||||
#include "sys/UserMemory.h"
|
#include "sys/UserMemory.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
|
|
||||||
@ -15,6 +16,21 @@ struct stat // FIXME: This struct is quite stubbed out.
|
|||||||
off_t st_size;
|
off_t st_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void do_stat(Context* context, VFS::Node* node, struct stat* buf)
|
||||||
|
{
|
||||||
|
struct stat* kstat = obtain_user_ref(buf);
|
||||||
|
if (!kstat)
|
||||||
|
{
|
||||||
|
context->rax = -EFAULT; // FIXME: The manual doesn't say fstat can return EFAULT, but it seems logical here...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kstat->st_ino = node->inode;
|
||||||
|
kstat->st_mode = (mode_t)node->type;
|
||||||
|
kstat->st_size = node->length;
|
||||||
|
release_user_ref(kstat);
|
||||||
|
context->rax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void sys_fstat(Context* context, int fd, struct stat* buf)
|
void sys_fstat(Context* context, int fd, struct stat* buf)
|
||||||
{
|
{
|
||||||
Task* current_task = Scheduler::current_task();
|
Task* current_task = Scheduler::current_task();
|
||||||
@ -29,16 +45,24 @@ void sys_fstat(Context* context, int fd, struct stat* buf)
|
|||||||
context->rax = -EBADF;
|
context->rax = -EBADF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct stat* kstat = obtain_user_ref(buf);
|
VFS::Node* node = file.node();
|
||||||
if (!kstat)
|
return do_stat(context, node, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sys_stat(Context* context, const char* path, struct stat* buf)
|
||||||
|
{
|
||||||
|
char* kpath = strdup_from_user(path);
|
||||||
|
if (!kpath)
|
||||||
{
|
{
|
||||||
context->rax = -EFAULT; // FIXME: The manual doesn't say fstat can return EFAULT, but it seems logical here...
|
context->rax = -EFAULT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
VFS::Node* node = file.node();
|
VFS::Node* node = VFS::resolve_path(kpath);
|
||||||
kstat->st_ino = node->inode;
|
kfree(kpath);
|
||||||
kstat->st_mode = (mode_t)node->type;
|
if (!node)
|
||||||
kstat->st_size = node->length;
|
{
|
||||||
release_user_ref(kstat);
|
context->rax = -ENOENT;
|
||||||
context->rax = 0;
|
return;
|
||||||
|
}
|
||||||
|
return do_stat(context, node, buf);
|
||||||
}
|
}
|
@ -25,6 +25,9 @@ extern "C"
|
|||||||
/* Returns information about the file pointed to by fd in buf. */
|
/* Returns information about the file pointed to by fd in buf. */
|
||||||
int fstat(int fd, struct stat* buf);
|
int fstat(int fd, struct stat* buf);
|
||||||
|
|
||||||
|
/* Returns information about the file pointed at path in buf. */
|
||||||
|
int stat(const char* pathname, struct stat* buf);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,5 +24,6 @@
|
|||||||
#define SYS_fstat 20
|
#define SYS_fstat 20
|
||||||
#define SYS_pstat 21
|
#define SYS_pstat 21
|
||||||
#define SYS_getdents 22
|
#define SYS_getdents 22
|
||||||
|
#define SYS_stat 23
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -13,4 +13,9 @@ extern "C"
|
|||||||
{
|
{
|
||||||
return (int)syscall(SYS_fstat, fd, buf);
|
return (int)syscall(SYS_fstat, fd, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int stat(const char* path, struct stat* buf)
|
||||||
|
{
|
||||||
|
return (int)syscall(SYS_stat, path, buf);
|
||||||
|
}
|
||||||
}
|
}
|
@ -24,6 +24,7 @@ extern "C" long syscall(long number, ...)
|
|||||||
case SYS_munmap:
|
case SYS_munmap:
|
||||||
case SYS_access:
|
case SYS_access:
|
||||||
case SYS_fstat:
|
case SYS_fstat:
|
||||||
|
case SYS_stat:
|
||||||
case SYS_pstat:
|
case SYS_pstat:
|
||||||
case SYS_open: {
|
case SYS_open: {
|
||||||
arg arg0 = va_arg(ap, arg);
|
arg arg0 = va_arg(ap, arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user