mu/html/091socket.cc.html
Kartik Agaram 08a0eed699 4891
Couple more tweaks to html rendering:
a) SubX definitions no longer link redundantly to themselves. This long-standing
issue turns out to be tractable to solve for SubX files since the syntax
is so simple.
b) Fix links to SubX definitions in other directories. I forgot that I
have to always generate tags from the directory of the file being linkified.
c) Fix link colors. Before we lost all syntax highlighting for functions
and Globals. Now they maintain their colors, just add an underline.
2018-12-30 00:02:42 -08:00

413 lines
81 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 091socket.cc</title>
<meta name="Generator" content="Vim/8.0">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.CommentedCode { color: #8a8a8a; }
.LineNr { }
.Constant { color: #008787; }
.Delimiter { color: #c000c0; }
.Special { color: #d70000; }
.Identifier { color: #af5f00; }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Comment { color: #005faf; }
.cSpecial { color: #008000; }
-->
</style>
<script type='text/javascript'>
<!--
/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
var lineNum;
lineNum = window.location.hash;
lineNum = lineNum.substr(1); /* strip off '#' */
if (lineNum.indexOf('L') == -1) {
lineNum = 'L'+lineNum;
}
lineElem = document.getElementById(lineNum);
/* Always jump to new location even if the line was hidden inside a fold, or
* we corrected the raw number to a line ID.
*/
if (lineElem) {
lineElem.scrollIntoView(true);
}
return true;
}
if ('onhashchange' in window) {
window.onhashchange = JumpToLine;
}
-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/091socket.cc'>https://github.com/akkartik/mu/blob/master/091socket.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr"> 1 </span><span class="Delimiter">:(before &quot;End Types&quot;)</span>
<span id="L2" class="LineNr"> 2 </span><span class="Normal">struct</span> socket_t <span class="Delimiter">{</span>
<span id="L3" class="LineNr"> 3 </span> <span class="Normal">int</span> fd<span class="Delimiter">;</span>
<span id="L4" class="LineNr"> 4 </span> sockaddr_in addr<span class="Delimiter">;</span>
<span id="L5" class="LineNr"> 5 </span> <span class="Normal">bool</span> polled<span class="Delimiter">;</span>
<span id="L6" class="LineNr"> 6 </span> socket_t<span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L7" class="LineNr"> 7 </span> fd = <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L8" class="LineNr"> 8 </span> polled =<span class="Constant"> false</span><span class="Delimiter">;</span>
<span id="L9" class="LineNr"> 9 </span> bzero<span class="Delimiter">(</span>&amp;addr<span class="Delimiter">,</span> <span class="Normal">sizeof</span><span class="Delimiter">(</span>addr<span class="Delimiter">));</span>
<span id="L10" class="LineNr"> 10 </span> <span class="Delimiter">}</span>
<span id="L11" class="LineNr"> 11 </span><span class="Delimiter">};</span>
<span id="L12" class="LineNr"> 12 </span>
<span id="L13" class="LineNr"> 13 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L14" class="LineNr"> 14 </span>_OPEN_CLIENT_SOCKET<span class="Delimiter">,</span>
<span id="L15" class="LineNr"> 15 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L16" class="LineNr"> 16 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;$open-client-socket&quot;</span><span class="Delimiter">,</span> _OPEN_CLIENT_SOCKET<span class="Delimiter">);</span>
<span id="L17" class="LineNr"> 17 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L18" class="LineNr"> 18 </span><span class="Normal">case</span> _OPEN_CLIENT_SOCKET: <span class="Delimiter">{</span>
<span id="L19" class="LineNr"> 19 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L20" class="LineNr"> 20 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$open-client-socket' requires exactly two ingredients, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L21" class="LineNr"> 21 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L22" class="LineNr"> 22 </span> <span class="Delimiter">}</span>
<span id="L23" class="LineNr"> 23 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_text<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>
<span id="L24" class="LineNr"> 24 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$open-client-socket' should be text (the hostname), 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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L25" class="LineNr"> 25 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L26" class="LineNr"> 26 </span> <span class="Delimiter">}</span>
<span id="L27" class="LineNr"> 27 </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>
<span id="L28" class="LineNr"> 28 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;second ingredient of '$open-client-socket' should be a number (the port of the hostname to connect to), 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">1</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L29" class="LineNr"> 29 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L30" class="LineNr"> 30 </span> <span class="Delimiter">}</span>
<span id="L31" class="LineNr"> 31 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L32" class="LineNr"> 32 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$open-client-socket' requires exactly one product, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L33" class="LineNr"> 33 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L34" class="LineNr"> 34 </span> <span class="Delimiter">}</span>
<span id="L35" class="LineNr"> 35 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<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>
<span id="L36" class="LineNr"> 36 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first product of '$open-client-socket' should be a number (socket handle), 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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L37" class="LineNr"> 37 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L38" class="LineNr"> 38 </span> <span class="Delimiter">}</span>
<span id="L39" class="LineNr"> 39 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L40" class="LineNr"> 40 </span><span class="Delimiter">}</span>
<span id="L41" class="LineNr"> 41 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L42" class="LineNr"> 42 </span><span class="Normal">case</span> _OPEN_CLIENT_SOCKET: <span class="Delimiter">{</span>
<span id="L43" class="LineNr"> 43 </span> string host = <a href='038new_text.cc.html#L142'>read_mu_text</a><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="Comment">/*</span><span class="Comment">skip alloc id</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">));</span>
<span id="L44" class="LineNr"> 44 </span> <span class="Normal">int</span> port = 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 id="L45" class="LineNr"> 45 </span> socket_t* client = <a href='091socket.cc.html#L57'>client_socket</a><span class="Delimiter">(</span>host<span class="Delimiter">,</span> port<span class="Delimiter">);</span>
<span id="L46" class="LineNr"> 46 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L47" class="LineNr"> 47 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>client<span class="Delimiter">-&gt;</span>fd &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// error</span>
<span id="L48" class="LineNr"> 48 </span> <span class="Normal">delete</span> client<span class="Delimiter">;</span>
<span id="L49" class="LineNr"> 49 </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 id="L50" class="LineNr"> 50 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L51" class="LineNr"> 51 </span> <span class="Delimiter">}</span>
<span id="L52" class="LineNr"> 52 </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>client<span class="Delimiter">);</span>
<span id="L53" class="LineNr"> 53 </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="Normal">static_cast</span>&lt;<span class="Normal">double</span>&gt;<span class="Delimiter">(</span>result<span class="Delimiter">));</span>
<span id="L54" class="LineNr"> 54 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L55" class="LineNr"> 55 </span><span class="Delimiter">}</span>
<span id="L56" class="LineNr"> 56 </span><span class="Delimiter">:(code)</span>
<span id="L57" class="LineNr"> 57 </span>socket_t* <a href='091socket.cc.html#L57'>client_socket</a><span class="Delimiter">(</span><span class="Normal">const</span> string&amp; host<span class="Delimiter">,</span> <span class="Normal">int</span> port<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L58" class="LineNr"> 58 </span> socket_t* result = <span class="Normal">new</span> socket_t<span class="Delimiter">;</span>
<span id="L59" class="LineNr"> 59 </span> result<span class="Delimiter">-&gt;</span>fd = socket<span class="Delimiter">(</span>AF_INET<span class="Delimiter">,</span> SOCK_STREAM<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span id="L60" class="LineNr"> 60 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L61" class="LineNr"> 61 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <span class="Constant">&quot;Failed to create socket.\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L62" class="LineNr"> 62 </span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span id="L63" class="LineNr"> 63 </span> <span class="Delimiter">}</span>
<span id="L64" class="LineNr"> 64 </span> result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_family = AF_INET<span class="Delimiter">;</span>
<span id="L65" class="LineNr"> 65 </span> hostent* tmp = gethostbyname<span class="Delimiter">(</span>host<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span>
<span id="L66" class="LineNr"> 66 </span> bcopy<span class="Delimiter">(</span>tmp<span class="Delimiter">-&gt;</span>h_addr<span class="Delimiter">,</span> <span class="Normal">reinterpret_cast</span>&lt;<span class="Normal">char</span>*&gt;<span class="Delimiter">(</span>&amp;result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr<span class="Delimiter">),</span> tmp<span class="Delimiter">-&gt;</span>h_length<span class="Delimiter">);</span>
<span id="L67" class="LineNr"> 67 </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 id="L68" class="LineNr"> 68 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>connect<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> &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L69" class="LineNr"> 69 </span> close<span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">);</span>
<span id="L70" class="LineNr"> 70 </span> result<span class="Delimiter">-&gt;</span>fd = -<span class="Constant">1</span><span class="Delimiter">;</span>
<span id="L71" class="LineNr"> 71 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <span class="Constant">&quot;Failed to connect to &quot;</span> &lt;&lt; host &lt;&lt; <span class="Constant">':'</span> &lt;&lt; port &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L72" class="LineNr"> 72 </span> <span class="Delimiter">}</span>
<span id="L73" class="LineNr"> 73 </span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span id="L74" class="LineNr"> 74 </span><span class="Delimiter">}</span>
<span id="L75" class="LineNr"> 75 </span>
<span id="L76" class="LineNr"> 76 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L77" class="LineNr"> 77 </span>_OPEN_SERVER_SOCKET<span class="Delimiter">,</span>
<span id="L78" class="LineNr"> 78 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L79" class="LineNr"> 79 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;$open-server-socket&quot;</span><span class="Delimiter">,</span> _OPEN_SERVER_SOCKET<span class="Delimiter">);</span>
<span id="L80" class="LineNr"> 80 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L81" class="LineNr"> 81 </span><span class="Normal">case</span> _OPEN_SERVER_SOCKET: <span class="Delimiter">{</span>
<span id="L82" class="LineNr"> 82 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L83" class="LineNr"> 83 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$open-server-socket' requires exactly one ingredient (the port to listen for requests on), but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L84" class="LineNr"> 84 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L85" class="LineNr"> 85 </span> <span class="Delimiter">}</span>
<span id="L86" class="LineNr"> 86 </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>
<span id="L87" class="LineNr"> 87 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$open-server-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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L88" class="LineNr"> 88 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L89" class="LineNr"> 89 </span> <span class="Delimiter">}</span>
<span id="L90" class="LineNr"> 90 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L91" class="LineNr"> 91 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$open-server-socket' requires exactly one product, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L92" class="LineNr"> 92 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L93" class="LineNr"> 93 </span> <span class="Delimiter">}</span>
<span id="L94" class="LineNr"> 94 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<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>
<span id="L95" class="LineNr"> 95 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first product of '$open-server-socket' should be a number (file handle), 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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L96" class="LineNr"> 96 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L97" class="LineNr"> 97 </span> <span class="Delimiter">}</span>
<span id="L98" class="LineNr"> 98 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L99" class="LineNr"> 99 </span><span class="Delimiter">}</span>
<span id="L100" class="LineNr">100 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L101" class="LineNr">101 </span><span class="Normal">case</span> _OPEN_SERVER_SOCKET: <span class="Delimiter">{</span>
<span id="L102" class="LineNr">102 </span> <span class="Normal">int</span> port = 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 id="L103" class="LineNr">103 </span> socket_t* server = <a href='091socket.cc.html#L115'>server_socket</a><span class="Delimiter">(</span>port<span class="Delimiter">);</span>
<span id="L104" class="LineNr">104 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L105" class="LineNr">105 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>server<span class="Delimiter">-&gt;</span>fd &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L106" class="LineNr">106 </span> <span class="Normal">delete</span> server<span class="Delimiter">;</span>
<span id="L107" class="LineNr">107 </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 id="L108" class="LineNr">108 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L109" class="LineNr">109 </span> <span class="Delimiter">}</span>
<span id="L110" class="LineNr">110 </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>server<span class="Delimiter">);</span>
<span id="L111" class="LineNr">111 </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="Normal">static_cast</span>&lt;<span class="Normal">double</span>&gt;<span class="Delimiter">(</span>result<span class="Delimiter">));</span>
<span id="L112" class="LineNr">112 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L113" class="LineNr">113 </span><span class="Delimiter">}</span>
<span id="L114" class="LineNr">114 </span><span class="Delimiter">:(code)</span>
<span id="L115" class="LineNr">115 </span>socket_t* <a href='091socket.cc.html#L115'>server_socket</a><span class="Delimiter">(</span><span class="Normal">int</span> port<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L116" class="LineNr">116 </span> socket_t* result = <span class="Normal">new</span> socket_t<span class="Delimiter">;</span>
<span id="L117" class="LineNr">117 </span> result<span class="Delimiter">-&gt;</span>fd = socket<span class="Delimiter">(</span>AF_INET<span class="Delimiter">,</span> SOCK_STREAM<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span id="L118" class="LineNr">118 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L119" class="LineNr">119 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <span class="Constant">&quot;Failed to create server socket.\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L120" class="LineNr">120 </span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span id="L121" class="LineNr">121 </span> <span class="Delimiter">}</span>
<span id="L122" class="LineNr">122 </span> <span class="Normal">int</span> dummy = <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L123" class="LineNr">123 </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>
<span id="L124" class="LineNr">124 </span> result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_family = AF_INET<span class="Delimiter">;</span>
<span id="L125" class="LineNr">125 </span> result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">.</span>sin_addr<span class="Delimiter">.</span>s_addr = <span class="Special">Current_scenario</span> ? 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>
<span id="L126" class="LineNr">126 </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 id="L127" class="LineNr">127 </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>
<span id="L128" class="LineNr">128 </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>
<span id="L129" class="LineNr">129 </span> <span class="Delimiter">}</span>
<span id="L130" class="LineNr">130 </span> <span class="Normal">else</span> <span class="Delimiter">{</span>
<span id="L131" class="LineNr">131 </span> close<span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">);</span>
<span id="L132" class="LineNr">132 </span> result<span class="Delimiter">-&gt;</span>fd = -<span class="Constant">1</span><span class="Delimiter">;</span>
<span id="L133" class="LineNr">133 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <span class="Constant">&quot;Failed to bind result socket to port &quot;</span> &lt;&lt; port &lt;&lt; <span class="Constant">&quot;. Something's already using that port.\n&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L134" class="LineNr">134 </span> <span class="Delimiter">}</span>
<span id="L135" class="LineNr">135 </span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span id="L136" class="LineNr">136 </span><span class="Delimiter">}</span>
<span id="L137" class="LineNr">137 </span>
<span id="L138" class="LineNr">138 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L139" class="LineNr">139 </span>_ACCEPT<span class="Delimiter">,</span>
<span id="L140" class="LineNr">140 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L141" class="LineNr">141 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;$accept&quot;</span><span class="Delimiter">,</span> _ACCEPT<span class="Delimiter">);</span>
<span id="L142" class="LineNr">142 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L143" class="LineNr">143 </span><span class="Normal">case</span> _ACCEPT: <span class="Delimiter">{</span>
<span id="L144" class="LineNr">144 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L145" class="LineNr">145 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$accept' requires exactly one ingredient, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L146" class="LineNr">146 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L147" class="LineNr">147 </span> <span class="Delimiter">}</span>
<span id="L148" class="LineNr">148 </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>
<span id="L149" class="LineNr">149 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of '$accept' 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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L150" class="LineNr">150 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L151" class="LineNr">151 </span> <span class="Delimiter">}</span>
<span id="L152" class="LineNr">152 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L153" class="LineNr">153 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$accept' requires exactly one product, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L154" class="LineNr">154 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L155" class="LineNr">155 </span> <span class="Delimiter">}</span>
<span id="L156" class="LineNr">156 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<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>
<span id="L157" class="LineNr">157 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first product of '$accept' should be a number (file handle), 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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L158" class="LineNr">158 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L159" class="LineNr">159 </span> <span class="Delimiter">}</span>
<span id="L160" class="LineNr">160 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L161" class="LineNr">161 </span><span class="Delimiter">}</span>
<span id="L162" class="LineNr">162 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L163" class="LineNr">163 </span><span class="Normal">case</span> _ACCEPT: <span class="Delimiter">{</span>
<span id="L164" class="LineNr">164 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
<span id="L165" class="LineNr">165 </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>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="Comment">// indicate it modifies its ingredient</span>
<span id="L166" class="LineNr">166 </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>
<span id="L167" class="LineNr">167 </span> socket_t* server = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span id="L168" class="LineNr">168 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>server<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L169" class="LineNr">169 </span> socket_t* session = <a href='091socket.cc.html#L179'>accept_session</a><span class="Delimiter">(</span>server<span class="Delimiter">);</span>
<span id="L170" class="LineNr">170 </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>
<span id="L171" class="LineNr">171 </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="Normal">static_cast</span>&lt;<span class="Normal">double</span>&gt;<span class="Delimiter">(</span>result<span class="Delimiter">));</span>
<span id="L172" class="LineNr">172 </span> <span class="Delimiter">}</span>
<span id="L173" class="LineNr">173 </span> <span class="Normal">else</span> <span class="Delimiter">{</span>
<span id="L174" class="LineNr">174 </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 id="L175" class="LineNr">175 </span> <span class="Delimiter">}</span>
<span id="L176" class="LineNr">176 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L177" class="LineNr">177 </span><span class="Delimiter">}</span>
<span id="L178" class="LineNr">178 </span><span class="Delimiter">:(code)</span>
<span id="L179" class="LineNr">179 </span>socket_t* <a href='091socket.cc.html#L179'>accept_session</a><span class="Delimiter">(</span>socket_t* server<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L180" class="LineNr">180 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>server<span class="Delimiter">-&gt;</span>fd == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
<span id="L181" class="LineNr">181 </span> socket_t* result = <span class="Normal">new</span> socket_t<span class="Delimiter">;</span>
<span id="L182" class="LineNr">182 </span> socklen_t dummy = <span class="Normal">sizeof</span><span class="Delimiter">(</span>result<span class="Delimiter">-&gt;</span>addr<span class="Delimiter">);</span>
<span id="L183" class="LineNr">183 </span> result<span class="Delimiter">-&gt;</span>fd = accept<span class="Delimiter">(</span>server<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> &amp;dummy<span class="Delimiter">);</span>
<span id="L184" class="LineNr">184 </span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span id="L185" class="LineNr">185 </span><span class="Delimiter">}</span>
<span id="L186" class="LineNr">186 </span>
<span id="L187" class="LineNr">187 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L188" class="LineNr">188 </span>_READ_FROM_SOCKET<span class="Delimiter">,</span>
<span id="L189" class="LineNr">189 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L190" class="LineNr">190 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><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 id="L191" class="LineNr">191 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L192" class="LineNr">192 </span><span class="Normal">case</span> _READ_FROM_SOCKET: <span class="Delimiter">{</span>
<span id="L193" class="LineNr">193 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L194" class="LineNr">194 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L195" class="LineNr">195 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L196" class="LineNr">196 </span> <span class="Delimiter">}</span>
<span id="L197" class="LineNr">197 </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>
<span id="L198" class="LineNr">198 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L199" class="LineNr">199 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L200" class="LineNr">200 </span> <span class="Delimiter">}</span>
<span id="L201" class="LineNr">201 </span> <span class="Normal">int</span> nprod = <a href='001help.cc.html#L141'>SIZE</a><span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span>
<span id="L202" class="LineNr">202 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>nprod == <span class="Constant">0</span> || nprod &gt; <span class="Constant">4</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L203" class="LineNr">203 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L204" class="LineNr">204 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L205" class="LineNr">205 </span> <span class="Delimiter">}</span>
<span id="L206" class="LineNr">206 </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>
<span id="L207" class="LineNr">207 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L208" class="LineNr">208 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L209" class="LineNr">209 </span> <span class="Delimiter">}</span>
<span id="L210" class="LineNr">210 </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>
<span id="L211" class="LineNr">211 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;second product of '$read-from-socket' should be a boolean (data received?), 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">1</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L212" class="LineNr">212 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L213" class="LineNr">213 </span> <span class="Delimiter">}</span>
<span id="L214" class="LineNr">214 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>nprod &gt; <span class="Constant">2</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">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
<span id="L215" class="LineNr">215 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;third product of '$read-from-socket' should be a boolean (eof?), 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">2</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L216" class="LineNr">216 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L217" class="LineNr">217 </span> <span class="Delimiter">}</span>
<span id="L218" class="LineNr">218 </span> <span class="Normal">if</span> <span class="Delimiter">(</span>nprod &gt; <span class="Constant">3</span> &amp;&amp; !is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
<span id="L219" class="LineNr">219 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;fourth product of '$read-from-socket' should be a number (error code), 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">3</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L220" class="LineNr">220 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L221" class="LineNr">221 </span> <span class="Delimiter">}</span>
<span id="L222" class="LineNr">222 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L223" class="LineNr">223 </span><span class="Delimiter">}</span>
<span id="L224" class="LineNr">224 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L225" class="LineNr">225 </span><span class="Normal">case</span> _READ_FROM_SOCKET: <span class="Delimiter">{</span>
<span id="L226" class="LineNr">226 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">);</span>
<span id="L227" class="LineNr">227 </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>
<span id="L228" class="LineNr">228 </span> socket_t* socket = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span id="L229" class="LineNr">229 </span> <span class="Comment">// 1. we'd like to simply read() from the socket</span>
<span id="L230" class="LineNr">230 </span> <span class="Comment">// however read() on a socket never returns EOF, so we wouldn't know when to stop</span>
<span id="L231" class="LineNr">231 </span> <span class="Comment">// 2. recv() can signal EOF, but it also signals &quot;no data yet&quot; in the beginning</span>
<span id="L232" class="LineNr">232 </span> <span class="Comment">// so use poll() in the beginning to wait for data before calling recv()</span>
<span id="L233" class="LineNr">233 </span> <span class="Comment">// 3. but poll() will block on EOF, so only use poll() on the very first</span>
<span id="L234" class="LineNr">234 </span> <span class="Comment">// $read-from-socket on a socket</span>
<span id="L235" class="LineNr">235 </span> <span class="Comment">//</span>
<span id="L236" class="LineNr">236 </span> <span class="Comment">// Also, there was an unresolved issue where attempts to read() a small</span>
<span id="L237" class="LineNr">237 </span> <span class="Comment">// number of bytes (less than 447 on Linux and Mac) would cause browsers to</span>
<span id="L238" class="LineNr">238 </span> <span class="Comment">// prematurely close the connection. See commit 3403. That seems to be gone</span>
<span id="L239" class="LineNr">239 </span> <span class="Comment">// after moving to recv()+poll(). It was never observed on OpenBSD.</span>
<span id="L240" class="LineNr">240 </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>
<span id="L241" class="LineNr">241 </span> pollfd p<span class="Delimiter">;</span>
<span id="L242" class="LineNr">242 </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>
<span id="L243" class="LineNr">243 </span> p<span class="Delimiter">.</span>fd = socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">;</span>
<span id="L244" class="LineNr">244 </span> p<span class="Delimiter">.</span>events = POLLIN | POLLHUP<span class="Delimiter">;</span>
<span id="L245" class="LineNr">245 </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 id="L246" class="LineNr">246 </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>
<span id="L247" class="LineNr">247 </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>
<span id="L248" class="LineNr">248 </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>
<span id="L249" class="LineNr">249 </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>
<span id="L250" class="LineNr">250 </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 id="L251" class="LineNr">251 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L252" class="LineNr">252 </span> <span class="Delimiter">}</span>
<span id="L253" class="LineNr">253 </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 id="L254" class="LineNr">254 </span> <span class="Normal">int</span> error_code = errno<span class="Delimiter">;</span>
<span id="L255" class="LineNr">255 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span><a href='026call.cc.html#L87'>current_recipe_name</a><span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;error in $read-from-socket\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L256" class="LineNr">256 </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>
<span id="L257" class="LineNr">257 </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>
<span id="L258" class="LineNr">258 </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>
<span id="L259" class="LineNr">259 </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 id="L260" class="LineNr">260 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L261" class="LineNr">261 </span> <span class="Delimiter">}</span>
<span id="L262" class="LineNr">262 </span> socket<span class="Delimiter">-&gt;</span>polled =<span class="Constant"> true</span><span class="Delimiter">;</span>
<span id="L263" class="LineNr">263 </span> <span class="Delimiter">}</span>
<span id="L264" class="LineNr">264 </span> <span class="Normal">char</span> c = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
<span id="L265" class="LineNr">265 </span> <span class="Normal">int</span> error_code = <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L266" class="LineNr">266 </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 id="L267" class="LineNr">267 </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 id="L268" class="LineNr">268 </span><span class="CommentedCode">//? if (error_code) {</span>
<span id="L269" class="LineNr">269 </span><span class="CommentedCode">//? ostringstream out;</span>
<span id="L270" class="LineNr">270 </span><span class="CommentedCode">//? out &lt;&lt; &quot;error in $read-from-socket &quot; &lt;&lt; socket-&gt;fd;</span>
<span id="L271" class="LineNr">271 </span><span class="CommentedCode">//? perror(out.str().c_str());</span>
<span id="L272" class="LineNr">272 </span><span class="CommentedCode">//? }</span>
<span id="L273" class="LineNr">273 </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>
<span id="L274" class="LineNr">274 </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>
<span id="L275" class="LineNr">275 </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>
<span id="L276" class="LineNr">276 </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 id="L277" class="LineNr">277 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L278" class="LineNr">278 </span><span class="Delimiter">}</span>
<span id="L279" class="LineNr">279 </span>
<span id="L280" class="LineNr">280 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L281" class="LineNr">281 </span>_WRITE_TO_SOCKET<span class="Delimiter">,</span>
<span id="L282" class="LineNr">282 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L283" class="LineNr">283 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;$write-to-socket&quot;</span><span class="Delimiter">,</span> _WRITE_TO_SOCKET<span class="Delimiter">);</span>
<span id="L284" class="LineNr">284 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L285" class="LineNr">285 </span><span class="Normal">case</span> _WRITE_TO_SOCKET: <span class="Delimiter">{</span>
<span id="L286" class="LineNr">286 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L287" class="LineNr">287 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$write-to-socket' requires exactly two ingredient, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L288" class="LineNr">288 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L289" class="LineNr">289 </span> <span class="Delimiter">}</span>
<span id="L290" class="LineNr">290 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L291" class="LineNr">291 </span><span class="Delimiter">}</span>
<span id="L292" class="LineNr">292 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L293" class="LineNr">293 </span><span class="Normal">case</span> _WRITE_TO_SOCKET: <span class="Delimiter">{</span>
<span id="L294" class="LineNr">294 </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>
<span id="L295" class="LineNr">295 </span> socket_t* socket = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span id="L296" class="LineNr">296 </span> <span class="Comment">// write just one character at a time to the socket</span>
<span id="L297" class="LineNr">297 </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 id="L298" class="LineNr">298 </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 id="L299" class="LineNr">299 </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>
<span id="L300" class="LineNr">300 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span><a href='026call.cc.html#L87'>current_recipe_name</a><span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;failed to write to socket\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L301" class="LineNr">301 </span> exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span id="L302" class="LineNr">302 </span> <span class="Delimiter">}</span>
<span id="L303" class="LineNr">303 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L304" class="LineNr">304 </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 id="L305" class="LineNr">305 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L306" class="LineNr">306 </span><span class="Delimiter">}</span>
<span id="L307" class="LineNr">307 </span>
<span id="L308" class="LineNr">308 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
<span id="L309" class="LineNr">309 </span>_CLOSE_SOCKET<span class="Delimiter">,</span>
<span id="L310" class="LineNr">310 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
<span id="L311" class="LineNr">311 </span><a href='001help.cc.html#L221'>put</a><span class="Delimiter">(</span><span class="Special">Recipe_ordinal</span><span class="Delimiter">,</span> <span class="Constant">&quot;$close-socket&quot;</span><span class="Delimiter">,</span> _CLOSE_SOCKET<span class="Delimiter">);</span>
<span id="L312" class="LineNr">312 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
<span id="L313" class="LineNr">313 </span><span class="Normal">case</span> _CLOSE_SOCKET: <span class="Delimiter">{</span>
<span id="L314" class="LineNr">314 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L315" class="LineNr">315 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'$close-socket' requires exactly two ingredient, but got '&quot;</span> &lt;&lt; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L316" class="LineNr">316 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L317" class="LineNr">317 </span> <span class="Delimiter">}</span>
<span id="L318" class="LineNr">318 </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>
<span id="L319" class="LineNr">319 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L320" class="LineNr">320 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L321" class="LineNr">321 </span> <span class="Delimiter">}</span>
<span id="L322" class="LineNr">322 </span> <span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L141'>SIZE</a><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>
<span id="L323" class="LineNr">323 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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; to_original_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L324" class="LineNr">324 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L325" class="LineNr">325 </span> <span class="Delimiter">}</span>
<span id="L326" class="LineNr">326 </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>
<span id="L327" class="LineNr">327 </span> <a href='003trace.cc.html#L196'>raise</a> &lt;&lt; <a href='013update_operation.cc.html#L25'>maybe</a><span class="Delimiter">(</span>get<span class="Delimiter">(</span><span class="Special">Recipe</span><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;'\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L225'>end</a><span class="Delimiter">();</span>
<span id="L328" class="LineNr">328 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L329" class="LineNr">329 </span> <span class="Delimiter">}</span>
<span id="L330" class="LineNr">330 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L331" class="LineNr">331 </span><span class="Delimiter">}</span>
<span id="L332" class="LineNr">332 </span><span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
<span id="L333" class="LineNr">333 </span><span class="Normal">case</span> _CLOSE_SOCKET: <span class="Delimiter">{</span>
<span id="L334" class="LineNr">334 </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>
<span id="L335" class="LineNr">335 </span> socket_t* socket = <span class="Normal">reinterpret_cast</span>&lt;socket_t*&gt;<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span id="L336" class="LineNr">336 </span> close<span class="Delimiter">(</span>socket<span class="Delimiter">-&gt;</span>fd<span class="Delimiter">);</span>
<span id="L337" class="LineNr">337 </span> <span class="Normal">delete</span> socket<span class="Delimiter">;</span>
<span id="L338" class="LineNr">338 </span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L339" class="LineNr">339 </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 id="L340" class="LineNr">340 </span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span id="L341" class="LineNr">341 </span><span class="Delimiter">}</span>
<span id="L342" class="LineNr">342 </span>
<span id="L343" class="LineNr">343 </span><span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span id="L344" class="LineNr">344 </span><span class="Comment">#include &lt;netinet/in.h&gt;</span>
<span id="L345" class="LineNr">345 </span><span class="Comment">#include &lt;netdb.h&gt;</span>
<span id="L346" class="LineNr">346 </span><span class="Comment">#include &lt;poll.h&gt;</span>
<span id="L347" class="LineNr">347 </span><span class="Comment">#include &lt;sys/socket.h&gt;</span>
<span id="L348" class="LineNr">348 </span><span class="Comment">#include &lt;unistd.h&gt;</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->