forked from Bananymous/banan-os
Kernel/LibC: add SYS_{SET,GET}_PWD and chdir, getpwd
This commit is contained in:
parent
537780ee1e
commit
0f63cfa43f
|
@ -58,6 +58,9 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> setenvp(char** envp);
|
BAN::ErrorOr<void> setenvp(char** envp);
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> set_pwd(const char* path);
|
||||||
|
BAN::ErrorOr<char*> get_pwd(char* buffer, size_t size);
|
||||||
|
|
||||||
BAN::ErrorOr<void> set_uid(uid_t);
|
BAN::ErrorOr<void> set_uid(uid_t);
|
||||||
BAN::ErrorOr<void> set_gid(gid_t);
|
BAN::ErrorOr<void> set_gid(gid_t);
|
||||||
BAN::ErrorOr<void> set_euid(uid_t);
|
BAN::ErrorOr<void> set_euid(uid_t);
|
||||||
|
|
|
@ -667,6 +667,38 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Process::set_pwd(const char* path)
|
||||||
|
{
|
||||||
|
BAN::String absolute_path;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
absolute_path = TRY(absolute_path_of(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto file = TRY(VirtualFileSystem::get().file_from_absolute_path(m_credentials, absolute_path, O_SEARCH));
|
||||||
|
if (!file.inode->mode().ifdir())
|
||||||
|
return BAN::Error::from_errno(ENOTDIR);
|
||||||
|
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
m_working_directory = BAN::move(file.canonical_path);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<char*> Process::get_pwd(char* buffer, size_t size)
|
||||||
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
|
||||||
|
if (size < m_working_directory.size() + 1)
|
||||||
|
return BAN::Error::from_errno(ERANGE);
|
||||||
|
|
||||||
|
memcpy(buffer, m_working_directory.data(), m_working_directory.size());
|
||||||
|
buffer[m_working_directory.size()] = '\0';
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::String> Process::working_directory() const
|
BAN::ErrorOr<BAN::String> Process::working_directory() const
|
||||||
{
|
{
|
||||||
BAN::String result;
|
BAN::String result;
|
||||||
|
|
|
@ -228,6 +228,22 @@ namespace Kernel
|
||||||
return Process::current().get_egid();
|
return Process::current().get_egid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long sys_get_pwd(char* buffer, size_t size)
|
||||||
|
{
|
||||||
|
auto ret = Process::current().get_pwd(buffer, size);
|
||||||
|
if (ret.is_error())
|
||||||
|
return -ret.error().get_error_code();
|
||||||
|
return (long)ret.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
long sys_set_pwd(const char* path)
|
||||||
|
{
|
||||||
|
auto ret = Process::current().set_pwd(path);
|
||||||
|
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)
|
||||||
|
@ -335,6 +351,12 @@ namespace Kernel
|
||||||
case SYS_GET_EGID:
|
case SYS_GET_EGID:
|
||||||
ret = sys_get_egid();
|
ret = sys_get_egid();
|
||||||
break;
|
break;
|
||||||
|
case SYS_GET_PWD:
|
||||||
|
ret = sys_get_pwd((char*)arg1, (size_t)arg2);
|
||||||
|
break;
|
||||||
|
case SYS_SET_PWD:
|
||||||
|
ret = sys_set_pwd((const char*)arg1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
|
|
@ -36,6 +36,8 @@ __BEGIN_DECLS
|
||||||
#define SYS_GET_GID 29
|
#define SYS_GET_GID 29
|
||||||
#define SYS_GET_EUID 30
|
#define SYS_GET_EUID 30
|
||||||
#define SYS_GET_EGID 31
|
#define SYS_GET_EGID 31
|
||||||
|
#define SYS_GET_PWD 32
|
||||||
|
#define SYS_SET_PWD 33
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -233,6 +233,19 @@ long syscall(long syscall, ...)
|
||||||
ret = Kernel::syscall(SYS_GET_EGID);
|
ret = Kernel::syscall(SYS_GET_EGID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SYS_GET_PWD:
|
||||||
|
{
|
||||||
|
char* buffer = va_arg(args, char*);
|
||||||
|
size_t size = va_arg(args, size_t);
|
||||||
|
ret = Kernel::syscall(SYS_GET_PWD, (uintptr_t)buffer, size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SYS_SET_PWD:
|
||||||
|
{
|
||||||
|
const char* path = va_arg(args, const char*);
|
||||||
|
ret = Kernel::syscall(SYS_SET_PWD, (uintptr_t)path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
puts("LibC: Unhandeled syscall");
|
puts("LibC: Unhandeled syscall");
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
|
@ -342,6 +355,26 @@ unsigned int sleep(unsigned int seconds)
|
||||||
return syscall(SYS_SLEEP, seconds);
|
return syscall(SYS_SLEEP, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* getcwd(char* buf, size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((char*)syscall(SYS_GET_PWD, buf, size) == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
setenv("PWD", buf, 1);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
int chdir(const char* path)
|
||||||
|
{
|
||||||
|
return syscall(SYS_SET_PWD, path);
|
||||||
|
}
|
||||||
|
|
||||||
uid_t getuid(void)
|
uid_t getuid(void)
|
||||||
{
|
{
|
||||||
return syscall(SYS_GET_UID);
|
return syscall(SYS_GET_UID);
|
||||||
|
|
Loading…
Reference in New Issue