|  | {{+bindTo:partials.standard_nacl_article}} | 
|  |  | 
|  | <section id="the-nacl-io-library"> | 
|  | <span id="nacl-io"></span><h1 id="the-nacl-io-library"><span id="nacl-io"></span>The nacl_io Library</h1> | 
|  | <div class="contents local" id="contents" style="display: none"> | 
|  | <ul class="small-gap"> | 
|  | <li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li> | 
|  | <li><a class="reference internal" href="#using-nacl-io" id="id2">Using nacl_io</a></li> | 
|  | <li><a class="reference internal" href="#logging-in-nacl-io" id="id3">Logging in nacl_io</a></li> | 
|  | <li><p class="first"><a class="reference internal" href="#the-nacl-io-demo" id="id4">The nacl_io demo</a></p> | 
|  | <ul class="small-gap"> | 
|  | <li><a class="reference internal" href="#building-and-running-the-demo" id="id5">Building and running the demo</a></li> | 
|  | <li><a class="reference internal" href="#a-look-at-the-code" id="id6">A look at the code</a></li> | 
|  | </ul> | 
|  | </li> | 
|  | <li><a class="reference internal" href="#reference-information" id="id7">Reference Information</a></li> | 
|  | </ul> | 
|  |  | 
|  | </div><h2 id="introduction">Introduction</h2> | 
|  | <p><code>nacl_io</code> is a utility library that provides implementations of standard | 
|  | C APIs such as POSIX I/O (<code>stdio.h</code>) and BSD sockets (<code>sys/socket.h</code>). | 
|  | Its primary function is to allow code that uses these standard APIs to be | 
|  | compiled and used in a Native Client module. The library is included as part | 
|  | of Native Client SDK and is implemented in on top of Pepper API.</p> | 
|  | <p>Since Native Client modules cannot access the host machine’s file system | 
|  | directly, nacl_io provides several alternative filesystem types which can be | 
|  | used by the application. For example, the Chrome browser supports the <a class="reference external" href="http://www.html5rocks.com/en/tutorials/file/filesystem/">HTML5 | 
|  | File System API</a> | 
|  | which provides access to a protected area of the local file system. This | 
|  | filesystem can be accessed by an HTML page using JavaScript commands, and also | 
|  | by a Native Client module using the Pepper <a class="reference internal" href="/native-client/devguide/coding/file-io.html"><em>File IO API</em></a>.</p> | 
|  | <p>With nacl_io a Native Client application can mount an HTML5 filesystem and | 
|  | access it via standard POSIX I/O function such as <code>fopen</code>, <code>fseek</code>, | 
|  | <code>fread</code>, <code>fwrite</code>, and <code>fclose</code>, or their low level UNIX counterparts | 
|  | <code>open</code>, <code>lseek</code>, <code>read</code>, <code>write</code> and <code>close</code>. As well as the HTML5 | 
|  | file system, nacl_io provides several other file system types which are | 
|  | described in the table below:</p> | 
|  | <table border="1" class="docutils"> | 
|  | <colgroup> | 
|  | </colgroup> | 
|  | <thead valign="bottom"> | 
|  | <tr class="row-odd"><th class="head">File System</th> | 
|  | <th class="head">Description</th> | 
|  | </tr> | 
|  | </thead> | 
|  | <tbody valign="top"> | 
|  | <tr class="row-even"><td>memfs</td> | 
|  | <td>An in-memory file system</td> | 
|  | </tr> | 
|  | <tr class="row-odd"><td>html5fs</td> | 
|  | <td>An HTML5 local file system, which can be persistent or temporary</td> | 
|  | </tr> | 
|  | <tr class="row-even"><td>http</td> | 
|  | <td>Maps files on a remote webserver into the local filesystem.</td> | 
|  | </tr> | 
|  | <tr class="row-odd"><td>dev</td> | 
|  | <td>A file system containing special files (e.g.: <code>/dev/null</code>)</td> | 
|  | </tr> | 
|  | </tbody> | 
|  | </table> | 
|  | <h2 id="using-nacl-io">Using nacl_io</h2> | 
|  | <p>Using nacl_io is mostly just a matter of using the standard POSIX C library | 
|  | functions. However, there are some steps required to initialize the library | 
|  | and setup the filesystem mounts. In general the following steps will be needed | 
|  | to use nacl_io in a NaCl application:</p> | 
|  | <ol class="arabic simple"> | 
|  | <li>Link the application with the nacl_io library (<code>-lnacl_io</code>)</li> | 
|  | <li>Initialize nacl_io at startup using the <code>nacl_io_init_ppapi</code> or | 
|  | <code>nacl_io_init</code> functions.</li> | 
|  | <li>Mount any desired filesystems using the <code>mount</code> function. The arguments | 
|  | to <code>mount</code> for the different filesystem types are detailed in | 
|  | <code>include/nacl_io/nacl_io.h</code>.</li> | 
|  | <li>If you are going to mount an HTML5 file system, be sure to allocate space | 
|  | for it. You can either set the <code>unlimitedStorage</code> permission in the app’s | 
|  | Web Store manifest file, or call the HTML5 QuotaManagement API. These | 
|  | options are explained in the <a class="reference internal" href="/native-client/devguide/coding/file-io.html#quota-management"><em>File IO documentation</em></a>.</li> | 
|  | <li>Make sure that file and socket API calls are all made from the background | 
|  | thread. This is because the main Pepper thread does not support the blocking | 
|  | behavior needed by the POSIX I/O operations.</li> | 
|  | </ol> | 
|  | <h2 id="logging-in-nacl-io">Logging in nacl_io</h2> | 
|  | <p>Unlike most input/output for nacl_io, internal logging writes directly to the | 
|  | <code>stderr</code> stream of the NaCl process. It deliberately bypasses the standard | 
|  | library functions implemented in nacl_io to avoid circular calls to itself.</p> | 
|  | <h2 id="the-nacl-io-demo">The nacl_io demo</h2> | 
|  | <h3 id="building-and-running-the-demo">Building and running the demo</h3> | 
|  | <p>The demo application launches a Native Client module that mounts three file | 
|  | systems and displays a set of controls that let you work with them:</p> | 
|  | <img alt="/native-client/images/nacl_io1.png" src="/native-client/images/nacl_io1.png" /> | 
|  | <p>Follow these steps to build and run the demo:</p> | 
|  | <ul class="small-gap"> | 
|  | <li><p class="first">Open a terminal in the demo directory:</p> | 
|  | <pre class="prettyprint"> | 
|  | $ cd $NACL_SDK_ROOT/examples/demo/nacl_io_demo | 
|  | </pre> | 
|  | </li> | 
|  | <li><p class="first">run the demo:</p> | 
|  | <pre class="prettyprint"> | 
|  | $ make run | 
|  | </pre> | 
|  | </li> | 
|  | </ul> | 
|  | <p>Once the demo is running, try these operations:</p> | 
|  | <ol class="arabic simple"> | 
|  | <li>select the fopen command (when you select a command the fields in the line | 
|  | below will change according to the command)</li> | 
|  | <li>type in the filename <code>/persistent/test</code></li> | 
|  | <li>check the write checkbox and press the fopen button</li> | 
|  | <li>select the fwrite command and select the file <code>/persistent/test</code> in the | 
|  | menu that appears below on the left</li> | 
|  | <li>enter some data and press the fwrite button</li> | 
|  | <li>select the fclose command, be sure the file <code>/persistent/test</code> is selected | 
|  | in the menu, and press the fclose button</li> | 
|  | <li>select the fopen command</li> | 
|  | <li>type in the filename <code>/persistent/test</code></li> | 
|  | <li>check the fread checkbox and press the fopen button</li> | 
|  | <li>select the fread command, be sure the file /persistent/test is selected in | 
|  | the menu, enter a byte count, and press the fread button</li> | 
|  | </ol> | 
|  | <h3 id="a-look-at-the-code">A look at the code</h3> | 
|  | <p>The demo is written C and comprises three files.</p> | 
|  | <h4 id="nacl-io-demo-c">nacl_io_demo.c</h4> | 
|  | <p>This is the demo’s main file. The code here creates and initializes the Native | 
|  | Client module instance. The Pepper function <code>Instance_DidCreate</code> initializes | 
|  | nacl_io and mounts an HTML5 filesystem at <code>/persistent</code>.</p> | 
|  | <pre class="prettyprint"> | 
|  | static PP_Bool Instance_DidCreate(PP_Instance instance, | 
|  | uint32_t argc, | 
|  | const char* argn[], | 
|  | const char* argv[]) { | 
|  | g_instance = instance; | 
|  | nacl_io_init_ppapi(instance, get_browser_interface); | 
|  | mount( | 
|  | "",  /* source */ | 
|  | "/persistent",  /* target */ | 
|  | "html5fs",  /* filesystemtype */ | 
|  | 0,  /* mountflags */ | 
|  | "type=PERSISTENT,expected_size=1048576");  /* data specific to the html5fs type */ | 
|  |  | 
|  | pthread_create(&g_handle_message_thread, NULL, &HandleMessageThread, NULL); | 
|  | InitializeMessageQueue(); | 
|  |  | 
|  | return PP_TRUE; | 
|  | } | 
|  | </pre> | 
|  | <p>Space is allocated to the <code>/persistent</code> file system after the module is | 
|  | initialized. This is accomplished by the <code>domContentLoaded</code> function in | 
|  | the file <code>example.js</code>. This script is included in the module’s html page (see | 
|  | <code>examples/demo/index.html</code>):</p> | 
|  | <pre class="prettyprint"> | 
|  | function domContentLoaded(name, tc, config, width, height) { | 
|  | navigator.webkitPersistentStorage.requestQuota(window.PERSISTENT, 1024 * 1024, | 
|  | function(bytes) { | 
|  | common.updateStatus( | 
|  | 'Allocated ' + bytes + ' bytes of persistant storage.'); | 
|  | common.createNaClModule(name, tc, config, width, height); | 
|  | common.attachDefaultListeners(); | 
|  | }, | 
|  | function(e) { alert('Failed to allocate space') }); | 
|  | } | 
|  | </pre> | 
|  | <p>The <code>Instance_DidCreate</code> function also creates a worker thread that receives | 
|  | messages sent from the html page and performs the specified file system | 
|  | operations. The logic for the worker thread is encoded in the other two files, | 
|  | described below.</p> | 
|  | <h4 id="queue-c">queue.c</h4> | 
|  | <p>This file implements a circular queue that is used to receive messages from the | 
|  | browser UI to the Native Client module. The file system commands in the | 
|  | enqueued messages are executed on the worker thread. This keeps blocking calls | 
|  | (like fread) off the main Native Client thread, which is a good thing. The | 
|  | queue is initialized in nacl_io_demo.c <code>Instance_DidCreate</code>.</p> | 
|  | <h4 id="handlers-c">handlers.c</h4> | 
|  | <p>This file implements the stdio calls associated with the commands sent from the | 
|  | browser. There is a separate <code>Handle*</code> function for each command: fopen, | 
|  | fclose, fseek, fread, fwrite. The handlers are called from the | 
|  | <code>HandleMessage</code> function in nacl_io_demo.c, which runs in the worker | 
|  | thread managing the message queue. The code for the <code>fwrite</code> handler appears | 
|  | below. Notice that it does not contain any PPAPI calls and looks like | 
|  | “ordinary” C code.</p> | 
|  | <pre class="prettyprint"> | 
|  | int HandleFwrite(int num_params, char** params, char** output) { | 
|  | FILE* file; | 
|  | const char* file_index_string; | 
|  | const char* data; | 
|  | size_t data_len; | 
|  | size_t bytes_written; | 
|  |  | 
|  | if (num_params != 2) { | 
|  | *output = PrintfToNewString("Error: fwrite takes 2 parameters."); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | file_index_string = params[0]; | 
|  | file = GetFileFromIndexString(file_index_string, NULL); | 
|  | data = params[1]; | 
|  | data_len = strlen(data); | 
|  |  | 
|  | if (!file) { | 
|  | *output = PrintfToNewString("Error: Unknown file handle %s.", | 
|  | file_index_string); | 
|  | return 2; | 
|  | } | 
|  |  | 
|  | bytes_written = fwrite(data, 1, data_len, file); | 
|  |  | 
|  | *output = PrintfToNewString("fwrite\1%s\1%d", file_index_string, | 
|  | bytes_written); | 
|  | return 0; | 
|  | } | 
|  | </pre> | 
|  | <h2 id="reference-information">Reference Information</h2> | 
|  | <p>The example discussed here is included in the SDK in the directory | 
|  | <code>examples/demo/nacl_io_demo</code>.</p> | 
|  | <p>The nacl_io library is included in the SDK toolchain and is not a part of the | 
|  | Pepper API. For reference information related to the nacl_io interface see | 
|  | its header file in the SDK directory, located at | 
|  | <code>include/nacl_io/nacl_io.h</code>.</p> | 
|  | <p>For more about the HTML5 file system read the <a class="reference external" href="http://dev.w3.org/2009/dap/file-system/pub/FileSystem/">specification</a>.</p> | 
|  | </section> | 
|  |  | 
|  | {{/partials.standard_nacl_article}} |