~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to system/doc/tutorial/cnode.xmlsrc

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="latin1" ?>
 
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
 
3
 
 
4
<chapter>
 
5
  <header>
 
6
    <copyright>
 
7
      <year>2000</year><year>2009</year>
 
8
      <holder>Ericsson AB. All Rights Reserved.</holder>
 
9
    </copyright>
 
10
    <legalnotice>
 
11
      The contents of this file are subject to the Erlang Public License,
 
12
      Version 1.1, (the "License"); you may not use this file except in
 
13
      compliance with the License. You should have received a copy of the
 
14
      Erlang Public License along with this software. If not, it can be
 
15
      retrieved online at http://www.erlang.org/.
 
16
    
 
17
      Software distributed under the License is distributed on an "AS IS"
 
18
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
19
      the License for the specific language governing rights and limitations
 
20
      under the License.
 
21
    
 
22
    </legalnotice>
 
23
 
 
24
    <title>C Nodes</title>
 
25
    <prepared></prepared>
 
26
    <docno></docno>
 
27
    <date></date>
 
28
    <rev></rev>
 
29
    <file>cnode.xml</file>
 
30
  </header>
 
31
  <p>This is an example of how to solve the <seealso marker="example">example problem</seealso> by using a C node. Note that a C node would not typically be used for solving a simple problem like this, a port would suffice.</p>
 
32
 
 
33
  <section>
 
34
    <title>Erlang Program</title>
 
35
    <p>From Erlang's point of view, the C node is treated like a normal Erlang node. Therefore, calling the functions <c>foo</c> and <c>bar</c> only involves sending a message to the C node asking for the function to be called, and receiving the result. Sending a message requires a recipient; a process which can be defined using either a pid or a tuple consisting of a registered name and a node name. In this case a tuple is the only alternative as no pid is known.</p>
 
36
    <pre>
 
37
{RegName, Node} ! Msg</pre>
 
38
    <p>The node name <c>Node</c> should be the name of the C node. If short node names are used, the plain name of the node will be <c>cN</c> where <c>N</c> is an integer. If long node names are used, there is no such restriction. An example of a C node name using short node names is thus <c>c1@idril</c>, an example using long node names is <c>cnode@idril.ericsson.se</c>.</p>
 
39
    <p>The registered name <c>RegName</c> could be any atom. The name can be ignored by the C code, or it could be used for example to distinguish between different types of messages. Below is an example of what the Erlang code could look like when using short node names. 
 
40
      </p>
 
41
    <codeinclude file="complex3.erl" tag="" type="erl"></codeinclude>
 
42
    <p>
 
43
      When using long node names the code is slightly different as shown in the following example:
 
44
    </p>
 
45
    <codeinclude file="complex4.erl" tag="" type="erl"></codeinclude>
 
46
 
 
47
  </section>
 
48
 
 
49
  <section>
 
50
    <title>C Program</title>
 
51
 
 
52
    <section>
 
53
      <title>Setting Up the Communication</title>
 
54
      <p>Before calling any other Erl_Interface function, the memory handling must be initiated.</p>
 
55
      <pre>
 
56
erl_init(NULL, 0);</pre>
 
57
      <p>Now the C node can be initiated. If short node names are used, this is done by calling <c>erl_connect_init()</c>.</p>
 
58
      <pre>
 
59
erl_connect_init(1, "secretcookie", 0);</pre>
 
60
      <p>The first argument is the integer which is used to construct the node name. In the example the plain node name will be <c>c1</c>.        <br></br>
 
61
 
 
62
        The second argument is a string defining the magic cookie.        <br></br>
 
63
 
 
64
        The third argument is an integer which is used to identify a particular instance of a C node.</p>
 
65
      <p>If long node node names are used, initiation is done by calling <c>erl_connect_xinit()</c>.</p>
 
66
      <pre>
 
67
erl_connect_xinit("idril", "cnode", "cnode@idril.ericsson.se",
 
68
                  &amp;addr, "secretcookie", 0);</pre>
 
69
      <p>The first three arguments are the host name, the plain node name, and the full node name. The fourth argument is a pointer to an <c>in_addr</c> struct with the IP address of the host, and the fifth and sixth arguments are the magic cookie and instance number.</p>
 
