summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Process.cpp18
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/Syscall.cpp3
-rw-r--r--Kernel/Syscall.h3
-rw-r--r--Libraries/LibC/unistd.cpp6
-rw-r--r--Libraries/LibC/unistd.h1
-rw-r--r--Userland/reboot.cpp15
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;
+}
+
+
+