Skip to content

Commit 1ff5d29

Browse files
aryxclaude
andcommitted
docs: add rfork/env explanations, fix table ordering in Shell.nw
Add export/isolation explanation to rfork section, footnote in Intro.nw linking to it, exec builtin explanation, initialization chapter row in code organization table, reorder table rows to match chapter order. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 094c8fb commit 1ff5d29

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

shells/Intro.nw

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,12 @@ basic command interpreter, not a full scripting language like [[rc]].
211211
\l if/goto (and glob) were external programs
212212

213213
%claude:
214-
The small size of Ken Thompson's shell reflects the \unix philosophy
215-
of keeping the shell minimal: [[if]] and [[goto]] were separate
216-
programs (not builtins), and wildcard expansion was handled by
217-
an external [[glob]] program. This made the shell itself trivial
218-
at the cost of some awkwardness---for example, you could not
219-
write a loop without creating a script file for [[goto]] to jump into.
214+
%The small size of Ken Thompson's shell reflects the \unix philosophy
215+
%of keeping the shell minimal: [[if]] and [[goto]] were separate
216+
%programs (not builtins), and wildcard expansion was handled by
217+
%an external [[glob]] program. This made the shell itself trivial
218+
%at the cost of some awkwardness---for example, you could not
219+
%write a loop without creating a script file for [[goto]] to jump into.
220220

221221
%history:
222222
\item The Bourne shell~\cite{sh}, also called [[sh]], superseded
@@ -261,14 +261,14 @@ as in [[rc]], but instead a complex recursive descent parser.
261261
\l design of sh by bourne: https://www.youtube.com/watch?v=2kEJoWfobpA
262262

263263
%claude:
264-
Part of the difficulty comes from the source code itself: Bourne
265-
wrote extensive C macros to make the code look like Algol
266-
([[IF]], [[THEN]], [[BEGIN]], [[END]], etc.), which allegedly
267-
inspired the International Obfuscated C Code Contest.
268-
More fundamentally, the Bourne shell has no formal grammar---Tom Duff
269-
once remarked that ``nobody knows the grammar of [[sh]]''---so
270-
the parser is full of special cases and context-dependent
271-
disambiguation that make it hard to reason about.
264+
%Part of the difficulty comes from the source code itself: Bourne
265+
%wrote extensive C macros to make the code look like Algol
266+
%([[IF]], [[THEN]], [[BEGIN]], [[END]], etc.), which allegedly
267+
%inspired the International Obfuscated C Code Contest.
268+
%More fundamentally, the Bourne shell has no formal grammar---Tom Duff
269+
%once remarked that ``nobody knows the grammar of [[sh]]''---so
270+
%the parser is full of special cases and context-dependent
271+
%disambiguation that make it hard to reason about.
272272

273273
%\item C shell lots of interactive features.
274274
%\item Korn shell lots of interactive features.
@@ -1263,7 +1263,10 @@ variable stringification, see Section~\ref{sec:quoting}).
12631263
%claude:
12641264
The [[boot.rc]] script also assigns [[objtype=arm]].
12651265
This is not just a local shell variable: in \plan, all shell
1266-
variables are automatically exported to the environment.
1266+
variables are automatically exported to the environment---there
1267+
is no need for an [[export]] command like in [[bash]]%
1268+
\footnote{If you need environment isolation, [[rfork e]] creates
1269+
a private copy of [[/env/]]; see Section~\ref{sec:rfork}.}.
12671270
When [[mk]] (the build tool) is later run from this shell,
12681271
it inherits [[$objtype]] and uses it to select the correct
12691272
compiler and assembler (e.g., [[5c]], [[5a]], [[5l]] for ARM).
@@ -1303,6 +1306,10 @@ would be unaffected.
13031306
The [[exec]] builtin replaces the current shell process
13041307
with the specified command. Here it replaces the boot
13051308
shell with an interactive instance of [[rc]] (the [[-i]] flag).
1309+
Without [[exec]], the boot shell would fork a child [[rc]],
1310+
wait for it to finish, and then continue---but there is
1311+
nothing left to do, so the extra process would just waste
1312+
a process slot until the interactive shell exits.
13061313
See Chapter~\ref{chap:builtins} for the full list of builtins.
13071314

