kernel+libc: Add stat() + fstat()
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
66c2896652
commit
13c9caa856
@ -34,6 +34,7 @@ set(SOURCES
|
||||
src/sys/mknod.cpp
|
||||
src/sys/waitpid.cpp
|
||||
src/sys/getdents.cpp
|
||||
src/sys/stat.cpp
|
||||
src/fs/VFS.cpp
|
||||
src/fs/tmpfs/FileSystem.cpp
|
||||
src/fs/devices/DeviceRegistry.cpp
|
||||
|
60
kernel/src/sys/stat.cpp
Normal file
60
kernel/src/sys/stat.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "memory/MemoryManager.h"
|
||||
#include "sys/Syscall.h"
|
||||
#include "thread/Scheduler.h"
|
||||
#include <bits/modes.h>
|
||||
#include <bits/struct_stat.h>
|
||||
|
||||
static mode_t make_mode(mode_t mode, VFS::InodeType type)
|
||||
{
|
||||
mode_t result = mode;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case VFS::InodeType::RegularFile: result |= S_IFREG; break;
|
||||
case VFS::InodeType::Directory: result |= S_IFDIR; break;
|
||||
case VFS::InodeType::Device: result |= S_IFCHR; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Result<u64> do_stat(SharedPtr<VFS::Inode> inode, stat* st)
|
||||
{
|
||||
stat kstat;
|
||||
|
||||
kstat.st_ino = inode->inode_number();
|
||||
kstat.st_mode = make_mode(inode->mode(), inode->type());
|
||||
kstat.st_nlink = 1; // FIXME: Count hard links to files.
|
||||
kstat.st_uid = inode->uid();
|
||||
kstat.st_gid = inode->gid();
|
||||
kstat.st_size = inode->size();
|
||||
|
||||
if (!MemoryManager::copy_to_user_typed(st, &kstat)) return err(EFAULT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result<u64> sys_stat(Registers*, SyscallArgs args)
|
||||
{
|
||||
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
||||
stat* st = (stat*)args[1];
|
||||
|
||||
Thread* current = Scheduler::current();
|
||||
|
||||
auto inode = TRY(VFS::resolve_path(path.chars(), current->auth));
|
||||
|
||||
return do_stat(inode, st);
|
||||
}
|
||||
|
||||
Result<u64> sys_fstat(Registers*, SyscallArgs args)
|
||||
{
|
||||
int fd = (int)args[0];
|
||||
stat* st = (stat*)args[1];
|
||||
|
||||
Thread* current = Scheduler::current();
|
||||
|
||||
auto descriptor = *TRY(current->resolve_fd(fd));
|
||||
|
||||
return do_stat(descriptor.inode, st);
|
||||
}
|
@ -6,6 +6,11 @@
|
||||
#define S_IFMT 070000
|
||||
#define S_IFREG 000000
|
||||
#define S_IFDIR 040000
|
||||
#define S_IFCHR 050000
|
||||
|
||||
#define S_ISREG(mode) ((mode)&S_IFMT == S_IFREG)
|
||||
#define S_ISDIR(mode) ((mode)&S_IFMT == S_IFDIR)
|
||||
#define S_ISCHR(mode) ((mode)&S_IFMT == S_IFCHR)
|
||||
|
||||
#define S_IRWXU 0700
|
||||
#define S_IRUSR 0400
|
||||
@ -23,7 +28,4 @@
|
||||
#define S_ISGID 02000
|
||||
#define S_ISVTX 01000
|
||||
|
||||
#define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
|
||||
#define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
|
||||
|
||||
#endif
|
||||
|
18
libc/include/bits/struct_stat.h
Normal file
18
libc/include/bits/struct_stat.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* bits/struct_stat.h: The stat structure. */
|
||||
|
||||
#ifndef _BITS_STRUCT_STAT_H
|
||||
#define _BITS_STRUCT_STAT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct stat
|
||||
{
|
||||
ino_t st_ino;
|
||||
mode_t st_mode;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
off_t st_size;
|
||||
};
|
||||
|
||||
#endif
|
@ -4,6 +4,7 @@
|
||||
#define _SYS_STAT_H
|
||||
|
||||
#include <bits/modes.h>
|
||||
#include <bits/struct_stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -17,6 +18,17 @@ extern "C"
|
||||
/* Create a special file. */
|
||||
int mknod(const char* path, mode_t mode, dev_t dev);
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
|
||||
/* Retrieve information about a file. */
|
||||
int stat(const char* path, struct stat* st);
|
||||
|
||||
#pragma GCC pop_options
|
||||
|
||||
/* Retrieve information about a file. */
|
||||
int fstat(int fd, struct stat* st);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@ typedef __u64_t dev_t;
|
||||
typedef __u64_t ino_t;
|
||||
typedef __u32_t uid_t;
|
||||
typedef __u32_t gid_t;
|
||||
typedef __u64_t nlink_t;
|
||||
|
||||
typedef off_t fpos_t;
|
||||
|
||||
|
@ -16,4 +16,16 @@ extern "C"
|
||||
long rc = syscall(SYS_mknod, path, mode, dev);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int stat(const char* path, struct stat* st)
|
||||
{
|
||||
long rc = syscall(SYS_stat, path, st);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
|
||||
int fstat(int fd, struct stat* st)
|
||||
{
|
||||
long rc = syscall(SYS_fstat, fd, st);
|
||||
__errno_return(rc, int);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(open) _e(close) _e(read) _e(getpid) _e(write) \
|
||||
_e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \
|
||||
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(chmod) _e(chown) \
|
||||
_e(ioctl)
|
||||
_e(ioctl) _e(stat) _e(fstat)
|
||||
|
||||
enum Syscalls
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user