Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / devguide / coding / nacl_io.rst
1 .. _nacl_io:
2
3 ###################
4 The nacl_io Library
5 ###################
6
7 .. contents::
8   :local:
9   :backlinks: none
10   :depth: 2
11
12 Introduction
13 ============
14
15 ``nacl_io`` is a utility library that provides implementations of standard
16 C APIs such as POSIX I/O (``stdio.h``) and BSD sockets (``sys/socket.h``).
17 Its primary function is to allow code that uses these standard APIs to be
18 compiled and used in a Native Client module. The library is included as part
19 of Native Client SDK and is implemented in on top of Pepper API.
20
21 Since Native Client modules cannot access the host machine's file system
22 directly, nacl_io provides several alternative filesystem types which can be
23 used by the application. For example, the Chrome browser supports the `HTML5
24 File System API <http://www.html5rocks.com/en/tutorials/file/filesystem/>`_
25 which provides access to a protected area of the local file system. This
26 filesystem can be accessed by an HTML page using JavaScript commands, and also
27 by a Native Client module using the Pepper :doc:`File IO API <file-io>`.
28
29 With nacl_io a Native Client application can mount an HTML5 filesystem and
30 access it via standard POSIX I/O function such as ``fopen``, ``fseek``,
31 ``fread``, ``fwrite``, and ``fclose``, or their low level UNIX counterparts
32 ``open``, ``lseek``, ``read``, ``write`` and ``close``. As well as the HTML5
33 file system, nacl_io provides several other file system types which are
34 described in the table below:
35
36 =========== ==================================================================
37 File System Description
38 =========== ==================================================================
39 memfs       An in-memory file system
40 html5fs     An HTML5 local file system, which can be persistent or temporary
41 http        Maps files on a remote webserver into the local filesystem.
42 dev         A file system containing special files (e.g.: ``/dev/null``)
43 =========== ==================================================================
44
45 Using nacl_io
46 =============
47
48 Using nacl_io is mostly just a matter of using the standard POSIX C library
49 functions. However, there are some steps required to initialize the library
50 and setup the filesystem mounts. In general the following steps will be needed
51 to use nacl_io in a NaCl application:
52
53 #. Link the application with the nacl_io library (``-lnacl_io``)
54 #. Initialize nacl_io at startup using the ``nacl_io_init_ppapi`` or
55    ``nacl_io_init`` functions.
56 #. Mount any desired filesystems using the ``mount`` function. The arguments
57    to ``mount`` for the different filesystem types are detailed in
58    ``include/nacl_io/nacl_io.h``.
59 #. If you are going to mount an HTML5 file system, be sure to allocate space
60    for it. You can either set the ``unlimitedStorage`` permission in the app's
61    Web Store manifest file, or call the HTML5 QuotaManagement API. These
62    options are explained in the :ref:`File IO documentation <quota_management>`.
63 #. Make sure that file and socket API calls are all made from the background
64    thread. This is because the main Pepper thread does not support the blocking
65    behavior needed by the POSIX I/O operations.
66
67 Logging in nacl_io
68 ==================
69
70 Unlike most input/output for nacl_io, internal logging writes directly to the
71 ``stderr`` stream of the NaCl process. It deliberately bypasses the standard
72 library functions implemented in nacl_io to avoid circular calls to itself.
73
74 The nacl_io demo
75 ================
76
77 Building and running the demo
78 -----------------------------
79
80 The demo application launches a Native Client module that mounts three file
81 systems and displays a set of controls that let you work with them:
82
83 .. image:: /images/nacl_io1.png
84
85 Follow these steps to build and run the demo:
86
87 * Open a terminal in the demo directory::
88
89     $ cd $NACL_SDK_ROOT/examples/demo/nacl_io_demo
90
91 * run the demo::
92
93     $ make run
94
95 Once the demo is running, try these operations:
96
97 #. select the fopen command (when you select a command the fields in the line
98    below will change according to the command)
99 #. type in the filename ``/persistent/test``
100 #. check the write checkbox and press the fopen button
101 #. select the fwrite command and select the file ``/persistent/test`` in the
102    menu that appears below on the left
103 #. enter some data and press the fwrite button
104 #. select the fclose command, be sure the file ``/persistent/test`` is selected
105    in the menu, and press the fclose button
106 #. select the fopen command
107 #. type in the filename ``/persistent/test``
108 #. check the fread checkbox and press the fopen button
109 #. select the fread command, be sure the file /persistent/test is selected in
110    the menu, enter a byte count, and press the fread button
111
112 A look at the code
113 ------------------
114
115 The demo is written C and comprises three files.
116
117 nacl_io_demo.c
118 ^^^^^^^^^^^^^^
119
120 This is the demo's main file. The code here creates and initializes the Native
121 Client module instance. The Pepper function ``Instance_DidCreate`` initializes
122 nacl_io and mounts an HTML5 filesystem at ``/persistent``.
123
124 .. naclcode::
125
126   static PP_Bool Instance_DidCreate(PP_Instance instance,
127                                     uint32_t argc,
128                                     const char* argn[],
129                                     const char* argv[]) {
130     g_instance = instance;
131     nacl_io_init_ppapi(instance, get_browser_interface);
132     mount(
133         "",  /* source */
134         "/persistent",  /* target */
135         "html5fs",  /* filesystemtype */
136         0,  /* mountflags */
137         "type=PERSISTENT,expected_size=1048576");  /* data specific to the html5fs type */
138
139     pthread_create(&g_handle_message_thread, NULL, &HandleMessageThread, NULL);
140     InitializeMessageQueue();
141
142     return PP_TRUE;
143   }
144
145 Space is allocated to the ``/persistent`` file system after the module is
146 initialized. This is accomplished by the ``domContentLoaded`` function in
147 the file ``example.js``. This script is included in the module's html page (see
148 ``examples/demo/index.html``):
149
150 .. naclcode::
151
152   function domContentLoaded(name, tc, config, width, height) {
153     navigator.webkitPersistentStorage.requestQuota(window.PERSISTENT, 1024 * 1024,
154         function(bytes) {
155           common.updateStatus(
156               'Allocated ' + bytes + ' bytes of persistant storage.');
157           common.createNaClModule(name, tc, config, width, height);
158           common.attachDefaultListeners();
159         },
160         function(e) { alert('Failed to allocate space') });
161   }
162
163 The ``Instance_DidCreate`` function also creates a worker thread that receives
164 messages sent from the html page and performs the specified file system
165 operations. The logic for the worker thread is encoded in the other two files,
166 described below.
167
168 queue.c
169 ^^^^^^^
170
171 This file implements a circular queue that is used to receive messages from the
172 browser UI to the Native Client module. The file system commands in the
173 enqueued messages are executed on the worker thread. This keeps blocking calls
174 (like fread) off the main Native Client thread, which is a good thing. The
175 queue is initialized in nacl_io_demo.c ``Instance_DidCreate``.
176
177 handlers.c
178 ^^^^^^^^^^
179
180 This file implements the stdio calls associated with the commands sent from the
181 browser. There is a separate ``Handle*`` function for each command: fopen,
182 fclose, fseek, fread, fwrite. The handlers are called from the
183 ``HandleMessage`` function in nacl_io_demo.c, which runs in the worker
184 thread managing the message queue. The code for the ``fwrite`` handler appears
185 below. Notice that it does not contain any PPAPI calls and looks like
186 "ordinary" C code.
187
188
189 .. naclcode::
190
191   int HandleFwrite(int num_params, char** params, char** output) {
192     FILE* file;
193     const char* file_index_string;
194     const char* data;
195     size_t data_len;
196     size_t bytes_written;
197
198     if (num_params != 2) {
199       *output = PrintfToNewString("Error: fwrite takes 2 parameters.");
200       return 1;
201     }
202
203     file_index_string = params[0];
204     file = GetFileFromIndexString(file_index_string, NULL);
205     data = params[1];
206     data_len = strlen(data);
207
208     if (!file) {
209       *output = PrintfToNewString("Error: Unknown file handle %s.",
210                                   file_index_string);
211       return 2;
212     }
213
214     bytes_written = fwrite(data, 1, data_len, file);
215
216     *output = PrintfToNewString("fwrite\1%s\1%d", file_index_string,
217                                 bytes_written);
218     return 0;
219   }
220
221 Reference Information
222 =====================
223
224 The example discussed here is included in the SDK in the directory
225 ``examples/demo/nacl_io_demo``.
226
227 The nacl_io library is included in the SDK toolchain and is not a part of the
228 Pepper API. For reference information related to the nacl_io interface see
229 its header file in the SDK directory, located at
230 ``include/nacl_io/nacl_io.h``.
231
232 For more about the HTML5 file system read the `specification
233 <http://dev.w3.org/2009/dap/file-system/pub/FileSystem/>`_.