about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-10-27 11:26:42 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-10-27 11:26:42 -0700
commitfcf35c1315773edb2061b6bbd87b0963eecbd097 (patch)
treecfeb566d121df94c0d77fd451ef29e28571f9eef
parentd4fd180fa051b03ff32cf74dfc5874eef4bdbdeb (diff)
downloadmu-fcf35c1315773edb2061b6bbd87b0963eecbd097.tar.gz
3604
-rw-r--r--html/020run.cc.html3
-rw-r--r--html/035lookup.cc.html20
-rw-r--r--html/036refcount.cc.html2
-rw-r--r--html/042name.cc.html4
-rw-r--r--html/050scenario.cc.html3
-rw-r--r--html/053recipe_header.cc.html11
-rw-r--r--html/057immutable.cc.html8
-rw-r--r--html/080display.cc.html8
-rw-r--r--html/091socket.cc.html68
-rw-r--r--html/092socket.mu.html38
-rw-r--r--html/edit/011-errors.mu.html6
-rw-r--r--html/http-client.mu.html3
-rw-r--r--html/http-server.mu.html4
13 files changed, 108 insertions, 70 deletions
diff --git a/html/020run.cc.html b/html/020run.cc.html
index cb39df0e..57ea81ac 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -90,12 +90,15 @@ routine* Current_routine = <span class="Constant">NULL</span><span class="Delimi
 map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; Instructions_running<span class="Delimiter">;</span>
 map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; Locations_read<span class="Delimiter">;</span>
 map&lt;string<span class="Delimiter">,</span> <span class="Normal">int</span>&gt; Locations_read_by_instruction<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
 
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> run<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   routine rr<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
   Current_routine = &amp;rr<span class="Delimiter">;</span>
   run_current_routine<span class="Delimiter">();</span>
+  Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 <span class="Normal">void</span> run_current_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span>
diff --git a/html/035lookup.cc.html b/html/035lookup.cc.html
index 277d71ed..07545857 100644
--- a/html/035lookup.cc.html
+++ b/html/035lookup.cc.html
@@ -104,6 +104,15 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 <span class="traceAbsent">-mem: storing 34 in location 0</span>
 <span class="traceContains">+error: can't write to location 0 in '1:address:num/lookup &lt;- copy 34'</span>
 
+<span class="Comment">//: attempts to /lookup address 0 always loudly fail</span>
+<span class="Delimiter">:(scenario lookup_0_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
+<span class="muRecipe">def</span> main [
+  <span class="Constant">1</span>:address:num<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  <span class="Constant">2</span>:num<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:num/lookup
+]
+<span class="traceContains">+error: tried to /lookup 0 in '2:num &lt;- copy 1:address:num/lookup'</span>
+
 <span class="Delimiter">:(code)</span>
 <span class="Normal">void</span> canonize<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
@@ -122,10 +131,10 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
     raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+  lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">check_for_null</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
-<span class="Normal">void</span> lookup_memory_core<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Normal">void</span> lookup_memory_core<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> <span class="Normal">bool</span> check_for_null<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;mem&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;location &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>value &lt;&lt; <span class="Constant">&quot; is &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
   x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">));</span>
@@ -134,6 +143,12 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
     trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;mem&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;skipping refcount at &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>value &lt;&lt; end<span class="Delimiter">();</span>
     x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value+<span class="Constant">1</span><span class="Delimiter">);</span>  <span class="Comment">// skip refcount</span>
   <span class="Delimiter">}</span>
+  <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>check_for_null<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">)</span>
+      raise &lt;&lt; <span class="Constant">&quot;tried to /lookup 0 in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Normal">else</span>
+      raise &lt;&lt; <span class="Constant">&quot;tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+  <span class="Delimiter">}</span>
   drop_one_lookup<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
@@ -147,6 +162,7 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 <span class="Normal">void</span> test_lookup_zero_address_does_not_skip_refcount<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span>
   reagent x<span class="Delimiter">(</span><span class="Constant">&quot;*x:address:num&quot;</span><span class="Delimiter">);</span>
   x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">34</span><span class="Delimiter">);</span>  <span class="Comment">// unsafe</span>
   put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
