78 lines
1.9 KiB
C++
78 lines
1.9 KiB
C++
#include "fs/VFS.h"
|
|
#include "interrupts/Context.h"
|
|
#include "std/errno.h"
|
|
#include "std/stdlib.h"
|
|
#include "sys/UserMemory.h"
|
|
#include "thread/Scheduler.h"
|
|
|
|
typedef unsigned short mode_t;
|
|
typedef unsigned long ino_t;
|
|
|
|
struct stat // FIXME: This struct is quite stubbed out.
|
|
{
|
|
ino_t st_ino;
|
|
mode_t st_mode;
|
|
off_t st_size;
|
|
int st_dev; // FIXME: Implement this.
|
|
int st_nlink; // FIXME: Implement this.
|
|
uid_t st_uid;
|
|
gid_t st_gid;
|
|
time_t st_atime;
|
|
time_t st_mtime;
|
|
time_t st_ctime;
|
|
};
|
|
|
|
void do_stat(Context* context, VFS::Node* node, struct stat* buf)
|
|
{
|
|
struct stat stat;
|
|
stat.st_ino = node->inode;
|
|
stat.st_mode = node->mode | ((1 << (node->type)) * 010000);
|
|
stat.st_size = node->length;
|
|
stat.st_uid = node->uid;
|
|
stat.st_gid = node->gid;
|
|
stat.st_atime = node->atime;
|
|
stat.st_ctime = node->ctime;
|
|
stat.st_mtime = node->mtime;
|
|
stat.st_dev = 0;
|
|
stat.st_nlink = 0;
|
|
if (!copy_typed_to_user(buf, &stat)) context->rax = -EFAULT;
|
|
else
|
|
context->rax = 0;
|
|
}
|
|
|
|
void sys_fstat(Context* context, int fd, struct stat* buf)
|
|
{
|
|
Task* current_task = Scheduler::current_task();
|
|
if (fd < 0 || fd >= TASK_MAX_FDS)
|
|
{
|
|
context->rax = -EBADF;
|
|
return;
|
|
}
|
|
Descriptor& file = current_task->files[fd];
|
|
if (!file.is_open())
|
|
{
|
|
context->rax = -EBADF;
|
|
return;
|
|
}
|
|
VFS::Node* node = file.node();
|
|
return do_stat(context, node, buf);
|
|
}
|
|
|
|
void sys_stat(Context* context, const char* path, struct stat* buf)
|
|
{
|
|
auto result = strdup_from_user(path);
|
|
if (result.has_error())
|
|
{
|
|
context->rax = -result.error();
|
|
return;
|
|
}
|
|
char* kpath = result.release_value();
|
|
VFS::Node* node = VFS::resolve_path(kpath);
|
|
kfree(kpath);
|
|
if (!node)
|
|
{
|
|
context->rax = -ENOENT;
|
|
return;
|
|
}
|
|
return do_stat(context, node, buf);
|
|
} |