SwadhyAI Notes

All Operating Systems notes

Start here

On Unix, the classic story is fork then exec: clone process context, possibly run briefly in the child, then replace the memory image with a new program. Modern kernels optimize with clone, vfork (dangerous), and posix_spawn.

fork / exec (theory)

fork (or clone with flags) creates a child that duplicates much of the parent’s kernel view, often using copy-on-write mappings for efficiency. execve loads a new ELF, replaces the address space, resets signals, and preserves the PID unless you created a new task differently, while carefully deciding which file descriptors survive (CLOEXEC).

By the end of this page you should be able to

  1. Describe CoW at a high level after fork.
  2. List two things exec typically resets vs what may persist.
  3. Explain why locking across fork in a multithreaded parent is hazardous.

Operating systems · Processes

Process creation (fork, exec)

Unix composition for spawning

TL;DR

`fork()` clones the calling task (modern Linux uses `clone` with flags); `execve()` replaces the address space with a new program image. Between them, shells reshape fds (pipes, redirections) before the final exec, COW makes fork cheap until writes happen.

Summary

Fork/exec is the Unix answer to “create a new program with a fresh memory image but inherit selected state.” Understanding fd tables and signal disposition inheritance is essential for secure multi-process servers.

Diagram

Use this as the picture you would redraw from memory after closing the tab.
Diagram text: the exact Mermaid definition below preserves the nodes, labels, and connections. Enable JavaScript to view the rendered diagram.
Read the diagram definition
flowchart LR
  F[fork/clone] --> C[child runnable]
  F --> P[parent continues]
  C --> E[execve]
  E --> N[new image same PID]

Deeper narrative

`fork` duplicates task structures with CoW mappings; `execve` replaces the image while often preserving PID. POSIX `posix_spawn` wraps optimized paths (`vfork`+`exec` historically) to reduce latency and locking in multithreaded parents.

Mechanism (step by step)

Treat each step as a sentence in the story you tell on a whiteboard.
1

fork/clone

Duplicate PCB subset, share or copy files/mm per flags, enqueue child as runnable.

2

Copy-on-write

PTEs marked read-only shared; writes fault to duplicate private pages.

3

execve

Load new ELF, smash mm, reset signals, keep some fds unless CLOEXEC.

4

Interpreter chain

Shebang or binfmt_misc may spawn helper before target binary.

Key insights

Each card is a compression of the lesson, use them as spaced-repetition prompts.

Return twice

Kernel arranges divergent return values: child sees 0, parent sees child PID, same syscall site, different outcomes.

Copy-on-write

Private writable pages start shared read-only; first write faults duplicate the physical page.

Threads complicate fork

POSIX leaves which threads survive fork underspecified, libraries often restrict calling fork only when single-threaded.

Shebang and interpreters

Exec resolves the interpreter path; argv[0] conventions matter for ps output and behavior.

Did you know?

Trivia with teeth: the kind of fact that changes how you reason about a design.
`posix_spawn` can be implemented as `clone` + `exec` with less error-prone signal handling than raw `vfork`.
`CLOEXEC` prevents accidental fd leaks across exec, critical for security when spawning untrusted helpers.
The dynamic loader runs in user mode but is mapped by the kernel’s exec path decisions.

Common pitfalls

Where smart people still trip, read slowly.

Locks held across fork in multithreaded parent

Child gets undefined lock state, use `pthread_atfork` or `posix_spawn`.

Leaking fds

Default fds survive exec unless `O_CLOEXEC` set, security issue for privileged children.

Comparison

fork vs exec

forkexec
Creates new PIDYesNo
Loads new binaryNoYes
Typical next step in shellsdup2/pipe setupexec the target binary

Glossary

CoW

Copy-on-write, share physical pages until first write in a private mapping.

CLOEXEC

Close-on-exec flag preventing fd leakage across `execve`.

ASLR

Randomizes load addresses to harden memory corruption exploits.

Interview follow-ups

  1. Why is `vfork` dangerous and when is it still used?
  2. What does `exec` preserve from the old process?
  3. How does `clone` subsume `fork`?

Callouts

vfork caution

`vfork` suspends parent until exec, easy to deadlock if child misbehaves; avoid unless you truly know the platform contract.

Walkthrough & deep dive

Left: practical “how would I use this?” threads. Right: slower, code-leaning explanations, open one panel at a time so the page does not feel like a wall of sameness.

Walkthrough

Buffering puzzle

Explain output ordering when `printf` without newline happens before fork, stdio buffers live in user memory and get duplicated.

Deep dive

What is duplicated vs shared?

Address space mappings are duplicated logically with COW; file descriptor table entries are copied pointing at shared `struct file` unless CLOEXEC, offsets are shared unless separated.

Minimal spawn

c
pid_t p = fork();
if (p == 0) {
  execl("/bin/true", "true", (char *)NULL);
  _exit(127);
}
waitpid(p, NULL, 0);

Self-check

Misses here are cheap; misses in an interview are not. Treat wrong answers as a patch list for tomorrow.

1After successful exec, the program counter points to…

2COW mainly optimizes…

3CLOEXEC marks fds to…