diff --git a/html/036refcount.cc.html b/html/036refcount.cc.html
index 40547a4d..95e1bf03 100644
--- a/html/036refcount.cc.html
+++ b/html/036refcount.cc.html
@@ -119,7 +119,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 
 <span class="Normal">int</span> payload_size<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair&lt;string<span class="Delimiter">,</span> string_tree*&gt;<span class="Delimiter">(</span><span class="Constant">&quot;lookup&quot;</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span>
-  lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+  lookup_memory_core<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">check for nulls</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span>
   <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/042name.cc.html b/html/042name.cc.html
index 098fee41..d6133a59 100644
--- a/html/042name.cc.html
+++ b/html/042name.cc.html
@@ -52,7 +52,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 <span class="muRecipe">def</span> main [
   <span class="Normal">x</span>:num<span class="Special"> &lt;- </span>copy y:num
 ]
-<span class="traceContains">+error: main: use before set: 'y'</span>
+<span class="traceContains">+error: main: tried to read ingredient 'y' in 'x:num &lt;- copy y:num' but it hasn't been written to yet</span>
 <span class="Comment"># todo: detect conditional defines</span>
 
 <span class="Delimiter">:(after &quot;Transform.push_back(compute_container_sizes)&quot;)</span>
@@ -92,7 +92,7 @@ Name = Name_snapshot<span class="Delimiter">;</span>
       <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>ingredient<span class="Delimiter">))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span>
       <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       <span class="Normal">if</span> <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>ingredient<span class="Delimiter">,</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-        raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;use before set: '&quot;</span> &lt;&lt; ingredient<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+        raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;tried to read ingredient '&quot;</span> &lt;&lt; ingredient<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;' in '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;' but it hasn't been written to yet</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
         <span class="Comment">// use-before-set Error</span>
         <span class="Identifier">return</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index 3ca291e8..d44504a0 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -160,13 +160,14 @@ vector&lt;scenario&gt; Scenarios<span class="Delimiter">;</span>
 Num_core_mu_scenarios = SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Tests&quot;)</span>
 Hide_missing_default_space_errors = <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Normal">if</span> <span class="Delimiter">(</span>Num_core_mu_scenarios<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Normal">if</span> <span class="Delimiter">(</span>Num_core_mu_scenarios &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
   time<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
   cerr &lt;&lt; <span class="Constant">&quot;Mu tests: &quot;</span> &lt;&lt; ctime<span class="Delimiter">(</span>&amp;t<span class="Delimiter">);</span>
   <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; Num_core_mu_scenarios<span class="Delimiter">;</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?     cerr &lt;&lt; '\n' &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; Scenarios.at(i).name;</span>
     run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
     <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr &lt;&lt; <span class="Constant">&quot;.&quot;</span><span class="Delimiter">;</span>
+    <span class="Normal">else</span> ++Num_failures<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   cerr &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
diff --git a/html/053recipe_header.cc.html b/html/053recipe_header.cc.html
index 021db5f4..a922f9e2 100644
--- a/html/053recipe_header.cc.html
+++ b/html/053recipe_header.cc.html
@@ -266,7 +266,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   local-scope
   <span class="Normal">b</span>:num<span class="Special"> &lt;- </span>add a:num<span class="Delimiter">,</span> <span class="Constant">1</span>
 ]
-<span class="traceContains">+error: foo: use before set: 'a'</span>
+<span class="traceContains">+error: foo: tried to read ingredient 'a' in 'b:num &lt;- add a:num, 1' but it hasn't been written to yet</span>
 <span class="traceContains">+error:   did you forget 'load-ingredients'?</span>
 
 <span class="Delimiter">:(after &quot;use-before-set Error&quot;)</span>
