Kernel: PID/TID typing

This compiles, and contains exactly the same bugs as before.
The regex 'FIXME: PID/' should reveal all markers that I left behind, including:
- Incomplete conversion
- Issues or things that look fishy
- Actual bugs that will go wrong during runtime
This commit is contained in:
Ben Wiederhake 2020-08-08 17:32:34 +02:00 committed by Andreas Kling
parent f225321184
commit f5744a6f2f
Notes: sideshowbarker 2024-07-19 04:06:48 +09:00
26 changed files with 136 additions and 111 deletions

View File

@ -123,7 +123,7 @@ enum ProcFileType {
FI_MaxStaticFileIndex,
};
static inline pid_t to_pid(const InodeIdentifier& identifier)
static inline ProcessID to_pid(const InodeIdentifier& identifier)
{
#ifdef PROCFS_DEBUG
dbg() << "to_pid, index=" << String::format("%08x", identifier.index()) << " -> " << (identifier.index() >> 16);
@ -154,14 +154,14 @@ static inline size_t to_sys_index(const InodeIdentifier& identifier)
return identifier.index() >> 16u;
}
static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, pid_t pid, ProcFileType proc_file_type)
static inline InodeIdentifier to_identifier(unsigned fsid, ProcParentDirectory parent, ProcessID pid, ProcFileType proc_file_type)
{
return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid << 16u) | (unsigned)proc_file_type };
return { fsid, ((unsigned)parent << 12u) | ((unsigned)pid.value() << 16u) | (unsigned)proc_file_type };
}
static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, pid_t pid, int fd)
static inline InodeIdentifier to_identifier_with_fd(unsigned fsid, ProcessID pid, int fd)
{
return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid << 16u) | (FI_MaxStaticFileIndex + fd) };
return { fsid, (PDI_PID_fd << 12u) | ((unsigned)pid.value() << 16u) | (FI_MaxStaticFileIndex + fd) };
}
static inline InodeIdentifier sys_var_to_identifier(unsigned fsid, unsigned index)
@ -663,7 +663,7 @@ Optional<KBuffer> procfs$pid_root(InodeIdentifier identifier)
Optional<KBuffer> procfs$self(InodeIdentifier)
{
char buffer[16];
sprintf(buffer, "%u", Process::current()->pid());
sprintf(buffer, "%d", Process::current()->pid().value());
return KBuffer::copy((const u8*)buffer, strlen(buffer));
}
@ -821,13 +821,13 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
break;
}
process_object.add("pid", process.pid());
process_object.add("pid", process.pid().value());
process_object.add("pgid", process.tty() ? process.tty()->pgid() : 0);
process_object.add("pgp", process.pgid());
process_object.add("sid", process.sid());
process_object.add("uid", process.uid());
process_object.add("gid", process.gid());
process_object.add("ppid", process.ppid());
process_object.add("ppid", process.ppid().value());
process_object.add("nfds", process.number_of_open_file_descriptors());
process_object.add("name", process.name());
process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty");
@ -842,7 +842,7 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
auto thread_array = process_object.add_array("threads");
process.for_each_thread([&](const Thread& thread) {
auto thread_object = thread_array.add_object();
thread_object.add("tid", thread.tid());
thread_object.add("tid", thread.tid().value());
thread_object.add("name", thread.name());
thread_object.add("times_scheduled", thread.times_scheduled());
thread_object.add("ticks", thread.ticks());
@ -1227,7 +1227,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
}
for (auto pid_child : Process::all_pids()) {
char name[16];
size_t name_length = (size_t)sprintf(name, "%u", pid_child);
size_t name_length = (size_t)sprintf(name, "%d", pid_child.value());
callback({ name, name_length, to_identifier(fsid(), PDI_Root, pid_child, FI_PID), 0 });
}
break;
@ -1270,7 +1270,7 @@ KResult ProcFSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntr
if (!description)
continue;
char name[16];
size_t name_length = (size_t)sprintf(name, "%u", i);
size_t name_length = (size_t)sprintf(name, "%d", i);
callback({ name, name_length, to_identifier_with_fd(fsid(), pid, i), 0 });
}
} break;

View File

