4.2.5 · D1Operating Systems

Foundations — Process creation — fork(), exec(), wait(), exit()

1,906 words9 min readBack to topic

Before you can read the parent note, you need to see what a process actually is, what a PID is, what "returning a value" means, and what those weird WIFEXITED-style words are made of. We build every one of these from nothing. Never skip ahead — each block below uses only words defined above it.


1. What is a process?

Look at the figure: the same recipe (program) can be cooked in two separate kitchens at once — those are two processes. They do not share bowls. What one stirs, the other never sees.

Figure — Process creation — fork(), exec(), wait(), exit()

Why the topic needs it. fork() literally builds a second identical kitchen. If you don't picture "a process = one private running instance," the phrase "the child is a duplicate of the parent" means nothing.

See Processes vs Threads for the neighbour idea (threads share the kitchen), and Process Control Block (PCB) for the exact record the OS keeps.


2. Parent and child

Why the topic needs it. wait() is "the parent pausing for its child." Orphans (parent died first) get re-adopted by init — see Zombie and Orphan Processes.


3. PID — the process's name tag

Picture a rack of numbered lockers. Each running process owns one locker; the number on the door is its PID. When a process dies, its locker eventually frees up for reuse.

Why the topic needs it.

  • fork() gives the parent back the child's PID so the parent can later say "wait for number 4123 specifically."
  • getpid() = "what's my number?", getppid() = "what's my parent's number?".

4. What "a function returns a value" means

Picture a vending machine: you press a button (call the function), a can drops out (the return value), you catch it in a box (the variable).

Figure — Process creation — fork(), exec(), wait(), exit()

Why the topic needs it. The entire fork() contract ( in child, child-PID in parent, on failure) is a story about return values. If "return value" is fuzzy, that contract is unreadable.


5. pid > 0, pid == 0, pid < 0 — reading the sign

The parent page hits you with three cases. They are just sign checks on the returned number.

Why the topic needs it. Every fork() program branches on these signs. >, ==, < are the whole navigation system.


6. Bits, bytes, and "the low 8 bits"

Picture 8 light switches in a row. Each is on/off. Every distinct on/off pattern is one number; there are exactly patterns, so the biggest is .

Figure — Process creation — fork(), exec(), wait(), exit()

Why the topic needs it. WEXITSTATUS(status) = status & 0xFF is exactly "throw away everything above the low byte." You can't read that line without knowing a byte is 8 bits.


7. The bit-mask & 0xFF

Why the topic needs it. This is the definition of WEXITSTATUS — extracting the child's exit code from a status word that also stores signal info in the higher bits.


8. The WIF... macros — words that expand into code

Why the topic needs it. After wait(&status), status is one packed integer holding how the child died. These macros are the only sane way to unpack it. They lean on everything above: bits, bytes, masking.


9. Memory: code, data, heap, stack


10. Prerequisite map

Process = running program

Parent and Child

Memory regions

PID number tag

Return value of a function

Sign cases 0, positive, -1

fork clone

Copy on Write

exec replace program

Bits and bytes

AND mask 0xFF

WIFEXITED WEXITSTATUS macros

wait and status

Process creation lifecycle


Equipment checklist

Cover the right side and answer out loud. If any line stumps you, re-read its section above before touching the parent note.

A running instance of a program with its own memory and open files
a process
The single root of the whole process tree, PID 1
init
The number that uniquely names a live process
its PID
Ask for your own PID vs your parent's PID
getpid() vs getppid()
The single answer a function hands back into a variable
the return value
fork() returns this in the child
0
fork() returns this in the parent
the child's PID (a positive number)
fork() returns this on failure
-1 (negative)
Number of bits in a byte, and the biggest value it holds
8 bits, max 255
Why exit(256) looks like exit(0) to the parent
only the low 8 bits survive; 256 = 1 0000 0000, low byte is 0
What status & 0xFF does
keeps the low 8 bits, erases the higher bits
Meaning of WIFEXITED(status)
true if the child ended normally via exit()
Meaning of WEXITSTATUS(status)
the exit code (low byte) the child passed to exit()
The four memory regions a fork copies
code, data, heap, stack

Ready? Head back to the parent topic (or its English twin) and every symbol there will now be one you've already met.