13081315
\subsection{Other features}

shells/Shell.nw

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,10 @@ other bytecodes & \ref{chap:compile-interpret} & [[exec.c]]
172172
\midrule
173173
shell builtins & \ref{chap:builtins} & [[builtins.c]] & [<execcd()>] [<execexit()>] [<execdot()>] & \\ % execshift execeval execflag [execwait()>] [execwhatis()>]
174174
shell environment & \ref{chap:environment} & [[env.c]] & [<addenv()>] [<Vinit()>] & \\ % Updenv
175+
signal management & \ref{chap:signals} & [[trap.c]] & [<dotrap()>] [<Trapinit()>] & \\ %
176+
initialization (bootstrap) & \ref{chap:initialization-real} & [[main.c]] & [<Rcmain>] [<dotcmds>] & \\ %
175177
wildcard matching & \ref{chap:globbing} & [[glob.c]] & [<glob()>] [<match()>] & \\ % globlist Xglob
176-
signal management & \ref{chap:signals} & [[trap.c]] & [<dotrap()>] & \\ %
177-
178-
\midrule
179-
% initialization chapter?
180-
here documents & \ref{chap:advanced-topics} & [[here.c]] & [<readhere()>] [<heredoc()>] & \\ %
178+
here documents & \ref{chap:advanced-topics} & [[here.c]] & [<readhere()>] [<heredoc()>] & \\ %
181179

182180
\midrule
183181
AST dumper & \ref{chap:debugging-appendix} & [[pcmd.c]] & [<pcmd()>] & \\ %
@@ -711,7 +709,7 @@ is responsible for this transformation.
711709

712710
%toc:
713711
The token kinds in [[rc]] are declared below using
714-
the [[yacc]] syntax [[\%token]] (see \book{Compiler}).
712+
the [[yacc]] syntax \verb+%token+ (see \book{Compiler}).
715713
%
716714
I have grouped them in categories:
717715
the keyword tokens ([[FOR]], [[WHILE]], [[IF]], etc.),
@@ -9336,9 +9334,8 @@ Executable(char *file)
93369334

93379335

93389336
\subsection{[[$ rfork]]}
9339-
%$
9337+
\label{sec:rfork}
93409338

9341-
%rfork
93429339
%claude:
93439340
The [[rfork]] builtin exposes Plan~9's [[rfork(2)]]
93449341
system call, which selectively shares or unshares
@@ -9350,6 +9347,28 @@ file descriptors.
93509347
This is the Plan~9 equivalent of Linux containers
93519348
and namespaces---but from 1992.
93529349

9350+
%claude:
9351+
The environment flag is particularly interesting.
9352+
As mentioned in Chapter~\ref{chap:environment},
9353+
all [[rc]] variables are automatically exported to [[/env/]]---there
9354+
is no [[export]] command like in [[bash]].
9355+
But this raises the question: how do you {\em prevent}
9356+
a variable from being visible to children?
9357+
The answer is [[rfork]]:
9358+
[[rfork e]] creates a {\em copy} of the current [[/env/]],
9359+
so subsequent changes in either the parent or the child
9360+
are invisible to the other;
9361+
[[rfork E]] creates an entirely {\em empty} [[/env/]],
9362+
starting with a clean slate.
9363+
%
9364+
Note that the lowercase flags ([[n]], [[e]], [[f]]) copy
9365+
the resource, while the uppercase flags ([[N]], [[E]], [[F]])
9366+
clear it entirely.
9367+
%
9368+
When called with no arguments, [[rfork]] defaults
9369+
to [[RFENVG|RFNAMEG|RFNOTEG]], creating new
9370+
environment, mount namespace, and note groups all at once.
9371+
93539372
<<function [[execnewpgrp]]>>=
93549373
void
93559374
execnewpgrp(void)

0 commit comments

Comments
 (0)