diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 818e137782e..b47a3e11928 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -518,6 +518,15 @@ void Task::dumpRegions() } } +void Task::notify_waiters(pid_t waitee, int exit_status, int signal) +{ + ASSERT_INTERRUPTS_DISABLED(); + for (auto* task = s_tasks->head(); task; task = task->next()) { + if (task->waitee() == waitee) + task->m_waiteeStatus = (exit_status << 8) | (signal); + } +} + void Task::sys$exit(int status) { cli(); @@ -531,10 +540,7 @@ void Task::sys$exit(int status) s_tasks->remove(this); - for (auto* task = s_tasks->head(); task; task = task->next()) { - if (task->waitee() == m_pid) - task->m_waiteeStatus = status << 8; - } + notify_waiters(m_pid, status, 0); if (!scheduleNewTask()) { kprintf("Task::sys$exit: Failed to schedule a new task :(\n"); @@ -546,13 +552,17 @@ void Task::sys$exit(int status) switchNow(); } -void Task::murder() +void Task::murder(int signal) { ASSERT_INTERRUPTS_DISABLED(); bool wasCurrent = current == this; setState(Exiting); s_tasks->remove(this); + + notify_waiters(m_pid, 0, signal); + if (wasCurrent) { + kprintf("Current task committing suicide!\n"); MM.unmapRegionsForTask(*this); if (!scheduleNewTask()) { kprintf("Task::murder: Failed to schedule a new task :(\n"); @@ -578,6 +588,8 @@ void Task::taskDidCrash(Task* crashedTask) s_tasks->remove(crashedTask); + notify_waiters(crashedTask->m_pid, 0, SIGSEGV); + MM.unmapRegionsForTask(*crashedTask); if (!scheduleNewTask()) { @@ -991,8 +1003,9 @@ int Task::sys$kill(pid_t pid, int sig) auto* peer = Task::fromPID(pid); if (!peer) return -ESRCH; - if (sig == 9) { - peer->murder(); + if (sig == SIGKILL) { + peer->murder(SIGKILL); + return 0; } else { ASSERT_NOT_REACHED(); } diff --git a/Kernel/Task.h b/Kernel/Task.h index 8f7e77716c0..20c5000d7d0 100644 --- a/Kernel/Task.h +++ b/Kernel/Task.h @@ -218,7 +218,8 @@ private: pid_t m_parentPID { 0 }; - void murder(); + static void notify_waiters(pid_t waitee, int exit_status, int signal); + void murder(int signal); Vector m_arguments; Vector m_initialEnvironment; diff --git a/Kernel/VirtualConsole.cpp b/Kernel/VirtualConsole.cpp index 433b438d485..6395fa03e1d 100644 --- a/Kernel/VirtualConsole.cpp +++ b/Kernel/VirtualConsole.cpp @@ -300,6 +300,8 @@ void VirtualConsole::scrollUp() void VirtualConsole::setCursor(unsigned row, unsigned column) { + ASSERT(row < m_rows); + ASSERT(column < m_columns); m_cursorRow = row; m_cursorColumn = column; if (m_active) @@ -308,6 +310,8 @@ void VirtualConsole::setCursor(unsigned row, unsigned column) void VirtualConsole::putCharacterAt(unsigned row, unsigned column, byte ch) { + ASSERT(row < m_rows); + ASSERT(column < m_columns); word cur = (row * 160) + (column * 2); m_buffer[cur] = ch; m_buffer[cur + 1] = m_currentAttribute; @@ -317,6 +321,7 @@ void VirtualConsole::putCharacterAt(unsigned row, unsigned column, byte ch) void VirtualConsole::onChar(byte ch, bool shouldEmit) { + InterruptDisabler disabler; if (shouldEmit) emit(ch); diff --git a/LibC/unistd.h b/LibC/unistd.h index fcddc917e25..92122149987 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -30,6 +30,7 @@ off_t lseek(int fd, off_t, int whence); #define WEXITSTATUS(status) (((status) & 0xff00) >> 8) #define WTERMSIG(status) ((status) & 0x7f) #define WIFEXITED(status) (WTERMSIG(status) == 0) +#define WIFSIGNALED(status) (((char) (((status) & 0x7f) + 1) >> 1) > 0) #define HOST_NAME_MAX 64 diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp index 7e795906e31..9285be1a872 100644 --- a/VirtualFileSystem/FileHandle.cpp +++ b/VirtualFileSystem/FileHandle.cpp @@ -5,6 +5,7 @@ #include "UnixTypes.h" #include "TTY.h" #include +#include FileHandle::FileHandle(RetainPtr&& vnode) : m_vnode(move(vnode)) diff --git a/VirtualFileSystem/UnixTypes.h b/VirtualFileSystem/UnixTypes.h index eeed7bb94bf..a55422a9210 100644 --- a/VirtualFileSystem/UnixTypes.h +++ b/VirtualFileSystem/UnixTypes.h @@ -8,6 +8,11 @@ namespace Unix { #define SEEK_CUR 1 #define SEEK_END 2 +#define SIGINT 2 +#define SIGKILL 9 +#define SIGSEGV 11 +#define SIGTERM 15 + typedef dword dev_t; typedef dword ino_t; typedef dword mode_t; diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 19de414dcf5..4ef6ba5df17 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -558,11 +558,13 @@ InodeIdentifier VirtualFileSystem::resolvePath(const String& path, int& error, I void VirtualFileSystem::Node::retain() { + InterruptDisabler disabler; // FIXME: Make a Retainable with atomic retain count instead. ++retainCount; } void VirtualFileSystem::Node::release() { + InterruptDisabler disabler; // FIXME: Make a Retainable with atomic retain count instead. ASSERT(retainCount); if (--retainCount == 0) { m_vfs->freeNode(this);