@ -56,7 +56,7 @@ Socket::Socket(int domain, int type, int protocol)
, m_protocol(protocol)
{
auto& process = *Process::current();
m_origin = { process.pid(), process.uid(), process.gid() };
m_origin = { process.pid().value(), process.uid(), process.gid() };
}
Socket::~Socket()
@ -83,7 +83,7 @@ RefPtr<Socket> Socket::accept()
auto client = m_pending.take_first();
ASSERT(!client->is_connected());
auto& process = *Process::current();
client->m_acceptor = { process.pid(), process.uid(), process.gid() };
client->m_acceptor = { process.pid().value(), process.uid(), process.gid() };
client->m_connected = true;
client->m_role = Role::Accepted;
return client;

View File

@ -94,12 +94,12 @@ PerformanceEvent& PerformanceEventBuffer::at(size_t index)
return events[index];
}
KBuffer PerformanceEventBuffer::to_json(pid_t pid, const String& executable_path) const
KBuffer PerformanceEventBuffer::to_json(ProcessID pid, const String& executable_path) const
{
KBufferBuilder builder;
JsonObjectSerializer object(builder);
object.add("pid", pid);
object.add("pid", pid.value());
object.add("executable", executable_path);
auto array = object.add_array("events");

View File

@ -68,7 +68,7 @@ public:
return const_cast<PerformanceEventBuffer&>(*this).at(index);
}
KBuffer to_json(pid_t, const String& executable_path) const;
KBuffer to_json(ProcessID, const String& executable_path) const;
private:
PerformanceEvent& at(size_t index);

View File

