Kernel/LibC: add SYS_STAT and stat(), lstat()
This commit is contained in:
parent
30bb61a775
commit
9d64dbd5c2
|
@ -64,7 +64,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<off_t> tell(int fd);
|
BAN::ErrorOr<off_t> tell(int fd);
|
||||||
|
|
||||||
BAN::ErrorOr<void> fstat(int fd, struct stat*);
|
BAN::ErrorOr<void> fstat(int fd, struct stat*);
|
||||||
BAN::ErrorOr<void> stat(BAN::StringView path, struct stat*);
|
BAN::ErrorOr<void> stat(BAN::StringView path, struct stat*, int flags);
|
||||||
|
|
||||||
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
||||||
|
|
||||||
|
|
|
@ -522,9 +522,9 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out)
|
BAN::ErrorOr<void> Process::stat(BAN::StringView path, struct stat* out, int flags)
|
||||||
{
|
{
|
||||||
int fd = TRY(open(path, O_RDONLY | O_NOFOLLOW));
|
int fd = TRY(open(path, flags));
|
||||||
auto ret = fstat(fd, out);
|
auto ret = fstat(fd, out);
|
||||||
MUST(close(fd));
|
MUST(close(fd));
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -534,7 +534,7 @@ argument_done:
|
||||||
BAN::String entry_path;
|
BAN::String entry_path;
|
||||||
TRY(entry_path.append(entry_prefix));
|
TRY(entry_path.append(entry_prefix));
|
||||||
TRY(entry_path.append(entry));
|
TRY(entry_path.append(entry));
|
||||||
TRY(Process::current().stat(entry_path, &st));
|
TRY(Process::current().stat(entry_path, &st, O_RDONLY | O_NOFOLLOW));
|
||||||
|
|
||||||
Inode::Mode mode { st.st_mode };
|
Inode::Mode mode { st.st_mode };
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ argument_done:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
TRY(Process::current().stat(arguments[1], &st));
|
TRY(Process::current().stat(arguments[1], &st, O_RDONLY | O_NOFOLLOW));
|
||||||
|
|
||||||
Inode::Mode mode { st.st_mode };
|
Inode::Mode mode { st.st_mode };
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,14 @@ namespace Kernel
|
||||||
return ret.value();
|
return ret.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sys_stat(const char* path, struct stat* buf, int flags)
|
||||||
|
{
|
||||||
|
auto ret = Process::current().stat(path, buf, flags);
|
||||||
|
if (ret.is_error())
|
||||||
|
return -ret.error().get_error_code();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" long sys_fork_trampoline();
|
extern "C" long sys_fork_trampoline();
|
||||||
|
|
||||||
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
extern "C" long cpp_syscall_handler(int syscall, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t arg4, uintptr_t arg5)
|
||||||
|
@ -193,6 +201,9 @@ namespace Kernel
|
||||||
case SYS_WAIT:
|
case SYS_WAIT:
|
||||||
ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
|
ret = sys_wait((pid_t)arg1, (int*)arg2, (int)arg3);
|
||||||
break;
|
break;
|
||||||
|
case SYS_STAT:
|
||||||
|
ret = sys_stat((const char*)arg1, (struct stat*)arg2, (int)arg3);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Kernel::panic("Unknown syscall {}", syscall);
|
Kernel::panic("Unknown syscall {}", syscall);
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,8 +180,8 @@ static void init2(void* tty1)
|
||||||
|
|
||||||
((TTY*)tty1)->initialize_device();
|
((TTY*)tty1)->initialize_device();
|
||||||
|
|
||||||
//MUST(Process::create_userspace("/usr/bin/test"sv));
|
MUST(Process::create_userspace("/usr/bin/Shell"sv));
|
||||||
//return;
|
return;
|
||||||
|
|
||||||
Process::create_kernel(
|
Process::create_kernel(
|
||||||
[](void*)
|
[](void*)
|
||||||
|
|
|
@ -10,6 +10,7 @@ set(LIBC_SOURCES
|
||||||
stdio.cpp
|
stdio.cpp
|
||||||
stdlib.cpp
|
stdlib.cpp
|
||||||
string.cpp
|
string.cpp
|
||||||
|
sys/stat.cpp
|
||||||
sys/wait.cpp
|
sys/wait.cpp
|
||||||
termios.cpp
|
termios.cpp
|
||||||
unistd.cpp
|
unistd.cpp
|
||||||
|
|
|
@ -22,6 +22,7 @@ __BEGIN_DECLS
|
||||||
#define SYS_EXEC 15
|
#define SYS_EXEC 15
|
||||||
#define SYS_REALLOC 16
|
#define SYS_REALLOC 16
|
||||||
#define SYS_WAIT 17
|
#define SYS_WAIT 17
|
||||||
|
#define SYS_STAT 18
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int lstat(const char* __restrict path, struct stat* __restrict buf)
|
||||||
|
{
|
||||||
|
return syscall(SYS_STAT, path, buf, O_RDONLY | O_NOFOLLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
int stat(const char* __restrict path, struct stat* __restrict buf)
|
||||||
|
{
|
||||||
|
return syscall(SYS_STAT, path, buf, O_RDONLY);
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
@ -145,6 +146,14 @@ long syscall(long syscall, ...)
|
||||||
ret = Kernel::syscall(SYS_WAIT, pid, (uintptr_t)stat_loc, options);
|
ret = Kernel::syscall(SYS_WAIT, pid, (uintptr_t)stat_loc, options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYS_STAT:
|
||||||
|
{
|
||||||
|
const char* path = va_arg(args, const char*);
|
||||||
|
struct stat* buf = va_arg(args, struct stat*);
|
||||||
|
int flags = va_arg(args, int);
|
||||||
|
ret = Kernel::syscall(SYS_STAT, (uintptr_t)path, (uintptr_t)buf, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
puts("LibC: Unhandeled syscall");
|
puts("LibC: Unhandeled syscall");
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
#include <BAN/Vector.h>
|
#include <BAN/Vector.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -42,6 +43,13 @@ int execute_command(BAN::StringView command)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
struct stat stat_buf;
|
||||||
|
if (stat(args.front(), &stat_buf) == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "command not found: %s\n", args.front());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +71,28 @@ int execute_command(BAN::StringView command)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int prompt_length(BAN::StringView prompt)
|
||||||
|
{
|
||||||
|
int length { 0 };
|
||||||
|
bool in_escape { false };
|
||||||
|
for (char c : prompt)
|
||||||
|
{
|
||||||
|
if (in_escape)
|
||||||
|
{
|
||||||
|
if (isalpha(c))
|
||||||
|
in_escape = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (c == '\e')
|
||||||
|
in_escape = true;
|
||||||
|
else
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
tcgetattr(0, &old_termios);
|
tcgetattr(0, &old_termios);
|
||||||
|
@ -102,8 +132,8 @@ int main(int argc, char** argv)
|
||||||
fread(&c, 1, sizeof(char), stdin);
|
fread(&c, 1, sizeof(char), stdin);
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'A': if (index > 0) { index--; col = buffers[index].size(); fprintf(stdout, "\e[G%s\e[K", buffers[index].data()); fflush(stdout); } break;
|
case 'A': if (index > 0) { index--; col = buffers[index].size(); fprintf(stdout, "\e[%dG%s\e[K", prompt_length(prompt) + 1, buffers[index].data()); fflush(stdout); } break;
|
||||||
case 'B': if (index < buffers.size() - 1) { index++; col = buffers[index].size(); fprintf(stdout, "\e[G%s\e[K", buffers[index].data()); fflush(stdout); } break;
|
case 'B': if (index < buffers.size() - 1) { index++; col = buffers[index].size(); fprintf(stdout, "\e[%dG%s\e[K", prompt_length(prompt) + 1, buffers[index].data()); fflush(stdout); } break;
|
||||||
case 'C': break;
|
case 'C': break;
|
||||||
case 'D': break;
|
case 'D': break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue