1/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
4
5#ifndef LIBRARIES_NACL_IO_NACL_IO_H_
6#define LIBRARIES_NACL_IO_NACL_IO_H_
7
8#include <ppapi/c/pp_instance.h>
9#include <ppapi/c/ppb.h>
10
11#include "nacl_io/ostypes.h"
12#include "sdk_util/macros.h"
13
14EXTERN_C_BEGIN
15
16typedef void (*nacl_io_exit_callback_t)(int status, void* user_data);
17
18typedef void (*nacl_io_mount_callback_t)(const char* source,
19                                         const char* target,
20                                         const char* filesystemtype,
21                                         unsigned long mountflags,
22                                         const void* data,
23                                         dev_t dev,
24                                         void* user_data);
25
26/**
27 * Initialize nacl_io.
28 *
29 * NOTE: If you initialize nacl_io with this constructor, you cannot
30 * use any filesystems that require PPAPI; e.g. persistent storage, etc.
31 */
32int nacl_io_init();
33
34/**
35 * Initialize nacl_io with PPAPI support.
36 *
37 * Usage:
38 *   PP_Instance instance;
39 *   PPB_GetInterface get_interface;
40 *   nacl_io_init(instance, get_interface);
41 *
42 * If you are using the PPAPI C interface:
43 *   |instance| is passed to your instance in the DidCreate function.
44 *   |get_interface| is passed to your module in the PPP_InitializeModule
45 *   function.
46 *
47 * If you are using the PPAPI C++ interface:
48 *   |instance| can be retrieved via the pp::Instance::pp_instance() method.
49 *   |get_interface| can be retrieved via
50 *       pp::Module::Get()->get_browser_interface()
51 */
52int nacl_io_init_ppapi(PP_Instance instance, PPB_GetInterface get_interface);
53
54/**
55 * Uninitialize nacl_io.
56 *
57 * This removes interception for POSIX C-library function and releases
58 * any associated resources.
59 */
60int nacl_io_uninit();
61
62void nacl_io_set_exit_callback(nacl_io_exit_callback_t exit_callback,
63                               void* user_data);
64
65/**
66 * Mount a new filesystem type.
67 *
68 * This function is declared in <sys/mount.h>, but we document it here
69 * because nacl_io is controlled primarily through mount(2)/umount(2).
70 *
71 * Some parameters are dependent on the filesystem type being mounted.
72 *
73 * The |data| parameter, if used, is always parsed as a string of comma
74 * separated key-value pairs:
75 *   e.g. "key1=param1,key2=param2"
76 *
77 *
78 * filesystem types:
79 *   "memfs": An in-memory filesystem.
80 *     source: Unused.
81 *     data: Unused.
82 *
83 *   "dev": A filesystem with various utility nodes. Some examples:
84 *          "null": equivalent to /dev/null.
85 *          "zero": equivalent to /dev/zero.
86 *          "urandom": equivalent to /dev/urandom.
87 *          "console[0-3]": logs to the JavaScript console with varying log
88 *              levels.
89 *          "tty": Posts a message to JavaScript, which will send a "message"
90 *              event from this module's embed element.
91 *     source: Unused.
92 *     data: Unused.
93 *
94 *   "html5fs": A filesystem that uses PPAPI FileSystem interface, which can be
95 *              read in JavaScript via the HTML5 FileSystem API. This filesystem
96 *              provides the use of persistent storage. Please read the
97 *              documentation in ppapi/c/ppb_file_system.h for more information.
98 *     source: Unused.
99 *     data: A string of parameters:
100 *       "type": Which type of filesystem to mount. Valid values are
101 *           "PERSISTENT" and "TEMPORARY". The default is "PERSISTENT".
102 *       "expected_size": The expected file-system size. Note that this does
103 *           not request quota -- you must do that from JavaScript.
104 *       "filesystem_resource": If specified, this is a string that contains
105 *           the integer ID of the Filesystem resource to use instead of
106 *           creating a new one. The "type" and "expected_size" parameters are
107 *           ignored in this case. This parameter is useful when you pass a
108 *           Filesystem resource from JavaScript, but still want to be able to
109 *           call open/read/write/etc.
110 *
111 *   "httpfs": A filesystem that reads from a URL via HTTP.
112 *     source: The root URL to read from. All paths read from this filesystem
113 *             will be appended to this root.
114 *             e.g. If source == "http://example.com/path", reading from
115 *             "foo/bar.txt" will attempt to read from the URL
116 *             "http://example.com/path/foo/bar.txt".
117 *     data: A string of parameters:
118 *       "allow_cross_origin_requests": If "true", then reads from this
119 *           filesystem will follow the CORS standard for cross-origin requests.
120 *           See http://www.w3.org/TR/access-control.
121 *       "allow_credentials": If "true", credentials are sent with cross-origin
122 *           requests. If false, no credentials are sent with the request and
123 *           cookies are ignored in the response.
124 *       All other key/value pairs are assumed to be headers to use with
125 *       HTTP requests.
126 *
127 *   "passthroughfs": A filesystem that passes all requests through to the
128 *                    underlying NaCl calls. The primary use of this filesystem
129 *                    is to allow reading NMF resources.
130 *     source: Unused.
131 *     data: Unused.
132 *
133 *
134 * @param[in] source Depends on the filesystem type. See above.
135 * @param[in] target The absolute path to mount the filesystem.
136 * @param[in] filesystemtype The name of the filesystem type to mount. See
137 *     above for examples.
138 * @param[in] mountflags Unused.
139 * @param[in] data Depends on the filesystem type. See above.
140 * @return 0 on success, -1 on failure (with errno set).
141 *
142 * int mount(const char* source, const char* target, const char* filesystemtype,
143 *         unsigned long mountflags, const void *data) NOTHROW;
144 */
145
146/**
147 * Register a new filesystem type, using a FUSE interface to implement it.
148 *
149 * Example:
150 *   int my_open(const char* path, struct fuse_file_info*) {
151 *     ...
152 *   }
153 *
154 *   int my_read(const char* path, char* buf, size_t count, off_t offset, struct
155 *               fuse_file_info* info) {
156 *     ...
157 *   }
158 *
159 *   struct fuse_operations my_fuse_ops = {
160 *     ...
161 *     my_open,
162 *     NULL,  // opendir() not implemented.
163 *     my_read,
164 *     ...
165 *   };
166 *
167 *   ...
168 *
169 *   const char fs_type[] = "my_fs";
170 *   int result = nacl_io_register_fs_type(fs_type, &my_fuse_ops);
171 *   if (!result) {
172 *     fprintf(stderr, "Error registering filesystem type %s.\n", fs_type);
173 *     exit(1);
174 *   }
175 *
176 *   ...
177 *
178 *   int result = mount("", "/fs/foo", fs_type, 0, NULL);
179 *   if (!result) {
180 *     fprintf(stderr, "Error mounting %s.\n", fs_type);
181 *     exit(1);
182 *   }
183 *
184 * See fuse.h for more information about the FUSE interface.
185 * Also see fuse.sourceforge.net for more information about FUSE in general.
186 *
187 * @param[in] fs_type The name of the new filesystem type.
188 * @param[in] fuse_ops A pointer to the FUSE interface that will be used to
189 *     implement this filesystem type. This pointer must be valid for the
190 *     lifetime of all filesystems and nodes that are created with it.
191 * @return 0 on success, -1 on failure (with errno set).
192 */
193struct fuse_operations;
194int nacl_io_register_fs_type(const char* fs_type,
195                             struct fuse_operations* fuse_ops);
196
197/**
198 * Unregister a filesystem type, previously registered by
199 * nacl_io_register_fs_type().
200 *
201 * @param[in] fs_type The name of the filesystem type; the same identifier that
202 *     was passed to nacl_io_register_fs_type().
203 * @return 0 on success, -1 on failure (with errno set).
204 */
205int nacl_io_unregister_fs_type(const char* fs_type);
206
207/**
208 * Set a mount callback.
209 *
210 * This callback is called whenever mount() succeeds. This callback can be used
211 * to get the dev number of the newly-mounted filesystem.
212 *
213 * @param[in] callback The callback to set, or NULL.
214 * @param[in] user_data User data that will be passed to the callback.
215 * @return 0 on success, -1 on failure.
216 */
217void nacl_io_set_mount_callback(nacl_io_mount_callback_t callback,
218                                void* user_data);
219
220EXTERN_C_END
221
222#endif /* LIBRARIES_NACL_IO_NACL_IO_H_ */
223