mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 17:06:31 +00:00
Kernel + LibC: Handle running processes in do_waitid()
This commit is contained in:
parent
9d54f21859
commit
8582a06899
|
@ -34,6 +34,7 @@
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <Kernel/ACPI/Parser.h>
|
#include <Kernel/ACPI/Parser.h>
|
||||||
#include <Kernel/Arch/i386/CPU.h>
|
#include <Kernel/Arch/i386/CPU.h>
|
||||||
|
#include <Kernel/Console.h>
|
||||||
#include <Kernel/Devices/BlockDevice.h>
|
#include <Kernel/Devices/BlockDevice.h>
|
||||||
#include <Kernel/Devices/KeyboardDevice.h>
|
#include <Kernel/Devices/KeyboardDevice.h>
|
||||||
#include <Kernel/Devices/NullDevice.h>
|
#include <Kernel/Devices/NullDevice.h>
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
#include <Kernel/FileSystem/TmpFS.h>
|
#include <Kernel/FileSystem/TmpFS.h>
|
||||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||||
#include <Kernel/Heap/kmalloc.h>
|
#include <Kernel/Heap/kmalloc.h>
|
||||||
|
#include <Kernel/IO.h>
|
||||||
#include <Kernel/KBufferBuilder.h>
|
#include <Kernel/KBufferBuilder.h>
|
||||||
#include <Kernel/KSyms.h>
|
#include <Kernel/KSyms.h>
|
||||||
#include <Kernel/Module.h>
|
#include <Kernel/Module.h>
|
||||||
|
@ -62,6 +64,7 @@
|
||||||
#include <Kernel/Random.h>
|
#include <Kernel/Random.h>
|
||||||
#include <Kernel/Scheduler.h>
|
#include <Kernel/Scheduler.h>
|
||||||
#include <Kernel/SharedBuffer.h>
|
#include <Kernel/SharedBuffer.h>
|
||||||
|
#include <Kernel/StdLib.h>
|
||||||
#include <Kernel/Syscall.h>
|
#include <Kernel/Syscall.h>
|
||||||
#include <Kernel/TTY/MasterPTY.h>
|
#include <Kernel/TTY/MasterPTY.h>
|
||||||
#include <Kernel/TTY/TTY.h>
|
#include <Kernel/TTY/TTY.h>
|
||||||
|
@ -73,9 +76,6 @@
|
||||||
#include <Kernel/VM/ProcessPagingScope.h>
|
#include <Kernel/VM/ProcessPagingScope.h>
|
||||||
#include <Kernel/VM/PurgeableVMObject.h>
|
#include <Kernel/VM/PurgeableVMObject.h>
|
||||||
#include <Kernel/VM/SharedInodeVMObject.h>
|
#include <Kernel/VM/SharedInodeVMObject.h>
|
||||||
#include <Kernel/IO.h>
|
|
||||||
#include <Kernel/Console.h>
|
|
||||||
#include <Kernel/StdLib.h>
|
|
||||||
#include <LibC/errno_numbers.h>
|
#include <LibC/errno_numbers.h>
|
||||||
#include <LibC/limits.h>
|
#include <LibC/limits.h>
|
||||||
#include <LibC/signal_numbers.h>
|
#include <LibC/signal_numbers.h>
|
||||||
|
@ -2429,31 +2429,6 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
||||||
return KResult(-ECHILD);
|
return KResult(-ECHILD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options & WNOHANG) {
|
|
||||||
// FIXME: Figure out what WNOHANG should do with stopped children.
|
|
||||||
if (idtype == P_ALL) {
|
|
||||||
InterruptDisabler disabler;
|
|
||||||
siginfo_t siginfo;
|
|
||||||
memset(&siginfo, 0, sizeof(siginfo));
|
|
||||||
for_each_child([&siginfo](Process& process) {
|
|
||||||
if (process.is_dead())
|
|
||||||
siginfo = reap(process);
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
return siginfo;
|
|
||||||
} else if (idtype == P_PID) {
|
|
||||||
InterruptDisabler disabler;
|
|
||||||
auto* waitee_process = Process::from_pid(id);
|
|
||||||
if (!waitee_process)
|
|
||||||
return KResult(-ECHILD);
|
|
||||||
if (waitee_process->is_dead())
|
|
||||||
return reap(*waitee_process);
|
|
||||||
} else {
|
|
||||||
// FIXME: Implement other PID specs.
|
|
||||||
return KResult(-EINVAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pid_t waitee_pid;
|
pid_t waitee_pid;
|
||||||
|
|
||||||
// FIXME: WaitBlocker should support idtype/id specs directly.
|
// FIXME: WaitBlocker should support idtype/id specs directly.
|
||||||
|
@ -2466,9 +2441,8 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
||||||
return KResult(-EINVAL);
|
return KResult(-EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(options & WNOHANG))
|
if (Thread::current->block<Thread::WaitBlocker>(options, waitee_pid) != Thread::BlockResult::WokeNormally)
|
||||||
if (Thread::current->block<Thread::WaitBlocker>(options, waitee_pid) != Thread::BlockResult::WokeNormally)
|
return KResult(-EINTR);
|
||||||
return KResult(-EINTR);
|
|
||||||
|
|
||||||
InterruptDisabler disabler;
|
InterruptDisabler disabler;
|
||||||
|
|
||||||
|
@ -2484,13 +2458,29 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
|
||||||
auto* waitee_thread = Thread::from_tid(waitee_pid);
|
auto* waitee_thread = Thread::from_tid(waitee_pid);
|
||||||
if (!waitee_thread)
|
if (!waitee_thread)
|
||||||
return KResult(-ECHILD);
|
return KResult(-ECHILD);
|
||||||
ASSERT(waitee_thread->state() == Thread::State::Stopped);
|
ASSERT((options & WNOHANG) || waitee_thread->state() == Thread::State::Stopped);
|
||||||
siginfo_t siginfo;
|
siginfo_t siginfo;
|
||||||
memset(&siginfo, 0, sizeof(siginfo));
|
memset(&siginfo, 0, sizeof(siginfo));
|
||||||
siginfo.si_signo = SIGCHLD;
|
siginfo.si_signo = SIGCHLD;
|
||||||
siginfo.si_pid = waitee_process->pid();
|
siginfo.si_pid = waitee_process->pid();
|
||||||
siginfo.si_uid = waitee_process->uid();
|
siginfo.si_uid = waitee_process->uid();
|
||||||
siginfo.si_code = CLD_STOPPED;
|
|
||||||
|
switch (waitee_thread->state()) {
|
||||||
|
case Thread::State::Stopped:
|
||||||
|
siginfo.si_code = CLD_STOPPED;
|
||||||
|
break;
|
||||||
|
case Thread::State::Running:
|
||||||
|
case Thread::State::Runnable:
|
||||||
|
case Thread::State::Blocked:
|
||||||
|
case Thread::State::Dying:
|
||||||
|
case Thread::State::Queued:
|
||||||
|
siginfo.si_code = CLD_CONTINUED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
siginfo.si_status = waitee_thread->m_stop_signal;
|
siginfo.si_status = waitee_thread->m_stop_signal;
|
||||||
return siginfo;
|
return siginfo;
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,8 @@ bool Thread::WaitBlocker::should_unblock(Thread& thread, time_t, long)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wait_finished = ((m_wait_options & WEXITED) && child_exited)
|
bool wait_finished = ((m_wait_options & WEXITED) && child_exited)
|
||||||
|| ((m_wait_options & WSTOPPED) && child_stopped);
|
|| ((m_wait_options & WSTOPPED) && child_stopped)
|
||||||
|
|| (m_wait_options & WNOHANG);
|
||||||
|
|
||||||
if (!wait_finished)
|
if (!wait_finished)
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
|
|
|
@ -72,6 +72,9 @@ pid_t waitpid(pid_t waitee, int* wstatus, int options)
|
||||||
case CLD_STOPPED:
|
case CLD_STOPPED:
|
||||||
*wstatus = siginfo.si_status << 8 | 0x7f;
|
*wstatus = siginfo.si_status << 8 | 0x7f;
|
||||||
break;
|
break;
|
||||||
|
case CLD_CONTINUED:
|
||||||
|
*wstatus = 0;
|
||||||
|
return 0; // return 0 if running
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue