title: C and Erlang: Erlang Port example
body: <p><em>Disclaimer: The author of the question has an average knowledge of Erlang and a basic knowledge of C.</em></p>
  
  <p>I am reading the <a href="http://www.erlang.org/doc/tutorial/users_guide.html" rel="noreferrer">Interoperability Tutorial User Guide</a> now. I have successfully compiled the <code>complex.c</code> example and it works with the Erlang Port without any problems.</p>
  
  <p>However, I would like to understand how the actual C code works. I understand it in general: in the example it reads 2 bytes from the standard input and checks the first byte. Depending on the first byte it calls either <code>foo</code> or <code>bar</code> function. This is the limit of my understanding of it right now.</p>
  
  <p>So, if we take both <code>erl_comm.c</code>:</p>
  
  <pre><code>/* erl_comm.c */
  
  typedef unsigned char byte;
  
  read_cmd(byte *buf)
  {
    int len;
  
    if (read_exact(buf, 2) != 2)
      return(-1);
    len = (buf[0] &lt;&lt; 8) | buf[1];
    return read_exact(buf, len);
  }
  
  write_cmd(byte *buf, int len)
  {
    byte li;
  
    li = (len &gt;&gt; 8) &amp; 0xff;
    write_exact(&amp;li, 1);
  
    li = len &amp; 0xff;
    write_exact(&amp;li, 1);
  
    return write_exact(buf, len);
  }
  
  read_exact(byte *buf, int len)
  {
    int i, got=0;
  
    do {
      if ((i = read(0, buf+got, len-got)) &lt;= 0)
        return(i);
      got += i;
    } while (got&lt;len);
  
    return(len);
  }
  
  write_exact(byte *buf, int len)
  {
    int i, wrote = 0;
  
    do {
      if ((i = write(1, buf+wrote, len-wrote)) &lt;= 0)
        return (i);
      wrote += i;
    } while (wrote&lt;len);
  
    return (len);
  }
  </code></pre>
  
  <p>and <code>port.c</code>:</p>
  
  <pre><code>/* port.c */
  
  typedef unsigned char byte;
  
  int main() {
    int fn, arg, res;
    byte buf[100];
  
    while (read_cmd(buf) &gt; 0) {
      fn = buf[0];
      arg = buf[1];
  
      if (fn == 1) {
        res = foo(arg);
      } else if (fn == 2) {
        res = bar(arg);
      }
  
      buf[0] = res;
      write_cmd(buf, 1);
    }
  }
  </code></pre>
  
  <p><strong>What does each function actually do there? What purpose do <code>li, len, i, wrote, got</code> variables actually serve?</strong></p>
  
  <p>Some more small questions:</p>
  
  <ol>
  <li>Why do not the functions have any return types, even <code>void</code>s?</li>
  <li>When Erlang port sends data to C, the first byte determines a function to be called. If the byte holds the decimal 1, then <code>foo()</code> is called, if the byte holds the decimal 2, then <code>bar()</code> is called. If not changed anyhow this protocol can be used to call up to 255 different C functions with only 1 parameter each. Is that right?</li>
  <li>"Adding the length indicator will be done automatically by the Erlang port, but must be done explicitly in the external C program".  What does that mean? On which line of code is it done?</li>
  <li>From the Tutorial: 
  "By default, the C program should read from standard input (file descriptor 0) and write to standard output (file descriptor 1)."
  Then: "Note that stdin and stdout are for buffered input/output and should not be used for the communication with Erlang!" What is the catch here?</li>
  <li>why <code>buf</code> is initialized to <code>[100]</code>?</li>
  </ol>