%
A unix system creates a process though the <#2465#> fork()<#2465#> system call, and
process termination is performed either by <#2466#> exit()<#2466#> or by receiving
a signal. The \ implementation for them resides in
<#2467#> kernel/fork.c<#2467#> and <#2468#> kernel/exit.c<#2468#>.
Forking is easy, and <#2469#> fork.c<#2469#> is short and ready understandable. Its
main task is filling the data structure for the new process. Relevant
steps, apart from filling fields, are
- getting a free page to hold the <#2471#> task_struct<#2471#>
- finding an empty process slot (<#2472#> find_empty_process()<#2472#>)
- getting another free page for the <#2473#> kernel_stack_page<#2473#>
- copying the father's LDT to the child
- duplicating <#2474#> mmap<#2474#> information of the father
<#2476#> sys_fork()<#2476#> also manages file descriptors and inodes.
#tex2html_wrap2954#
Exiting from a process is trickier, because the parent process
must be notified about any child who exits. Moreover, a process can exit
by being <#2478#> kill()<#2478#>ed by another process (these are \ features).
The file <#2479#> exit.c<#2479#> is therefore the home of <#2480#> sys_kill()<#2480#> and the
various flavors of <#2481#> sys_wait()<#2481#>, in addition to <#2482#> sys_exit()<#2482#>.
The code belonging to <#2483#> exit.c<#2483#> is not described here---it is not that
interesting. It deals with a lot of details in order to
leave the system in a consistent state. The POSIX standard,
then, is quite demanding about signals, and it must be dealt with.