AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
proc.c File Reference

Processes: making them and ending them, their IDs, their descriptors, and their sessions and process groups. More...

#include <core/system.h>
#include <core/panic.h>
#include <core/string.h>
#include <core/arch.h>
#include <mm/pmap.h>
#include <mm/mm.h>
#include <mm/vm.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <fs/vfs.h>
#include <dev/tty.h>
#include <ds/queue.h>
#include <ds/bitmap.h>

Go to the source code of this file.

Functions

static int pid_is_group (int pid)
 Returns whether a process group or a session has pid as its ID.
int proc_pid_alloc ()
 Allocates a process ID, from 1 (init's) on.
void proc_pid_free (int pid)
 Frees a process ID.
int proc_new (struct proc **ref)
 Makes a new process structure, with one thread and an empty address space, on the list of every process.
struct proc * proc_pid_find (pid_t pid)
 Finds a process by its ID.
int proc_init (struct proc *proc)
 Gives a new process (init) its ID and its descriptor table.
int pgrp_orphaned (struct pgroup *pgrp, struct proc *gone)
 Says whether a process group is orphaned (POSIX): none of its members has a parent in another group of the same session, so no one there would continue it once it stops.
static void pgrp_orphaned_hangup (struct pgroup *pgrp, struct proc *gone)
 Sends SIGHUP and SIGCONT to a process group that gone leaving makes orphaned, if one of its members is stopped: nothing else would continue them.
static int pgrp_other_same_session (struct proc *p, struct proc *q)
 Returns whether p's process group is another group of the same session as q's.
static void proc_zombie_notify (struct proc *proc)
 Tells a zombie's parent that it ended: its wait() wakes up and it gets SIGCHLD.
int proc_threads_end (struct proc *proc, struct thread *keep, int exiting)
 Ends the threads of a process, but one.
void proc_threads_exec (struct proc *proc)
 Ends every thread of a process but the current one, for execve() (POSIX: they run in the program that is replaced).
void proc_kill (struct proc *proc)
 Ends a process: its threads end, its descriptors are closed, its memory is freed, its children go to init, and it becomes a zombie that its parent may wait for.
int proc_reap (struct proc *proc)
 Frees a zombie, once its parent waited for it (or doesn't wait for its children).
int proc_fd_get (struct proc *proc)
 Reserves the lowest free descriptor of a process, while a system call sets it up: no other thread takes it, and it doesn't refer to a file yet.
void proc_fd_release (struct proc *proc, int fd)
 Frees a reserved descriptor that wasn't set up after all.
void proc_fd_install (struct proc *proc, int fd, struct file *file, int flags)
 Makes a reserved descriptor refer to an open file.
struct file * proc_fd_file (struct proc *proc, int fd)
 Finds the open file a descriptor refers to.
int proc_fd_close (struct proc *proc, int fd)
 Closes a descriptor: it is free again, and its reference to the open file is dropped.
int session_new (struct proc *proc)
 Makes a new session, with a new process group, both led by a process and with its ID, and moves the process into it, as setsid() does.
int proc_setpgid (struct proc *proc, pid_t pgid)
 Moves a process into a process group of its session, as setpgid() does.
void pgrp_release (struct pgroup *pgrp)
 Frees a process group if no process is left in it, and its session if that was the session's last group.

Variables

struct queue * procs = QUEUE_NEW()
struct proc * initproc
struct queue * sessions = QUEUE_NEW()
struct bitmap * pid_bitmap = BITMAP_NEW(4096)
static int last_pid

Detailed Description

Processes: making them and ending them, their IDs, their descriptors, and their sessions and process groups.

A process that ends becomes a zombie: it keeps its ID and its exit status until its parent waits for it (proc_reap()). Its children go to init. Sessions and process groups follow POSIX's job control: a group that would be left stopped with no one to continue it (an orphaned group) gets SIGHUP and SIGCONT. See docs/kernel/processes.md.

Definition in file proc.c.

Function Documentation

◆ pgrp_orphaned()

int pgrp_orphaned ( struct pgroup * pgrp,
struct proc * gone )

Says whether a process group is orphaned (POSIX): none of its members has a parent in another group of the same session, so no one there would continue it once it stops.

Init doesn't count as such a parent, since it isn't a shell.

Parameters
pgrpthe process group
gonea process on its way out, which doesn't count as a member or a parent; or NULL
Returns
1 if it is orphaned, 0 if not

Definition at line 227 of file proc.c.

References initproc, proc::parent, proc::pgrp, pgrp_orphaned(), pgroup::procs, queue_for, pgroup::session, and proc::zombie.

Referenced by pgrp_orphaned(), pgrp_orphaned_hangup(), signal_take(), and tty_background().

◆ pgrp_orphaned_hangup()

void pgrp_orphaned_hangup ( struct pgroup * pgrp,
struct proc * gone )
static

Sends SIGHUP and SIGCONT to a process group that gone leaving makes orphaned, if one of its members is stopped: nothing else would continue them.

Definition at line 245 of file proc.c.

References proc::pgrp, pgrp_orphaned(), pgrp_orphaned_hangup(), pgroup::procs, queue_for, proc::running, signal_pgrp_send(), and proc::stopped.

Referenced by pgrp_orphaned_hangup(), and proc_kill().

◆ pgrp_other_same_session()

int pgrp_other_same_session ( struct proc * p,
struct proc * q )
static

Returns whether p's process group is another group of the same session as q's.

Definition at line 264 of file proc.c.

References proc::pgrp, pgrp_other_same_session(), and pgroup::session.

Referenced by pgrp_other_same_session(), and proc_kill().

◆ pgrp_release()

void pgrp_release ( struct pgroup * pgrp)

Frees a process group if no process is left in it, and its session if that was the session's last group.

A terminal whose foreground group or session it was loses it.

Parameters
pgrpthe process group

Definition at line 742 of file proc.c.

References queue::count, session::ctty, tty::fg, kfree(), NULL, session::pgps, pgrp_release(), pgroup::procs, pgroup::session, tty::session, and pgroup::session_node.

Referenced by pgrp_release(), proc_reap(), proc_setpgid(), and sys_setsid().

◆ pid_is_group()

int pid_is_group ( int pid)
static

Returns whether a process group or a session has pid as its ID.

Such an ID isn't given to a new process (POSIX), since groups and sessions outlive their leader.

Definition at line 56 of file proc.c.

References pgroup::pgid, session::pgps, pid_is_group(), queue_for, sessions, and session::sid.

Referenced by pid_is_group(), and proc_pid_alloc().

◆ proc_fd_close()

int proc_fd_close ( struct proc * proc,
int fd )

Closes a descriptor: it is free again, and its reference to the open file is dropped.

Dropping the last reference closes the file.

Parameters
procthe process
fdthe descriptor
Returns
what closing the file returned (0 or a negative errno), or -EBADF if the descriptor isn't open

Definition at line 578 of file proc.c.

References proc::fds, file_put(), proc_fd_close(), and proc_fd_file().

Referenced by proc_execve(), proc_fd_close(), proc_fork(), proc_kill(), sys_accept(), sys_close(), and sys_pipe().

◆ proc_fd_file()

struct file * proc_fd_file ( struct proc * proc,
int fd )

Finds the open file a descriptor refers to.

Parameters
procthe process
fdthe descriptor
Returns
the open file, or NULL if the descriptor is free, being set up, or out of range

Definition at line 560 of file proc.c.

References FD_RESERVED, proc::fds, FDS_COUNT, fd::file, NULL, and proc_fd_file().

Referenced by copy_fds(), fd_file(), fd_peek(), proc_execve(), proc_fd_close(), and proc_fd_file().

◆ proc_fd_get()

int proc_fd_get ( struct proc * proc)

Reserves the lowest free descriptor of a process, while a system call sets it up: no other thread takes it, and it doesn't refer to a file yet.

proc_fd_install() or proc_fd_release() ends the reservation.

Parameters
procthe process
Returns
the descriptor, or -1 if there is no free one

Definition at line 514 of file proc.c.

References FD_RESERVED, proc::fds, FDS_COUNT, fd::file, and proc_fd_get().

Referenced by do_openat(), proc_fd_get(), sys_accept(), sys_pipe(), and sys_socket().

◆ proc_fd_install()

void proc_fd_install ( struct proc * proc,
int fd,
struct file * file,
int flags )

Makes a reserved descriptor refer to an open file.

The caller's reference to the file becomes the descriptor's.

Parameters
procthe process
fdthe descriptor, reserved by proc_fd_get()
filethe open file
flagsthe descriptor's flags (FD_CLOEXEC)

Definition at line 547 of file proc.c.

References proc::fds, fd::file, fd::flags, file::flags, and proc_fd_install().

Referenced by do_openat(), proc_fd_install(), sys_accept(), sys_fcntl(), sys_pipe(), and sys_socket().

◆ proc_fd_release()

void proc_fd_release ( struct proc * proc,
int fd )

Frees a reserved descriptor that wasn't set up after all.

Parameters
procthe process
fdthe descriptor

Definition at line 532 of file proc.c.

References proc::fds, FDS_COUNT, and proc_fd_release().

Referenced by do_openat(), proc_fd_release(), sys_accept(), sys_pipe(), and sys_socket().

◆ proc_init()

int proc_init ( struct proc * proc)

Gives a new process (init) its ID and its descriptor table.

Parameters
procthe process
Returns
0, -EINVAL if proc is NULL, -EAGAIN if no ID is free, or -ENOMEM

Definition at line 197 of file proc.c.

References proc::fds, FDS_COUNT, kmalloc(), M_ZERO, proc::pid, proc_init(), proc_pid_alloc(), and proc_pid_free().

Referenced by proc_dump(), proc_init(), and sched_init_spawn().

◆ proc_kill()

void proc_kill ( struct proc * proc)

Ends a process: its threads end, its descriptors are closed, its memory is freed, its children go to init, and it becomes a zombie that its parent may wait for.

If the current thread is the process's, it doesn't return. Ending init restarts the machine.

Parameters
procthe process; its exit status is set already

Definition at line 375 of file proc.c.

References arch_cur_thread_kill(), arch_interrupts_disable(), arch_reboot(), session::ctty, curthread, proc::cwd, proc::exit, proc::fds, FDS_COUNT, queue::head, initproc, kfree(), kvm_space, session::leader, qnode::next, NULL, panic, proc::parent, proc::pgrp, pgrp_orphaned_hangup(), pgrp_other_same_session(), proc::pid, vm_space::pmap, pmap_decref(), printk(), proc_fd_close(), proc_kill(), proc_threads_end(), proc_zombie_notify(), procs, proc::running, sched_alarm(), pgroup::session, proc::sig_pending, thread_files_release(), proc::threads, tty_hangup(), qnode::value, vfs_close(), proc::vm_space, vm_space_destroy(), and proc::zombie.

Referenced by proc_execve(), proc_kill(), signal_exit(), and sys_exit().

◆ proc_new()

int proc_new ( struct proc ** ref)

Makes a new process structure, with one thread and an empty address space, on the list of every process.

It has no ID yet.

Parameters
refif not NULL, set to the new process
Returns
0, or -ENOMEM

Definition at line 114 of file proc.c.

References kfree(), kmalloc(), M_ZERO, NULL, vm_space::pmap, pmap_create(), pmap_decref(), proc_new(), procs, pmap::ref, proc::running, SIG_DFL, SIG_MAX, proc::sigaction, thread_new(), proc::threads, and proc::vm_space.

Referenced by kmain(), proc_fork(), and proc_new().

◆ proc_pid_alloc()

int proc_pid_alloc ( void )

Allocates a process ID, from 1 (init's) on.

Returns
the ID, or -1 if none is free

Definition at line 80 of file proc.c.

References last_pid, bitmap::max_idx, pid_bitmap, pid_is_group(), and proc_pid_alloc().

Referenced by proc_fork(), proc_init(), and proc_pid_alloc().

◆ proc_pid_find()

struct proc * proc_pid_find ( pid_t pid)

Finds a process by its ID.

Parameters
pidthe ID
Returns
the process (it may be a zombie), or NULL

Definition at line 179 of file proc.c.

References NULL, proc::pid, proc_pid_find(), procs, and queue_for.

Referenced by kernel_ctrlaltdel(), proc_alive(), proc_pid_find(), procfs_proc_maps(), procfs_proc_status(), procfs_proc_vmstats(), signal_send(), sys_setpgid(), and vt_signal().

◆ proc_pid_free()

void proc_pid_free ( int pid)

Frees a process ID.

Parameters
pidthe ID

Definition at line 102 of file proc.c.

References pid_bitmap, and proc_pid_free().

Referenced by proc_fork(), proc_init(), proc_pid_free(), and proc_reap().

◆ proc_reap()

int proc_reap ( struct proc * proc)

Frees a zombie, once its parent waited for it (or doesn't wait for its children).

Its CPU times are added to its parent's children's times.

Parameters
procthe zombie
Returns
0

Definition at line 484 of file proc.c.

References proc::cstime, proc::cutime, kfree(), proc::name, proc::parent, proc::pgrp, proc::pgrp_node, pgrp_release(), proc::pid, proc_pid_free(), proc_reap(), pgroup::procs, procs, proc::stime, and proc::utime.

Referenced by proc_reap(), proc_zombie_notify(), and sys_waitpid().

◆ proc_setpgid()

int proc_setpgid ( struct proc * proc,
pid_t pgid )

Moves a process into a process group of its session, as setpgid() does.

A group can only be joined if it exists and has members; a process can only start a new group with its own ID as the group's ID.

Parameters
procthe process
pgidthe group's ID
Returns
0, -EPERM if there is no such group and pgid isn't the process's ID, or -ENOMEM

Definition at line 667 of file proc.c.

References queue::count, kfree(), kmalloc(), pgroup::leader, M_ZERO, NULL, pgroup::pgid, session::pgps, proc::pgrp, proc::pgrp_node, pgrp_release(), proc::pid, proc_setpgid(), pgroup::procs, queue_for, pgroup::session, and pgroup::session_node.

Referenced by proc_setpgid(), and sys_setpgid().

◆ proc_threads_end()

int proc_threads_end ( struct proc * proc,
struct thread * keep,
int exiting )

Ends the threads of a process, but one.

A thread that isn't running is freed. One running on another CPU (in user mode, since this CPU has the kernel lock) is marked killed and made to enter the kernel now, where it frees itself.

Parameters
procthe process
keepthe thread to keep, or NULL
exitingwhether the process is ending: then the threads running elsewhere are detached from it at once; otherwise they leave its list when they go, and wake up proc->thread_join
Returns
how many threads were running on other CPUs

Definition at line 305 of file proc.c.

References queue::head, kfree(), thread::killed, NULL, thread::owner, proc_threads_end(), thread::run_link, sched_thread_cpu(), sched_thread_kick(), sched_timer_cancel(), thread::state, thread_files_release(), thread_kill(), proc::threads, thread::waitq, and ZOMBIE.

Referenced by proc_kill(), proc_threads_end(), and proc_threads_exec().

◆ proc_threads_exec()

void proc_threads_exec ( struct proc * proc)

Ends every thread of a process but the current one, for execve() (POSIX: they run in the program that is replaced).

It waits for the threads running on other CPUs to be gone.

Parameters
procthe process, which must be the current thread's

Definition at line 358 of file proc.c.

References curthread, proc_threads_end(), proc_threads_exec(), proc::thread_join, and waitq_sleep_unint().

Referenced by binfmt_fmt_load(), and proc_threads_exec().

◆ proc_zombie_notify()

void proc_zombie_notify ( struct proc * proc)
static

Tells a zombie's parent that it ended: its wait() wakes up and it gets SIGCHLD.

If the parent doesn't wait for its children (it ignores SIGCHLD, or set SA_NOCLDWAIT), the zombie is reaped at once.

Definition at line 272 of file proc.c.

References proc::parent, proc_reap(), proc_zombie_notify(), SIG_IGN, proc::sigaction, signal_proc_send(), proc::wait_queue, and waitq_wakeup().

Referenced by proc_kill(), and proc_zombie_notify().

◆ session_new()

int session_new ( struct proc * proc)

Makes a new session, with a new process group, both led by a process and with its ID, and moves the process into it, as setsid() does.

Parameters
procthe process
Returns
0, or -ENOMEM

Definition at line 596 of file proc.c.

References kfree(), kmalloc(), pgroup::leader, session::leader, M_ZERO, NULL, pgroup::pgid, session::pgps, proc::pgrp, proc::pgrp_node, proc::pid, pgroup::procs, pgroup::session, session_new(), pgroup::session_node, and session::sid.

Referenced by kproc_init(), sched_init_spawn(), session_new(), and sys_setsid().

Variable Documentation

◆ initproc

struct proc* initproc

Definition at line 39 of file proc.c.

Referenced by kmain(), pgrp_orphaned(), and proc_kill().

◆ last_pid

int last_pid
static

Definition at line 51 of file proc.c.

Referenced by proc_pid_alloc().

◆ pid_bitmap

struct bitmap* pid_bitmap = BITMAP_NEW(4096)

Definition at line 45 of file proc.c.

Referenced by proc_pid_alloc(), and proc_pid_free().

◆ procs

◆ sessions

struct queue* sessions = QUEUE_NEW()

Definition at line 42 of file proc.c.

Referenced by pid_is_group().