70
      <p>The C node can act as a server or a client when setting up the communication Erlang-C. If it acts as a client, it connects to an Erlang node by calling <c>erl_connect()</c>, which will return an open file descriptor at success.</p>
 
71
      <pre>
 
72
fd = erl_connect("e1@idril");</pre>
 
73
      <p>If the C node acts as a server, it must first create a socket (call <c>bind()</c> and <c>listen()</c>) listening to a certain port number <c>port</c>. It then publishes its name and port number with <c>epmd</c> (the Erlang port mapper daemon, see the man page for <c>epmd</c>).</p>
 
74
      <pre>
 
75
erl_publish(port);</pre>
 
76
      <p>Now the C node server can accept connections from Erlang nodes.</p>
 
77
      <pre>
 
78
fd = erl_accept(listen, &amp;conn);</pre>
 
79
      <p>The second argument to <c>erl_accept</c> is a struct <c>ErlConnect</c> that will contain useful information when a connection has been established; for example, the name of the Erlang node.</p>
 
80
    </section>
 
81
 
 
82
    <section>
 
83
      <title>Sending and Receiving Messages</title>
 
84
      <p>The C node can receive a message from Erlang by calling <c>erl_receive msg()</c>. This function reads data from the open file descriptor <c>fd</c> into a buffer and puts the result in an <c>ErlMessage</c> struct <c>emsg</c>. <c>ErlMessage</c> has a field <c>type</c> defining which kind of data was received. In this case the type of interest is <c>ERL_REG_SEND</c> which indicates that Erlang sent a message to a registered process at the C node. The actual message, an <c>ETERM</c>, will be in the <c>msg</c> field.</p>
 
85
      <p>It is also necessary to take care of the types <c>ERL_ERROR</c> (an error occurred) and <c>ERL_TICK</c> (alive check from other node, should be ignored). Other possible types indicate process events such as link/unlink and exit.</p>
 
86
      <pre>
 
