diff options
-rw-r--r-- | Kernel/Process.cpp | 18 | ||||
-rw-r--r-- | Kernel/Process.h | 1 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 3 | ||||
-rw-r--r-- | Kernel/Syscall.h | 3 | ||||
-rw-r--r-- | Libraries/LibC/unistd.cpp | 6 | ||||
-rw-r--r-- | Libraries/LibC/unistd.h | 1 | ||||
-rw-r--r-- | Userland/reboot.cpp | 15 |
7 files changed, 45 insertions, 2 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 395c469f68..f89b5bc870 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -12,6 +12,7 @@ #include <Kernel/FileSystem/FileDescription.h> #include <Kernel/FileSystem/SharedMemory.h> #include <Kernel/FileSystem/VirtualFileSystem.h> +#include <Kernel/IO.h> #include <Kernel/KSyms.h> #include <Kernel/Multiboot.h> #include <Kernel/Net/Socket.h> @@ -19,8 +20,8 @@ #include <Kernel/ProcessTracer.h> #include <Kernel/RTC.h> #include <Kernel/Scheduler.h> -#include <Kernel/StdLib.h> #include <Kernel/SharedBuffer.h> +#include <Kernel/StdLib.h> #include <Kernel/Syscall.h> #include <Kernel/TTY/MasterPTY.h> #include <Kernel/kmalloc.h> @@ -2635,6 +2636,21 @@ int Process::sys$systrace(pid_t pid) return fd; } +int Process::sys$reboot() +{ + if (!is_superuser()) + return -EPERM; + + dbgprintf("acquiring FS locks...\n"); + FS::lock_all(); + dbgprintf("syncing mounted filesystems...\n"); + FS::sync(); + dbgprintf("attempting reboot via KB Controller...\n"); + IO::out8(0x64, 0xFE); + + return ESUCCESS; +} + ProcessTracer& Process::ensure_tracer() { if (!m_tracer) diff --git a/Kernel/Process.h b/Kernel/Process.h index 67ea98672c..874ed84f9b 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -203,6 +203,7 @@ public: int sys$release_shared_buffer(int shared_buffer_id); int sys$seal_shared_buffer(int shared_buffer_id); int sys$get_shared_buffer_size(int shared_buffer_id); + int sys$reboot(); static void initialize(); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 80f08785de..4f17862e41 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -293,6 +293,9 @@ static u32 handle(RegisterDump& regs, u32 function, u32 arg1, u32 arg2, u32 arg3 IO::out16(0x604, 0x2000); break; } + case Syscall::SC_reboot: { + return current->process().sys$reboot(); + } default: kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3); return -ENOSYS; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 2dd38ec449..20e030999b 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -114,7 +114,8 @@ struct timeval; __ENUMERATE_SYSCALL(sched_setparam) \ __ENUMERATE_SYSCALL(sched_getparam) \ __ENUMERATE_SYSCALL(fchown) \ - __ENUMERATE_SYSCALL(halt) + __ENUMERATE_SYSCALL(halt) \ + __ENUMERATE_SYSCALL(reboot) namespace Syscall { diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index b2307f1f7c..a859bcd85b 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -514,4 +514,10 @@ int fsync(int fd) dbgprintf("FIXME: Implement fsync()\n"); return 0; } + +int reboot() +{ + int rc = syscall(SC_reboot); + __RETURN_WITH_ERRNO(rc, rc, -1); +} } diff --git a/Libraries/LibC/unistd.h b/Libraries/LibC/unistd.h index 806efbebe0..a84353dc5a 100644 --- a/Libraries/LibC/unistd.h +++ b/Libraries/LibC/unistd.h @@ -93,6 +93,7 @@ char* getlogin(); int chown(const char* pathname, uid_t, gid_t); int fchown(int fd, uid_t, gid_t); int ftruncate(int fd, off_t length); +int reboot(); enum { _PC_NAME_MAX, diff --git a/Userland/reboot.cpp b/Userland/reboot.cpp new file mode 100644 index 0000000000..feeae974ba --- /dev/null +++ b/Userland/reboot.cpp @@ -0,0 +1,15 @@ +#include <stdio.h> +#include <unistd.h> + + +int main(int, char**) +{ + if (reboot() < 0){ + perror("reboot"); + return 1; + } + return 0; +} + + + |