linux-sysprog · advanced · ~30 min

Order of operations to daemonize a process

Memorize the conventional double-fork daemon recipe.

Challenge

Write out the canonical order of the steps a process performs to become a daemon. This is a pure-logic exercise: you fill an array with the step codes in the right sequence — no real forking happens.

Task

Implement int daemon_steps(int *out, int max) that writes the daemonization step codes, in order, into out.

Input

  • out, max: destination array and how many slots it has. The step codes are these fixed constants:
enum {
  STEP_FORK_1=1, STEP_SETSID=2, STEP_FORK_2=3, STEP_CHDIR_ROOT=4,
  STEP_UMASK_0=5, STEP_CLOSE_STDIN=6, STEP_REDIRECT_STDOUT_NULL=7,
  STEP_REDIRECT_STDERR_NULL=8
};

Output

Fills out with the 8 codes in canonical order (STEP_FORK_1, STEP_SETSID, STEP_FORK_2, STEP_CHDIR_ROOT, STEP_UMASK_0, STEP_CLOSE_STDIN, STEP_REDIRECT_STDOUT_NULL, STEP_REDIRECT_STDERR_NULL) and returns how many it wrote (at most max).

Example

daemon_steps(out, 8)   ->   8, out = [1,2,3,4,5,6,7,8]
daemon_steps(out, 3)   ->   3, out = [1,2,3]   (truncated to max)

Edge cases

  • If max is smaller than 8, write only the first max steps and return max.

Why this matters

Becoming a 'real' daemon requires a precise dance: fork twice, setsid, chdir /, umask 0, close fds, redirect stdio. Get the order wrong and your daemon leaks a controlling terminal or stays in the session group — both are pretty bad bugs.

Input format

An output array out and its capacity max. The 8 step codes are the fixed STEP_* enum constants (1..8).

Output format

Fills out with the step codes in canonical order; returns the count written (min of 8 and max).

Constraints

The sequence is exactly STEP_FORK_1, SETSID, FORK_2, CHDIR_ROOT, UMASK_0, CLOSE_STDIN, REDIRECT_STDOUT_NULL, REDIRECT_STDERR_NULL.

Starter code

enum {
  STEP_FORK_1=1, STEP_SETSID=2, STEP_FORK_2=3, STEP_CHDIR_ROOT=4,
  STEP_UMASK_0=5, STEP_CLOSE_STDIN=6, STEP_REDIRECT_STDOUT_NULL=7,
  STEP_REDIRECT_STDERR_NULL=8
};
int daemon_steps(int *out, int max) { /* TODO */ return 0; }

Common mistakes

setsid before the first fork (fails — the parent is process group leader); only forking once (your daemon can still acquire a controlling tty); chdir after closing fds (chdir is fine but order is conventional).

Edge cases to handle

max < 8 — return as many as fit.

Complexity

O(1).

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.