87
  while (loop) {
 
88
 
 
89
    got = erl_receive_msg(fd, buf, BUFSIZE, &amp;emsg);
 
90
    if (got == ERL_TICK) {
 
91
      /* ignore */
 
92
    } else if (got == ERL_ERROR) {
 
93
      loop = 0; /* exit while loop */
 
94
    } else {
 
95
      if (emsg.type == ERL_REG_SEND) {</pre>
 
96
      <p>Since the message is an <c>ETERM</c> struct, Erl_Interface functions can be used to manipulate it. In this case, the message will be a 3-tuple (because that was how the Erlang code was written, see above). The second element will be the pid of the caller and the third element will be the tuple <c>{Function,Arg}</c> determining which function to call with which argument. The result of calling the function is made into an <c>ETERM</c> struct as well and sent back to Erlang using <c>erl_send()</c>, which takes the open file descriptor, a pid and a term as arguments.</p>
 
97
      <pre>
 
98
        fromp = erl_element(2, emsg.msg);
 
99
        tuplep = erl_element(3, emsg.msg);
 
100
        fnp = erl_element(1, tuplep);
 
101
        argp = erl_element(2, tuplep);
 
102
 
 
103
        if (strncmp(ERL_ATOM_PTR(fnp), "foo", 3) == 0) {
 
104
          res = foo(ERL_INT_VALUE(argp));
 
105
        } else if (strncmp(ERL_ATOM_PTR(fnp), "bar", 3) == 0) {
 
106
          res = bar(ERL_INT_VALUE(argp));
 
107
        }
 
108
 
 
109
        resp = erl_format("{cnode, ~i}", res);
 
110
        erl_send(fd, fromp, resp);</pre>
 
111
      <p>Finally, the memory allocated by the <c>ETERM</c> creating functions (including <c>erl_receive_msg()</c> must be freed.</p>
 
112
      <pre>
 
113
        erl_free_term(emsg.from); erl_free_term(emsg.msg);
 
114
        erl_free_term(fromp); erl_free_term(tuplep);
 
115
        erl_free_term(fnp); erl_free_term(argp);
 
116
        erl_free_term(resp);</pre>
 
117
      <p>The resulting C programs can be found in looks like the following examples. First a C node server using short node names.</p>
 
118
      <codeinclude file="cnode_s.c" type="c"/>
 
119
      <p>Below follows a C node server using long node names.</p>
 
120
      <codeinclude file="cnode_s2.c" type="c"/>
 
121
      <p>And finally we have the code for the C node client.</p>
 
122
      <codeinclude file="cnode_c.c" type="c"/>
 
123
    </section>
 
124
  </section>
 
125
 
 
126
  <section>
 
127
    <title>Running the Example</title>
 
128
    <p>1. Compile the C code, providing the paths to the Erl_Interface include files and libraries, and to the <c>socket</c> and <c>nsl</c> libraries.</p>
 
129
    <p>In R5B and later versions of OTP, the <c>include</c> and <c>lib</c> directories are situated under <c>OTPROOT/lib/erl_interface-VSN</c>, where <c>OTPROOT</c> is the root directory of the OTP installation (<c>/usr/local/otp</c> in the example above) and <c>VSN</c> is the version of the <c>erl_interface</c> application (3.2.1 in the example above).      <br></br>
 
130
 
 
131
      In R4B and earlier versions of OTP, <c>include</c> and <c>lib</c> are situated under <c>OTPROOT/usr</c>.</p>
 
132
    <pre>
 
133
      
 
134
>  <input>gcc -o cserver \\ </input>
 
135
<input>-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </input>
 
136
<input>-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
 
137
<input>complex.c cnode_s.c \\ </input>
 
138
<input>-lerl_interface -lei -lsocket -lnsl</input>
 
139
 
 
140
unix> <input>gcc -o cserver2 \\ </input>
 
141
<input>-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </input>
 
142
<input>-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
 
143
<input>complex.c cnode_s2.c \\ </input>
 
144
<input>-lerl_interface -lei -lsocket -lnsl</input>
 
145
 
 
146
unix> <input>gcc -o cclient \\ </input>
 
147
<input>-I/usr/local/otp/lib/erl_interface-3.2.1/include \\ </input>
 
148
<input>-L/usr/local/otp/lib/erl_interface-3.2.1/lib \\ </input>
 
149
<input>complex.c cnode_c.c \\ </input>
 
150
<input>-lerl_interface -lei -lsocket -lnsl</input></pre>
 
151
    <p>2. Compile the Erlang code.</p>
 
152
    <pre>
 
153
unix> <input>erl -compile complex3 complex4</input></pre>
 
154
    <p>3. Run the C node server example with short node names.</p>
 
155
    <p>Start the C program <c>cserver</c> and Erlang in different windows. <c>cserver</c> takes a port number as argument and must be started before trying to call the Erlang functions. The Erlang node should be given the short name <c>e1</c> and must be set to use the same magic cookie as the C node, <c>secretcookie</c>.</p>
 
156
    <pre>
 
157
unix> <input>cserver 3456</input>
 
158
 
 
159
unix> <input>erl -sname e1 -setcookie secretcookie</input>
 
160
Erlang (BEAM) emulator version 4.9.1.2
 
161
 
 
162
Eshell V4.9.1.2  (abort with ^G)
 
163
(e1@idril)1> <input>complex3:foo(3).</input>
 
164
4
 
165
(e1@idril)2> <input>complex3:bar(5).</input>
 
166
10</pre>
 
167
    <p>4. Run the C node client example. Terminate <c>cserver</c> but not Erlang and start <c>cclient</c>. The Erlang node must be started before the C node client is.</p>
 
168
    <pre>
 
169
unix> <input>cclient</input>
 
170
 
 
171
(e1@idril)3> <input>complex3:foo(3).</input>
 
172
4
 
173
(e1@idril)4> <input>complex3:bar(5).</input>
 
174
10</pre>
 
175
    <p>5. Run the C node server, long node names, example.</p>
 
176
    <pre>
 
177
unix> <input>cserver2 3456</input>
 
178
 
 
179
unix> <input>erl -name e1 -setcookie secretcookie</input>
 
180
Erlang (BEAM) emulator version 4.9.1.2
 
181
 
 
182
Eshell V4.9.1.2  (abort with ^G)
 
183
(e1@idril.du.uab.ericsson.se)1> <input>complex4:foo(3).</input>
 
184
4
 
185
(e1@idril.du.uab.ericsson.se)2> <input>complex4:bar(5).</input>
 
186
10</pre>
 
187
  </section>
 
188
</chapter>
 
189