diff options
-rw-r--r-- | Kernel/FileSystem/FileSystem.cpp | 8 | ||||
-rw-r--r-- | Kernel/FileSystem/FileSystem.h | 1 | ||||
-rw-r--r-- | Kernel/Syscall.cpp | 10 | ||||
-rw-r--r-- | Kernel/Syscall.h | 3 | ||||
-rw-r--r-- | Userland/shutdown.cpp | 17 |
5 files changed, 38 insertions, 1 deletions
diff --git a/Kernel/FileSystem/FileSystem.cpp b/Kernel/FileSystem/FileSystem.cpp index 96728554bc..95a4f47093 100644 --- a/Kernel/FileSystem/FileSystem.cpp +++ b/Kernel/FileSystem/FileSystem.cpp @@ -68,3 +68,11 @@ void FS::sync() for (auto fs : fses) fs->flush_writes(); } + +void FS::lock_all() +{ + for (auto& it : all_fses()) { + it.value->m_lock.lock(); + } +} + diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h index 81d953c832..a41063c0a8 100644 --- a/Kernel/FileSystem/FileSystem.h +++ b/Kernel/FileSystem/FileSystem.h @@ -32,6 +32,7 @@ public: unsigned fsid() const { return m_fsid; } static FS* from_fsid(dword); static void sync(); + static void lock_all(); virtual bool initialize() = 0; virtual const char* class_name() const = 0; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 95d14e44d7..0f6fb51404 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -1,6 +1,7 @@ #include <Kernel/Arch/i386/CPU.h> #include <Kernel/Console.h> #include <Kernel/Process.h> +#include <Kernel/IO.h> #include <Kernel/ProcessTracer.h> #include <Kernel/Scheduler.h> #include <Kernel/Syscall.h> @@ -281,6 +282,15 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2); case Syscall::SC_sched_getparam: return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2); + case Syscall::SC_halt: { + dbgprintf("<%u> halting! acquiring locks...\n"); + FS::lock_all(); + dbgprintf("<%u> halting! syncing...\n"); + FS::sync(); + dbgprintf("<%u> halting! bye, friends...\n"); + IO::out16(0x604, 0x2000); + break; + } 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 fd2f7fceef..033148a76f 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -112,7 +112,8 @@ struct timeval; __ENUMERATE_SYSCALL(getpeername) \ __ENUMERATE_SYSCALL(sched_setparam) \ __ENUMERATE_SYSCALL(sched_getparam) \ - __ENUMERATE_SYSCALL(fchown) + __ENUMERATE_SYSCALL(fchown) \ + __ENUMERATE_SYSCALL(halt) namespace Syscall { diff --git a/Userland/shutdown.cpp b/Userland/shutdown.cpp new file mode 100644 index 0000000000..7884f12c15 --- /dev/null +++ b/Userland/shutdown.cpp @@ -0,0 +1,17 @@ +#include <Kernel/Syscall.h> +#include <LibCore/CArgsParser.h> + +int main(int argc, char** argv) +{ + CArgsParser args_parser("shutdown"); + args_parser.add_arg("n", "shut down now"); + CArgsParserResult args = args_parser.parse(argc, (const char**)argv); + + if (args.is_present("n")) { + syscall(SC_halt); + return 0; + } else { + args_parser.print_usage(); + return 0; + } +} |