@ -95,8 +95,12 @@ Lock* g_hostname_lock;
VirtualAddress g_return_to_ring3_from_signal_trampoline;
HashMap<String, OwnPtr<Module>>* g_modules;
pid_t Process::allocate_pid()
ProcessID Process::allocate_pid()
{
// Overflow is UB, and negative PIDs wreck havoc.
// TODO: Handle PID overflow
// For example: Use an Atomic<u32>, mask the most significant bit,
// retry if PID is already taken as a PID, taken as a TID, or zero.
return next_pid.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel);
}
@ -112,9 +116,9 @@ void Process::initialize()
create_signal_trampolines();
}
Vector<pid_t> Process::all_pids()
Vector<ProcessID> Process::all_pids()
{
Vector<pid_t> pids;
Vector<ProcessID> pids;
ScopedSpinLock lock(g_processes_lock);
pids.ensure_capacity((int)g_processes->size_slow());
for (auto& process : *g_processes)
@ -286,7 +290,7 @@ void Process::kill_all_threads()
});
}
RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, pid_t parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String& path, uid_t uid, gid_t gid, ProcessID parent_pid, int& error, Vector<String>&& arguments, Vector<String>&& environment, TTY* tty)
{
auto parts = path.split('/');
if (arguments.is_empty()) {
@ -334,7 +338,7 @@ RefPtr<Process> Process::create_user_process(Thread*& first_thread, const String
NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, String&& name, void (*e)(), u32 affinity)
{
auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, (pid_t)0, Ring0));
auto process = adopt(*new Process(first_thread, move(name), (uid_t)0, (gid_t)0, ProcessID(0), Ring0));
first_thread->tss().eip = (FlatPtr)e;
if (process->pid() != 0) {
@ -348,7 +352,7 @@ NonnullRefPtr<Process> Process::create_kernel_process(Thread*& first_thread, Str
return process;
}
Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
Process::Process(Thread*& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, RingLevel ring, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
: m_name(move(name))
, m_pid(allocate_pid())
, m_euid(uid)
@ -473,10 +477,11 @@ void Process::crash(int signal, u32 eip, bool out_of_memory)
ASSERT_NOT_REACHED();
}
RefPtr<Process> Process::from_pid(pid_t pid)
RefPtr<Process> Process::from_pid(ProcessID pid)
{
ScopedSpinLock lock(g_processes_lock);
for (auto& process : *g_processes) {
process.pid();
if (process.pid() == pid)
return &process;
}
@ -553,7 +558,7 @@ siginfo_t Process::reap(Process& process)
siginfo_t siginfo;
memset(&siginfo, 0, sizeof(siginfo));
siginfo.si_signo = SIGCHLD;
siginfo.si_pid = process.pid();
siginfo.si_pid = process.pid().value();
siginfo.si_uid = process.uid();
if (process.m_termination_signal) {
@ -566,7 +571,7 @@ siginfo_t Process::reap(Process& process)
ASSERT(g_processes_lock.is_locked());
if (process.ppid()) {
if (!!process.ppid()) {
auto parent = Process::from_pid(process.ppid());
if (parent) {
parent->m_ticks_in_user_for_dead_children += process.m_ticks_in_user + process.m_ticks_in_user_for_dead_children;
@ -654,7 +659,8 @@ void Process::finalize()
disown_all_shared_buffers();
{
InterruptDisabler disabler;
if (auto* parent_thread = Thread::from_tid(m_ppid)) {
// FIXME: PID/TID BUG
if (auto* parent_thread = Thread::from_tid(m_ppid.value())) {
if (parent_thread->m_signal_action_data[SIGCHLD].flags & SA_NOCLDWAIT) {
// NOTE: If the parent doesn't care about this process, let it go.
m_ppid = 0;
@ -783,7 +789,8 @@ void Process::terminate_due_to_signal(u8 signal)
KResult Process::send_signal(u8 signal, Process* sender)
{
InterruptDisabler disabler;
if (auto* thread = Thread::from_tid(m_pid)) {
// FIXME: PID/TID BUG
if (auto* thread = Thread::from_tid(m_pid.value())) {
thread->send_signal(signal, sender);
return KSuccess;
}

View File

@ -126,10 +126,10 @@ public:
}
static NonnullRefPtr<Process> create_kernel_process(Thread*& first_thread, String&& name, void (*entry)(), u32 affinity = THREAD_AFFINITY_DEFAULT);
static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, pid_t ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
static RefPtr<Process> create_user_process(Thread*& first_thread, const String& path, uid_t, gid_t, ProcessID ppid, int& error, Vector<String>&& arguments = Vector<String>(), Vector<String>&& environment = Vector<String>(), TTY* = nullptr);
~Process();
static Vector<pid_t> all_pids();
static Vector<ProcessID> all_pids();
static AK::NonnullRefPtrVector<Process> all_processes();
Thread* create_kernel_thread(void (*entry)(), u32 priority, const String& name, u32 affinity = THREAD_AFFINITY_DEFAULT, bool joinable = true);
@ -152,10 +152,10 @@ public:
PageDirectory& page_directory() { return *m_page_directory; }
const PageDirectory& page_directory() const { return *m_page_directory; }
static RefPtr<Process> from_pid(pid_t);
static RefPtr<Process> from_pid(ProcessID);
const String& name() const { return m_name; }
pid_t pid() const { return m_pid; }
ProcessID pid() const { return m_pid; }
pid_t sid() const { return m_sid; }
pid_t pgid() const { return m_pgid; }
const FixedArray<gid_t>& extra_gids() const { return m_extra_gids; }
@ -165,9 +165,9 @@ public:
gid_t gid() const { return m_gid; }
uid_t suid() const { return m_suid; }
gid_t sgid() const { return m_sgid; }
pid_t ppid() const { return m_ppid; }
ProcessID ppid() const { return m_ppid; }
pid_t exec_tid() const { return m_exec_tid; }
ThreadID exec_tid() const { return m_exec_tid; }
mode_t umask() const { return m_umask; }
@ -224,7 +224,7 @@ public:
int sys$fstat(int fd, stat*);
int sys$stat(Userspace<const Syscall::SC_stat_params*>);
int sys$lseek(int fd, off_t, int whence);
int sys$kill(pid_t pid, int sig);
int sys$kill(pid_t pid_or_pgid, int sig);
[[noreturn]] void sys$exit(int status);
int sys$sigreturn(RegisterState& registers);
pid_t sys$waitid(Userspace<const Syscall::SC_waitid_params*>);
@ -263,7 +263,7 @@ public:
int sys$getgroups(ssize_t, gid_t*);
int sys$setgroups(ssize_t, const gid_t*);
int sys$pipe(int pipefd[2], int flags);
int sys$killpg(int pgrp, int sig);
int sys$killpg(pid_t pgrp, int sig);
int sys$seteuid(uid_t);
int sys$setegid(gid_t);
int sys$setuid(uid_t);
@ -338,7 +338,7 @@ public:
int sys$sendfd(int sockfd, int fd);
int sys$recvfd(int sockfd);
long sys$sysconf(int name);
int sys$disown(pid_t);
int sys$disown(ProcessID);
template<bool sockname, typename Params>
int get_sock_or_peer_name(const Params&);
@ -574,8 +574,8 @@ private:
friend class Scheduler;
friend class Region;
Process(Thread*& first_thread, const String& name, uid_t, gid_t, pid_t ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
static pid_t allocate_pid();
Process(Thread*& first_thread, const String& name, uid_t, gid_t, ProcessID ppid, RingLevel, RefPtr<Custody> cwd = nullptr, RefPtr<Custody> executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr);
static ProcessID allocate_pid();
Range allocate_range(VirtualAddress, size_t, size_t alignment = PAGE_SIZE);
@ -607,7 +607,7 @@ private:
}
KResultOr<String> get_syscall_path_argument(const Syscall::StringArgument&) const;
bool has_tracee_thread(int tracer_pid) const;
bool has_tracee_thread(ProcessID tracer_pid) const;
RefPtr<PageDirectory> m_page_directory;
@ -616,7 +616,7 @@ private:
String m_name;
pid_t m_pid { 0 };
ProcessID m_pid { 0 };
pid_t m_sid { 0 };
pid_t m_pgid { 0 };
@ -627,7 +627,7 @@ private:
uid_t m_suid { 0 };
gid_t m_sgid { 0 };
pid_t m_exec_tid { 0 };
ThreadID m_exec_tid { 0 };
FlatPtr m_load_offset { 0U };
FlatPtr m_entry_eip { 0U };
@ -677,7 +677,7 @@ private:
};
RegionLookupCache m_region_lookup_cache;
pid_t m_ppid { 0 };
ProcessID m_ppid { 0 };
mode_t m_umask { 022 };
FixedArray<gid_t> m_extra_gids;
@ -732,11 +732,12 @@ template<typename Callback>
inline void Process::for_each_child(Callback callback)
{
ASSERT_INTERRUPTS_DISABLED();
pid_t my_pid = pid();
ProcessID my_pid = pid();
ScopedSpinLock lock(g_processes_lock);
for (auto* process = g_processes->head(); process;) {
auto* next_process = process->next();
if (process->ppid() == my_pid || process->has_tracee_thread(m_pid)) {
// FIXME: PID/TID BUG
if (process->ppid() == my_pid || process->has_tracee_thread(m_pid.value())) {
if (callback(*process) == IterationDecision::Break)
break;
}
@ -748,7 +749,7 @@ template<typename Callback>
inline void Process::for_each_thread(Callback callback) const
{
InterruptDisabler disabler;
pid_t my_pid = pid();
ProcessID my_pid = pid();
if (my_pid == 0) {
// NOTE: Special case the colonel process, since its main thread is not in the global thread table.
@ -800,14 +801,14 @@ inline bool InodeMetadata::may_execute(const Process& process) const
return may_execute(process.euid(), process.egid(), process.extra_gids());
}
inline int Thread::pid() const
inline ProcessID Thread::pid() const
{
return m_process->pid();
}
inline const LogStream& operator<<(const LogStream& stream, const Process& process)
{
return stream << process.name() << '(' << process.pid() << ')';
return stream << process.name() << '(' << process.pid().value() << ')';
}
inline u32 Thread::effective_priority() const

View File

@ -61,7 +61,7 @@ void start(Process& process)
executable_path() = process.executable()->absolute_path().impl();
else
executable_path() = {};
s_pid = process.pid();
s_pid = process.pid().value(); // FIXME: PID/TID INCOMPLETE
if (!s_profiling_buffer) {
s_profiling_buffer = RefPtr<KBufferImpl>(KBuffer::create_with_size(8 * MB).impl()).leak_ref();

View File

@ -43,7 +43,7 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
return KSuccess;
}
if (params.pid == caller.pid())
if (params.pid == caller.pid().value())
return KResult(-EINVAL);
Thread* peer = nullptr;

View File

@ -136,7 +136,7 @@ Thread::WriteBlocker::WriteBlocker(const FileDescription& description)
timespec* Thread::WriteBlocker::override_timeout(timespec* timeout)
{
auto& description = blocked_description();
auto& description = blocked_description();
if (description.is_socket()) {
auto& socket = *description.socket();
if (socket.has_send_timeout()) {
@ -227,7 +227,7 @@ bool Thread::SelectBlocker::should_unblock(Thread& thread)
return false;
}
Thread::WaitBlocker::WaitBlocker(int wait_options, pid_t& waitee_pid)
Thread::WaitBlocker::WaitBlocker(int wait_options, ProcessID& waitee_pid)
: m_wait_options(wait_options)
, m_waitee_pid(waitee_pid)
{
@ -296,8 +296,7 @@ void Thread::consider_unblock(time_t now_sec, long now_usec)
case Thread::Dying:
/* don't know, don't care */
return;
case Thread::Blocked:
{
case Thread::Blocked: {
ASSERT(m_blocker != nullptr);
timespec now;
now.tv_sec = now_sec,
@ -378,7 +377,7 @@ bool Scheduler::pick_next()
auto name = process.name();
auto pid = process.pid();
auto exit_status = Process::reap(process);
dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid << "), exit status: " << exit_status.si_status;
dbg() << "Scheduler[" << Processor::current().id() << "]: Reaped unparented process " << name << "(" << pid.value() << "), exit status: " << exit_status.si_status;
}
return IterationDecision::Continue;
}
@ -496,7 +495,7 @@ bool Scheduler::yield()
bool Scheduler::donate_to(Thread* beneficiary, const char* reason)
{
ASSERT(beneficiary);
// Set the m_in_scheduler flag before acquiring the spinlock. This
// prevents a recursive call into Scheduler::invoke_async upon
// leaving the scheduler lock.
@ -685,8 +684,9 @@ void Scheduler::timer_tick(const RegisterState& regs)
SmapDisabler disabler;
auto backtrace = current_thread->raw_backtrace(regs.ebp, regs.eip);
auto& sample = Profiling::next_sample_slot();
sample.pid = current_thread->process().pid();
sample.tid = current_thread->tid();
// FIXME: PID/TID INCOMPLETE
sample.pid = current_thread->process().pid().value();
sample.tid = current_thread->tid().value();
sample.timestamp = g_uptime;
for (size_t i = 0; i < min(backtrace.size(), Profiling::max_stack_frame_count); ++i) {
sample.frames[i] = backtrace[i];

View File

@ -48,13 +48,13 @@ void SharedBuffer::sanity_check(const char* what)
if (found_refs != m_total_refs) {
dbg() << what << " sanity -- SharedBuffer{" << this << "} id: " << m_shbuf_id << " has total refs " << m_total_refs << " but we found " << found_refs;
for (const auto& ref : m_refs) {
dbg() << " ref from pid " << ref.pid << ": refcnt " << ref.count;
dbg() << " ref from pid " << ref.pid.value() << ": refcnt " << ref.count;
}
ASSERT_NOT_REACHED();
}
}
bool SharedBuffer::is_shared_with(pid_t peer_pid) const
bool SharedBuffer::is_shared_with(ProcessID peer_pid) const
{
LOCKER(shared_buffers().lock(), Lock::Mode::Shared);
if (m_global)
@ -102,7 +102,7 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process)
ASSERT_NOT_REACHED();
}
void SharedBuffer::share_with(pid_t peer_pid)
void SharedBuffer::share_with(ProcessID peer_pid)
{
LOCKER(shared_buffers().lock());
if (m_global)
@ -146,7 +146,7 @@ void SharedBuffer::deref_for_process(Process& process)
ASSERT_NOT_REACHED();
}
void SharedBuffer::disown(pid_t pid)
void SharedBuffer::disown(ProcessID pid)
{
LOCKER(shared_buffers().lock());
for (size_t i = 0; i < m_refs.size(); ++i) {

View File

@ -36,12 +36,12 @@ namespace Kernel {
class SharedBuffer {
private:
struct Reference {
Reference(pid_t pid)
Reference(ProcessID pid)
: pid(pid)
{
}
pid_t pid;
ProcessID pid;
unsigned count { 0 };
WeakPtr<Region> region;
};
@ -64,12 +64,12 @@ public:
}
void sanity_check(const char* what);
bool is_shared_with(pid_t peer_pid) const;
bool is_shared_with(ProcessID peer_pid) const;
void* ref_for_process_and_get_address(Process& process);
void share_with(pid_t peer_pid);
void share_with(ProcessID peer_pid);
void share_globally() { m_global = true; }
void deref_for_process(Process& process);
void disown(pid_t pid);
void disown(ProcessID pid);
size_t size() const { return m_vmobject->size(); }
void destroy_if_unused();
void seal();

View File

@ -28,7 +28,7 @@
namespace Kernel {
int Process::sys$disown(pid_t pid)
int Process::sys$disown(ProcessID pid)
{
REQUIRE_PROMISE(proc);
auto process = Process::from_pid(pid);

View File

@ -282,7 +282,8 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
m_master_tls_size = master_tls_size;
m_master_tls_alignment = master_tls_alignment;
m_pid = new_main_thread->tid();
// FIXME: PID/TID BUG
m_pid = new_main_thread->tid().value();
new_main_thread->make_thread_specific_region({});
new_main_thread->reset_fpu_state();
@ -296,7 +297,7 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
tss.eip = m_entry_eip;
tss.esp = new_userspace_esp;
tss.cr3 = m_page_directory->cr3();
tss.ss2 = m_pid;
tss.ss2 = m_pid.value();
if (was_profiling)
Profiling::did_exec(path);

View File

@ -95,7 +95,7 @@ pid_t Process::sys$fork(RegisterState& regs)
}
child_first_thread->set_state(Thread::State::Skip1SchedulerPass);
return child->pid();
return child->pid().value();
}
}

View File

@ -35,7 +35,7 @@ KResult Process::do_kill(Process& process, int signal)
if (!is_superuser() && m_euid != process.m_uid && m_uid != process.m_uid)
return KResult(-EPERM);
if (process.is_ring0() && signal == SIGKILL) {
klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid() << ")";
klog() << "attempted to send SIGKILL to ring 0 process " << process.name().characters() << "(" << process.pid().value() << ")";
return KResult(-EPERM);
}
if (signal != 0)
@ -119,33 +119,34 @@ KResult Process::do_killself(int signal)
return KSuccess;
}
int Process::sys$kill(pid_t pid, int signal)
int Process::sys$kill(pid_t pid_or_pgid, int signal)
{
if (pid == m_pid)
if (pid_or_pgid == m_pid.value())
REQUIRE_PROMISE(stdio);
else
REQUIRE_PROMISE(proc);
if (signal < 0 || signal >= 32)
return -EINVAL;
if (pid < -1) {
if (pid == NumericLimits<i32>::min())
if (pid_or_pgid < -1) {
if (pid_or_pgid == NumericLimits<i32>::min())
return -EINVAL;
return do_killpg(-pid, signal);
return do_killpg(-pid_or_pgid, signal);
}
if (pid == -1)
if (pid_or_pgid == -1)
return do_killall(signal);
if (pid == m_pid) {
if (pid_or_pgid == m_pid.value()) {
return do_killself(signal);
}
ASSERT(pid_or_pgid >= 0);
ScopedSpinLock lock(g_processes_lock);
auto peer = Process::from_pid(pid);
auto peer = Process::from_pid(pid_or_pgid);
if (!peer)
return -ESRCH;
return do_kill(*peer, signal);
}
int Process::sys$killpg(int pgrp, int signum)
int Process::sys$killpg(pid_t pgrp, int signum)
{
REQUIRE_PROMISE(proc);
if (signum < 1 || signum >= 32)

View File

@ -32,13 +32,13 @@ namespace Kernel {
pid_t Process::sys$getpid()
{
REQUIRE_PROMISE(stdio);
return m_pid;
return m_pid.value();
}
pid_t Process::sys$getppid()
{
REQUIRE_PROMISE(stdio);
return m_ppid;
return m_ppid.value();
}
int Process::sys$set_process_icon(int icon_id)

View File

@ -44,7 +44,10 @@ int Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> user_params)
return result.is_error() ? result.error() : result.value();
}
bool Process::has_tracee_thread(int tracer_pid) const
/**
* "Does this process have a thread that is currently being traced by the provided process?"
*/
bool Process::has_tracee_thread(ProcessID tracer_pid) const
{
bool has_tracee = false;

View File

@ -48,14 +48,15 @@ pid_t Process::sys$setsid()
REQUIRE_PROMISE(proc);
InterruptDisabler disabler;
bool found_process_with_same_pgid_as_my_pid = false;
Process::for_each_in_pgrp(pid(), [&](auto&) {
// FIXME: PID/PGID ISSUE?
Process::for_each_in_pgrp(pid().value(), [&](auto&) {
found_process_with_same_pgid_as_my_pid = true;
return IterationDecision::Break;
});
if (found_process_with_same_pgid_as_my_pid)
return -EPERM;
m_sid = m_pid;
m_pgid = m_pid;
m_sid = m_pid.value();
m_pgid = m_pid.value();
m_tty = nullptr;
return m_sid;
}
@ -91,7 +92,7 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
{
REQUIRE_PROMISE(proc);
ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle
pid_t pid = specified_pid ? specified_pid : m_pid;
ProcessID pid = specified_pid ? ProcessID(specified_pid) : m_pid;
if (specified_pgid < 0) {
// The value of the pgid argument is less than 0, or is not a value supported by the implementation.
return -EINVAL;
@ -115,7 +116,8 @@ int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
return -EPERM;
}
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
// FIXME: PID/PGID INCOMPLETE
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid.value();
pid_t current_sid = get_sid_from_pgid(process->m_pgid);
pid_t new_sid = get_sid_from_pgid(new_pgid);
if (current_sid != new_sid) {

View File

@ -70,7 +70,7 @@ int Process::sys$shbuf_create(int size, void** buffer)
int Process::sys$shbuf_allow_pid(int shbuf_id, pid_t peer_pid)
{
REQUIRE_PROMISE(shared_buffer);
if (!peer_pid || peer_pid < 0 || peer_pid == m_pid)
if (!peer_pid || peer_pid < 0 || ProcessID(peer_pid) == m_pid)
return -EINVAL;
LOCKER(shared_buffers().lock());
auto it = shared_buffers().resource().find(shbuf_id);

View File

@ -87,7 +87,7 @@ int Process::sys$create_thread(void* (*entry)(void*), Userspace<const Syscall::S
thread->make_thread_specific_region({});
thread->set_state(Thread::State::Runnable);
return thread->tid();
return thread->tid().value();
}
void Process::sys$exit_thread(void* exit_value)
@ -212,7 +212,7 @@ int Process::sys$get_thread_name(int tid, char* buffer, size_t buffer_size)
int Process::sys$gettid()
{
REQUIRE_PROMISE(stdio);
return Thread::current()->tid();
return Thread::current()->tid().value();
}
}

View File

@ -34,9 +34,12 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
ScopedSpinLock lock(g_processes_lock);
if (idtype == P_PID && !Process::from_pid(id))
return KResult(-ECHILD);
// FIXME: Race: After 'lock' releases, the 'id' process might vanish.
// If that is not a problem, why check for it?
// If it is a problem, let's fix it! (Eventually.)
}
pid_t waitee_pid;
ProcessID waitee_pid { 0 };
// FIXME: WaitBlocker should support idtype/id specs directly.
if (idtype == P_ALL) {
@ -62,14 +65,15 @@ KResultOr<siginfo_t> Process::do_waitid(idtype_t idtype, int id, int options)
if (waitee_process->is_dead()) {
return reap(*waitee_process);
} else {
auto* waitee_thread = Thread::from_tid(waitee_pid);
// FIXME: PID/TID BUG
auto* waitee_thread = Thread::from_tid(waitee_pid.value());
if (!waitee_thread)
return KResult(-ECHILD);
ASSERT((options & WNOHANG) || waitee_thread->state() == Thread::State::Stopped);
siginfo_t siginfo;
memset(&siginfo, 0, sizeof(siginfo));
siginfo.si_signo = SIGCHLD;
siginfo.si_pid = waitee_process->pid();
siginfo.si_pid = waitee_process->pid().value();
siginfo.si_uid = waitee_process->uid();
switch (waitee_thread->state()) {

View File

@ -52,9 +52,10 @@ Thread::Thread(NonnullRefPtr<Process> process)
{
if (m_process->m_thread_count.fetch_add(1, AK::MemoryOrder::memory_order_acq_rel) == 0) {
// First thread gets TID == PID
m_tid = m_process->pid();
m_tid = m_process->pid().value();
} else {
m_tid = Process::allocate_pid();
// TODO: Use separate counter?
m_tid = Process::allocate_pid().value();
}
#ifdef THREAD_DEBUG
dbg() << "Created new thread " << m_process->name() << "(" << m_process->pid() << ":" << m_tid << ")";
@ -721,7 +722,6 @@ void Thread::set_state(State new_state)
m_wait_queue->dequeue(*this);
m_wait_queue = nullptr;
}
if (this != Thread::current() && is_finalizable()) {
// Some other thread set this thread to Dying, notify the
@ -859,7 +859,7 @@ void Thread::make_thread_specific_region(Badge<Process>)
const LogStream& operator<<(const LogStream& stream, const Thread& value)
{
return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")";
return stream << value.process().name() << "(" << value.pid().value() << ":" << value.tid().value() << ")";
}
Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeval* timeout, Atomic<bool>* lock, Thread* beneficiary)
@ -982,7 +982,7 @@ void Thread::reset_fpu_state()
memcpy(m_fpu_state, &Processor::current().clean_fpu_state(), sizeof(FPUState));
}
void Thread::start_tracing_from(pid_t tracer)
void Thread::start_tracing_from(ProcessID tracer)
{
m_tracer = ThreadTracer::create(tracer);
}

View File

@ -82,11 +82,11 @@ public:
explicit Thread(NonnullRefPtr<Process>);
~Thread();
static Thread* from_tid(int);
static Thread* from_tid(pid_t);
static void finalize_dying_threads();
int tid() const { return m_tid; }
int pid() const;
ThreadID tid() const { return m_tid; }
ProcessID pid() const;
void set_priority(u32 p) { m_priority = p; }
u32 priority() const { return m_priority; }
@ -236,13 +236,13 @@ public:
class WaitBlocker final : public Blocker {
public:
WaitBlocker(int wait_options, pid_t& waitee_pid);
WaitBlocker(int wait_options, ProcessID& waitee_pid);
virtual bool should_unblock(Thread&) override;
virtual const char* state_string() const override { return "Waiting"; }
private:
int m_wait_options { 0 };
pid_t& m_waitee_pid;
ProcessID& m_waitee_pid;
};
class SemiPermanentBlocker final : public Blocker {
@ -512,7 +512,7 @@ public:
static constexpr u32 default_userspace_stack_size = 4 * MB;
ThreadTracer* tracer() { return m_tracer.ptr(); }
void start_tracing_from(pid_t tracer);
void start_tracing_from(ProcessID tracer);
void stop_tracing();
void tracer_trap(const RegisterState&);
@ -533,7 +533,7 @@ private:
mutable RecursiveSpinLock m_lock;
NonnullRefPtr<Process> m_process;
int m_tid { -1 };
ThreadID m_tid { -1 };
TSS32 m_tss;
Atomic<u32> m_cpu { 0 };
u32 m_cpu_affinity { THREAD_AFFINITY_DEFAULT };

View File

@ -32,7 +32,7 @@
namespace Kernel {
ThreadTracer::ThreadTracer(pid_t tracer_pid)
ThreadTracer::ThreadTracer(ProcessID tracer_pid)
: m_tracer_pid(tracer_pid)
{
}

View File

@ -35,9 +35,9 @@ namespace Kernel {
class ThreadTracer {
public:
static NonnullOwnPtr<ThreadTracer> create(pid_t tracer) { return make<ThreadTracer>(tracer); }
static NonnullOwnPtr<ThreadTracer> create(ProcessID tracer) { return make<ThreadTracer>(tracer); }
pid_t tracer_pid() const { return m_tracer_pid; }
ProcessID tracer_pid() const { return m_tracer_pid; }
bool has_pending_signal(u32 signal) const { return m_pending_signals & (1 << (signal - 1)); }
void set_signal(u32 signal) { m_pending_signals |= (1 << (signal - 1)); }
void unset_signal(u32 signal) { m_pending_signals &= ~(1 << (signal - 1)); }
@ -54,10 +54,10 @@ public:
return m_regs.value();
}
explicit ThreadTracer(pid_t);
explicit ThreadTracer(ProcessID);
private:
pid_t m_tracer_pid { -1 };
ProcessID m_tracer_pid { -1 };
// This is a bitmap for signals that are sent from the tracer to the tracee
// TODO: Since we do not currently support sending signals

View File

@ -26,6 +26,7 @@
#pragma once
#include <AK/DistinctNumeric.h>
#include <AK/Types.h>
#define O_RDONLY (1 << 0)
@ -320,6 +321,11 @@ typedef u32 gid_t;
typedef u32 clock_t;
typedef u32 socklen_t;
typedef int pid_t;
// Avoid interference with AK/Types.h and LibC/sys/types.h by defining *separate* names:
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessID);
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ThreadID);
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, SessionID);
TYPEDEF_DISTINCT_ORDERED_ID(pid_t, ProcessGroupID);
struct tms {
clock_t tms_utime;