1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:38:10 +00:00

UserspaceEmulator: Add syscalls: stat(), realpath(), gethostname()

This is enough to run /bin/ls :^)
This commit is contained in:
Andreas Kling 2020-07-28 00:02:47 +02:00
parent 9def88e08d
commit b8d3dbcf2d
2 changed files with 57 additions and 0 deletions

View file

@ -245,6 +245,12 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
switch (function) {
case SC_execve:
return virt$execve(arg1);
case SC_stat:
return virt$stat(arg1);
case SC_realpath:
return virt$realpath(arg1);
case SC_gethostname:
return virt$gethostname(arg1, arg2);
case SC_ioctl:
return virt$ioctl(arg1, arg2, arg3);
case SC_get_dir_entries:
@ -927,4 +933,52 @@ int Emulator::virt$execve(FlatPtr params_addr)
return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data());
}
int Emulator::virt$stat(FlatPtr params_addr)
{
Syscall::SC_stat_params params;
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
struct stat host_statbuf;
int rc;
if (params.follow_symlinks)
rc = stat(path.characters(), &host_statbuf);
else
rc = lstat(path.characters(), &host_statbuf);
if (rc < 0)
return -errno;
mmu().copy_to_vm((FlatPtr)params.statbuf, &host_statbuf, sizeof(host_statbuf));
return rc;
}
int Emulator::virt$realpath(FlatPtr params_addr)
{
Syscall::SC_realpath_params params;
mmu().copy_from_vm(&params, params_addr, sizeof(params));
auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
char host_buffer[PATH_MAX] = {};
Syscall::SC_realpath_params host_params;
host_params.path = { path.characters(), path.length() };
host_params.buffer = { host_buffer, sizeof(host_buffer) };
int rc = syscall(SC_realpath, &host_params);
if (rc < 0)
return rc;
mmu().copy_to_vm((FlatPtr)params.buffer.data, host_buffer, min(params.buffer.size, sizeof(host_buffer)));
return rc;
}
int Emulator::virt$gethostname(FlatPtr buffer, ssize_t buffer_size)
{
if (buffer_size < 0)
return -EINVAL;
auto host_buffer = ByteBuffer::create_zeroed(buffer_size);
int rc = syscall(SC_gethostname, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
return rc;
}
}