@@ -286,6 +286,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
 <span class="Normal">if</span> <span class="Delimiter">(</span>is_present_in_ingredients<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> recipe_name<span class="Delimiter">)),</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span>
   raise &lt;&lt; <span class="Constant">&quot;  did you forget 'load-ingredients'?</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
 
+<span class="Delimiter">:(code)</span>
+<span class="Normal">bool</span> is_present_in_ingredients<span class="Delimiter">(</span><span class="Normal">const</span> recipe&amp; callee<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; ingredient_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<span class="Delimiter">)</span>
+      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="SalientComment">//:: Check all calls against headers.</span>
 
 <span class="Delimiter">:(scenario show_clear_error_on_bad_call)</span>
diff --git a/html/057immutable.cc.html b/html/057immutable.cc.html
index f1fbb793..5f8ad767 100644
--- a/html/057immutable.cc.html
+++ b/html/057immutable.cc.html
@@ -538,14 +538,6 @@ set&lt;<span class="Normal">int</span>&gt; scan_contained_in_product_indices<spa
   <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="Normal">bool</span> is_present_in_ingredients<span class="Delimiter">(</span><span class="Normal">const</span> recipe&amp; callee<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; ingredient_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    <span class="Normal">if</span> <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<span class="Delimiter">)</span>
-      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
 set&lt;<span class="Normal">int</span>&gt; ingredient_indices<span class="Delimiter">(</span><span class="Normal">const</span> instruction&amp; inst<span class="Delimiter">,</span> <span class="Normal">const</span> set&lt;reagent&gt;&amp; ingredient_names<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   set&lt;<span class="Normal">int</span>&gt; result<span class="Delimiter">;</span>
   <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/080display.cc.html b/html/080display.cc.html
index 56533131..a5f85757 100644
--- a/html/080display.cc.html
+++ b/html/080display.cc.html
@@ -47,17 +47,17 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 <span class="PreProc">#define CHECK_SCREEN \</span>
 <span class="PreProc">    </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span>
 <span class="PreProc">      </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span>
-<span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to print to real screen before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
-<span class="PreProc">      </span><span class="Normal">else</span><span class="PreProc"> \</span>
 <span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to print to real screen in a test!</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
+<span class="PreProc">      </span><span class="Normal">else</span><span class="PreProc"> \</span>
+<span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to print to real screen before 'open-console' or after 'close-console'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
 <span class="PreProc">      </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
 <span class="PreProc">    </span><span class="Delimiter">}</span>
 <span class="PreProc">#define CHECK_CONSOLE \</span>
 <span class="PreProc">    </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span>
 <span class="PreProc">      </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span>
-<span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to read event from real keyboard/mouse before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
-<span class="PreProc">      </span><span class="Normal">else</span><span class="PreProc"> \</span>
 <span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to read event from real keyboard/mouse in a test!</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
+<span class="PreProc">      </span><span class="Normal">else</span><span class="PreProc"> \</span>
+<span class="PreProc">        raise &lt;&lt; maybe(current_recipe_name()) &lt;&lt; </span><span class="Constant">&quot;tried to read event from real keyboard/mouse before 'open-console' or after 'close-console'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="PreProc"> &lt;&lt; end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
 <span class="PreProc">      </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span>
 <span class="PreProc">    </span><span class="Delimiter">}</span>
 
