build-a-shell / lesson-26.md
Lesson 26 · Redirection

Redirecting builtins

Builtins run inside the shell, so redirecting them means temporarily rerouting the shell's own output and putting it back. Today you make redirection work for `pwd` and friends, closing out the redirection chapter.

The goal

Make redirection apply to builtins by saving and restoring the shell's own descriptors around the builtin call.

Start here - the target
TO DO
Scenario: Redirecting a builtin's output
Giventhe line: pwd > where.txt
Whenthe shell runs it
Thenwhere.txt contains the current directory followed by a newline
Anda following bare "pwd" prints to the screen again (the shell's output was restored)
Background

External commands redirect easily because each runs in its own child - you change the child’s descriptors and the shell is unaffected. Builtins are different: they run in the shell process, so redirecting pwd > file means redirecting the shell’s own standard output, running the builtin, and then carefully putting it back - otherwise every later prompt would write to that file too.

The pattern is save-redirect-restore. Before running the builtin, dup the real standard output to a spare descriptor to remember it; apply the redirections; run the builtin; then dup2 the saved descriptor back onto fd 1 and close the spare. It is the same discipline any code that temporarily borrows a global resource must follow. With this, redirection is uniform across builtins and external commands, and the chapter is complete.

Make it work
int saved = dup(1); // remember the real stdout
int fd = open("where.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
dup2(fd, 1); close(fd);
run_builtin(cmd); // its printf goes to the file
dup2(saved, 1); close(saved); // put stdout back
CheckpointDONE
Redirection works for builtins too. Chapter four is done - your shell redirects freely. Commit and stop here.