Kernel/LibC/Userspace: Add SYS_POWEROFF + cli tool
You can now shutdown/reboot banan-os with the poweroff cli tool. Reboot doesn't seem to work on qemu.
This commit is contained in:
@@ -111,6 +111,8 @@ namespace Kernel
|
||||
|
||||
BAN::ErrorOr<long> sys_sync(bool should_block);
|
||||
|
||||
BAN::ErrorOr<long> sys_poweroff(int command);
|
||||
|
||||
BAN::ErrorOr<void> mount(BAN::StringView source, BAN::StringView target);
|
||||
|
||||
BAN::ErrorOr<long> sys_read_dir_entries(int fd, DirectoryEntryList* buffer, size_t buffer_size);
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
#include <LibELF/ELF.h>
|
||||
#include <LibELF/Values.h>
|
||||
|
||||
#include <lai/helpers/pm.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/banan-os.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@@ -773,6 +776,33 @@ namespace Kernel
|
||||
return 0;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_poweroff(int command)
|
||||
{
|
||||
if (command != POWEROFF_REBOOT && command != POWEROFF_SHUTDOWN)
|
||||
return BAN::Error::from_errno(EINVAL);
|
||||
|
||||
// FIXME: gracefully kill all processes
|
||||
|
||||
DevFileSystem::get().initiate_sync(true);
|
||||
|
||||
lai_api_error_t error;
|
||||
switch (command)
|
||||
{
|
||||
case POWEROFF_REBOOT:
|
||||
error = lai_acpi_reset();
|
||||
break;
|
||||
case POWEROFF_SHUTDOWN:
|
||||
error = lai_enter_sleep(5);
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
// If we reach here, there was an error
|
||||
dprintln("{}", lai_api_error_to_string(error));
|
||||
return BAN::Error::from_errno(EUNKNOWN);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<long> Process::sys_read_dir_entries(int fd, DirectoryEntryList* list, size_t list_size)
|
||||
{
|
||||
LockGuard _(m_lock);
|
||||
|
||||
@@ -196,6 +196,9 @@ namespace Kernel
|
||||
case SYS_TTY_CTRL:
|
||||
ret = Process::current().sys_tty_ctrl((int)arg1, (int)arg2, (int)arg3);
|
||||
break;
|
||||
case SYS_POWEROFF:
|
||||
ret = Process::current().sys_poweroff((int)arg1);
|
||||
break;
|
||||
default:
|
||||
dwarnln("Unknown syscall {}", syscall);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user