diff --git a/html/091socket.cc.html b/html/091socket.cc.html
index e205508f..2c75978a 100644
--- a/html/091socket.cc.html
+++ b/html/091socket.cc.html
@@ -14,6 +14,7 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
 body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 12pt; font-size: 1em; }
 .Constant { color: #00a0a0; }
+.CommentedCode { color: #6c6c6c; }
 .cSpecial { color: #008000; }
 .Delimiter { color: #800080; }
 .Identifier { color: #c0a020; }
@@ -155,7 +156,7 @@ socket_t* server_socket<span class="Delimiter">(</span><span class="Normal">int<
   <span class="Normal">int</span> dummy = <span class="Constant">0</span><span class="Delimiter">;</span>
   setsockopt<span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> SOL_SOCKET<span class="Delimiter">,</span> SO_REUSEADDR<span class="Delimiter">,</span> &amp;dummy<span class="Delimiter">,</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>dummy<span class="Delimiter">));</span>
   result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_family = AF_INET<span class="Delimiter">;</span>
-  result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr = INADDR_ANY<span class="Delimiter">;</span>
+  result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr = Current_scenario ? htonl<span class="Delimiter">(</span>INADDR_LOOPBACK<span class="Delimiter">)</span> : INADDR_ANY<span class="Delimiter">;</span>  <span class="Comment">// run tests without running afoul of any firewall</span>
   result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_port = htons<span class="Delimiter">(</span>port<span class="Delimiter">);</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>bind<span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> <span class="Normal">reinterpret_cast</span>&lt;sockaddr*&gt;<span class="Delimiter">(</span>&amp;result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">),</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">))</span> &gt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     listen<span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">queue length</span><span class="Comment">*/</span><span class="Constant">5</span><span class="Delimiter">);</span>
@@ -223,16 +224,12 @@ _READ_FROM_SOCKET<span class="Delimiter">,</span>
 put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;$read-from-socket&quot;</span><span class="Delimiter">,</span> _READ_FROM_SOCKET<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
 <span class="Normal">case</span> _READ_FROM_SOCKET: <span class="Delimiter">{</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$read-from-socket' requires exactly two ingredients, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$read-from-socket' requires exactly one ingredient, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$read-from-socket' should be a number, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-    <span class="Identifier">break</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;second ingredient of '$read-from-socket' should be a number, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$read-from-socket' should be a number (socket), but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">int</span> nprod = SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span>
@@ -240,8 +237,8 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
     raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$read-from-socket' requires 1-4 products, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_text<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first product of '$read-from-socket' should be a text (address array character), but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_character<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first product of '$read-from-socket' should be a character, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>nprod &gt; <span class="Constant">1</span> &amp;&amp; !is_mu_boolean<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
@@ -269,20 +266,25 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Comment">// so use poll() in the beginning to wait for data before calling recv()</span>
   <span class="Comment">// 3. but poll() will block on EOF, so only use poll() on the very first</span>
   <span class="Comment">// $read-from-socket on a socket</span>
+  <span class="Comment">//</span>
+  <span class="Comment">// Also, there was an unresolved issue where attempts to read() a small</span>
+  <span class="Comment">// number of bytes (less than 447 on Linux and Mac) would cause browsers to</span>
+  <span class="Comment">// prematurely close the connection. See commit 3403. That seems to be gone</span>
+  <span class="Comment">// after moving to recv()+poll(). It was never observed on OpenBSD.</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>!socket<span class="Delimiter">-&gt;</span>polled<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     pollfd p<span class="Delimiter">;</span>
     bzero<span class="Delimiter">(</span>&amp;p<span class="Delimiter">,</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>p<span class="Delimiter">));</span>
     p<span class="Delimiter">.</span>fd = socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">;</span>
     p<span class="Delimiter">.</span>events = POLLIN | POLLHUP<span class="Delimiter">;</span>
-    <span class="Normal">int</span> status = poll<span class="Delimiter">(</span>&amp;p<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">num pollfds</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">timeout</span><span class="Comment">*/</span><span class="Constant">100</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span>
-    <span class="Normal">if</span> <span class="Delimiter">(</span>status == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Normal">int</span> poll_result = poll<span class="Delimiter">(</span>&amp;p<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">num pollfds</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">timeout</span><span class="Comment">*/</span><span class="Constant">100</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span>
+    <span class="Normal">if</span> <span class="Delimiter">(</span>poll_result == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">no data</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
       products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span>
       products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">eof</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span>
       products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">error</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
       <span class="Identifier">break</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
-    <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>status &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>poll_result &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       <span class="Normal">int</span> error_code = errno<span class="Delimiter">;</span>
       raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;error in $read-from-socket</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">no data</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
@@ -293,15 +295,19 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
     <span class="Delimiter">}</span>
     socket<span class="Delimiter">-&gt;</span>polled = <span class="Constant">true</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  <span class="Normal">int</span> bytes = <span class="Normal">static_cast</span>&lt;<span class="Normal">int</span>&gt;<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
-  <span class="Normal">char</span>* contents = <span class="Normal">new</span> <span class="Normal">char</span>[bytes]<span class="Delimiter">;</span>
-  bzero<span class="Delimiter">(</span>contents<span class="Delimiter">,</span> bytes<span class="Delimiter">);</span>
-  <span class="Normal">int</span> bytes_read = recv<span class="Delimiter">(</span>socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> contents<span class="Delimiter">,</span> bytes-<span class="Comment">/*</span><span class="Comment">terminal null</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> MSG_DONTWAIT<span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_mu_text<span class="Delimiter">(</span>contents<span class="Delimiter">));</span>
+  <span class="Normal">char</span> c = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
+  <span class="Normal">int</span> error_code = <span class="Constant">0</span><span class="Delimiter">;</span>
+  <span class="Normal">int</span> bytes_read = recv<span class="Delimiter">(</span>socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> &amp;c<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">single byte</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> MSG_DONTWAIT<span class="Delimiter">);</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>bytes_read &lt; <span class="Constant">0</span><span class="Delimiter">)</span> error_code = errno<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   if (error_code) {</span>
+<span class="CommentedCode">//?     ostringstream out;</span>
+<span class="CommentedCode">//?     out &lt;&lt; &quot;error in $read-from-socket &quot; &lt;&lt; socket-&gt;fd;</span>
+<span class="CommentedCode">//?     perror(out.str().c_str());</span>
+<span class="CommentedCode">//?   }</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">eof</span><span class="Comment">*/</span>bytes_read &lt;= <span class="Constant">0</span><span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">error</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
-  <span class="Normal">delete</span> contents<span class="Delimiter">;</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>error_code<span class="Delimiter">);</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -320,17 +326,16 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 <span class="Normal">case</span> _WRITE_TO_SOCKET: <span class="Delimiter">{</span>
   <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x = <span class="Normal">static_cast</span>&lt;<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>&gt;<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
-  socket_t* session = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
-  <span class="Comment">// write just one character at a time to the session socket</span>
+  socket_t* socket = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+  <span class="Comment">// write just one character at a time to the socket</span>
   <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> y = <span class="Normal">static_cast</span>&lt;<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>&gt;<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
   <span class="Normal">char</span> c = <span class="Normal">static_cast</span>&lt;<span class="Normal">char</span>&gt;<span class="Delimiter">(</span>y<span class="Delimiter">);</span>
-  <span class="Normal">if</span> <span class="Delimiter">(</span>write<span class="Delimiter">(</span>session<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> &amp;c<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>write<span class="Delimiter">(</span>socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">,</span> &amp;c<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;failed to write to socket</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
-  <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Normal">reinterpret_cast</span>&lt;<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>&gt;<span class="Delimiter">(</span>session<span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -345,7 +350,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$close-socket' should be a character, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$close-socket' should be a number, but got '&quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$close-socket' requires exactly one product, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name != inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;product of '$close-socket' must be first ingredient '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;', but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -355,6 +368,9 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span
   <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x = <span class="Normal">static_cast</span>&lt;<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>&gt;<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
   socket_t* socket = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
   close<span class="Delimiter">(</span>socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">);</span>
+  <span class="Normal">delete</span> socket<span class="Delimiter">;</span>
+  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>  <span class="Comment">// make sure we can't reuse the socket</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/092socket.mu.html b/html/092socket.mu.html
index 78321183..e3c179eb 100644
--- a/html/092socket.mu.html
+++ b/html/092socket.mu.html
@@ -54,6 +54,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   memory-should-contain [
     10:array:character <span class="Special">&lt;-</span> <span class="Constant">[abc]</span>
   ]
+  socket <span class="Special">&lt;-</span> $close-socket socket
 ]
 <span class="Comment"># helper just for this scenario</span>
 <span class="muRecipe">def</span> example-handler query:text<span class="muRecipe"> -&gt; </span>response:text [
@@ -85,18 +86,18 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 
 <span class="muData">type</span> request-handler = (recipe text<span class="muRecipe"> -&gt; </span>text)
 
-<span class="muRecipe">def</span> serve-one-request socket:num, request-handler:request-handler [
+<span class="muRecipe">def</span> serve-one-request socket:num, request-handler:request-handler<span class="muRecipe"> -&gt; </span>socket:num [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   session:num <span class="Special">&lt;-</span> $accept socket
   assert session, <span class="Constant">[ </span>
 <span class="Constant">F - example-server-test: $accept failed]</span>
   contents:&amp;:source:char, sink:&amp;:sink:char <span class="Special">&lt;-</span> new-channel<span class="Constant"> 30</span>
-  sink <span class="Special">&lt;-</span> start-running receive-from-socket session, sink
+  start-running receive-from-socket session, sink
   query:text <span class="Special">&lt;-</span> drain contents
   response:text <span class="Special">&lt;-</span> call request-handler, query
   write-to-socket session, response
-  $close-socket session
+  session <span class="Special">&lt;-</span> $close-socket session
 ]
 
 <span class="muRecipe">def</span> start-reading-from-network resources:&amp;:resources, uri:text<span class="muRecipe"> -&gt; </span>contents:&amp;:source:char [
@@ -120,7 +121,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   req:text <span class="Special">&lt;-</span> interpolate <span class="Constant">[GET _ HTTP/1.1]</span>, path
   request-socket socket, req
   contents:&amp;:source:char, sink:&amp;:sink:char <span class="Special">&lt;-</span> new-channel<span class="Constant"> 10000</span>
-  start-running receive-from-socket socket, sink
+  start-running receive-from-client-socket-and-close socket, sink
 ]
 
 <span class="muRecipe">def</span> request-socket socket:num, s:text<span class="muRecipe"> -&gt; </span>socket:num [
@@ -134,33 +135,34 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
   $write-to-socket socket, <span class="Constant">10/lf</span>
 ]
 
-<span class="muRecipe">def</span> receive-from-socket socket:num, sink:&amp;:sink:char<span class="muRecipe"> -&gt; </span>sink:&amp;:sink:char [
+<span class="muRecipe">def</span> receive-from-socket socket:num, sink:&amp;:sink:char<span class="muRecipe"> -&gt; </span>sink:&amp;:sink:char, socket:num [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
 <span class="Constant">    +next-attempt</span>
-    req:text, found?:bool, eof?:bool, error:num <span class="Special">&lt;-</span> $read-from-socket socket, <span class="Constant">4096/bytes</span>
+    c:char, found?:bool, eof?:bool, error:num <span class="Special">&lt;-</span> $read-from-socket socket
+    <span class="muControl">break-if</span> eof?
     <span class="muControl">break-if</span> error
     <span class="Delimiter">{</span>
-      <span class="muControl">break-if</span> found?
-      switch
-      <span class="muControl">loop</span> <span class="Constant">+next-attempt</span>
+      <span class="muControl">break-unless</span> found?
+      sink <span class="Special">&lt;-</span> write sink, c
     <span class="Delimiter">}</span>
-    bytes-read:num <span class="Special">&lt;-</span> length *req
-    i:num <span class="Special">&lt;-</span> copy<span class="Constant"> 0</span>
     <span class="Delimiter">{</span>
-      done?:bool <span class="Special">&lt;-</span> greater-or-equal i, bytes-read
-      <span class="muControl">break-if</span> done?
-      c:char <span class="Special">&lt;-</span> index *req, i  <span class="Comment"># todo: unicode</span>
-      sink <span class="Special">&lt;-</span> write sink, c
-      i <span class="Special">&lt;-</span> add i,<span class="Constant"> 1</span>
-      <span class="muControl">loop</span>
+      <span class="muControl">break-if</span> found?
+      switch
     <span class="Delimiter">}</span>
-    <span class="muControl">loop-unless</span> eof?
+    <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   sink <span class="Special">&lt;-</span> close sink
 ]
 
+<span class="muRecipe">def</span> receive-from-client-socket-and-close socket:num, sink:&amp;:sink:char<span class="muRecipe"> -&gt; </span>sink:&amp;:sink:char, socket:num [
+  <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
+  sink <span class="Special">&lt;-</span> receive-from-socket socket, sink
+  socket <span class="Special">&lt;-</span> $close-socket socket
+]
+
 <span class="muRecipe">def</span> write-to-socket socket:num, s:text [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
diff --git a/html/edit/011-errors.mu.html b/html/edit/011-errors.mu.html
index 2bdf811a..91e48c57 100644
--- a/html/edit/011-errors.mu.html
+++ b/html/edit/011-errors.mu.html
@@ -521,7 +521,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .  local-scope                                     ╎                                                 .</span>
    <span class="Constant"> .  x:num &lt;- copy y:num                             ╎                                                 .</span>
    <span class="Constant"> .]                                                 ╎                                                 .</span>
-   <span class="Constant"> .foo: use before set: 'y'                          ╎                                                 .</span>
+   <span class="Constant"> .foo: tried to read ingredient 'y' in 'x:num &lt;- co↩╎                                                 .</span>
+   <span class="Constant"> .py y:num' but it hasn't been written to yet       ╎                                                 .</span>
    <span class="Constant"> .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .</span>
    <span class="Constant"> .                                                  ╎                                                 .</span>
   ]
@@ -539,7 +540,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
    <span class="Constant"> .  local-scope                                     ╎                                                 .</span>
    <span class="Constant"> .  x:num &lt;- copy y:num                             ╎                                                 .</span>
    <span class="Constant"> .]                                                 ╎                                                 .</span>
-   <span class="Constant"> .foo: use before set: 'y'                          ╎                                                 .</span>
+   <span class="Constant"> .foo: tried to read ingredient 'y' in 'x:num &lt;- co↩╎                                                 .</span>
+   <span class="Constant"> .py y:num' but it hasn't been written to yet       ╎                                                 .</span>
    <span class="Constant"> .╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╎                                                 .</span>
    <span class="Constant"> .                                                  ╎                                                 .</span>
   ]
diff --git a/html/http-client.mu.html b/html/http-client.mu.html
index 264f56ed..8421fc60 100644
--- a/html/http-client.mu.html
+++ b/html/http-client.mu.html
@@ -18,7 +18,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
 .Special { color: #c00000; }
-.CommentedCode { color: #6c6c6c; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -43,8 +42,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
     <span class="muControl">break-if</span> done?
     n <span class="Special">&lt;-</span> add n,<span class="Constant"> 1</span>
     buf <span class="Special">&lt;-</span> append buf, c
-<span class="CommentedCode">#?     trunc?:bool &lt;- greater-or-equal n, 10000</span>
-<span class="CommentedCode">#?     loop-unless trunc?</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   result:text <span class="Special">&lt;-</span> buffer-to-array buf
diff --git a/html/http-server.mu.html b/html/http-server.mu.html
index 97220e9b..6ed0ffe6 100644
--- a/html/http-server.mu.html
+++ b/html/http-server.mu.html
@@ -54,8 +54,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color
 <span class="Constant">SUCCESS!</span>
 <span class="Constant">]</span>
   $print <span class="Constant">10/newline</span>, <span class="Constant">[Wrote to and closing socket...]</span>, <span class="Constant">10/newline</span>
-  $close-socket session
-  $close-socket socket
+  session <span class="Special">&lt;-</span> $close-socket session
+  socket <span class="Special">&lt;-</span> $close-socket socket
 ]
 </pre>
 </body>