1 /*
2  * Copyright (C) 2015-2019 Alibaba Group Holding Limited
3  */
4 
5 #include "amp_config.h"
6 #include "aos_fs.h"
7 #include "amp_defines.h"
8 #include "aos_system.h"
9 #include "be_inl.h"
10 
11 #define MOD_STR "FS"
check_fs_is_support()12 static int check_fs_is_support()
13 {
14     int ret;
15 	int fp;
16     const char *string = "test if fs mount ok";
17     char testfile[64]  = {0};
18 
19     snprintf(testfile, sizeof(testfile), AMP_FS_ROOT_DIR"/%s", "testfile.txt");
20     fp = aos_open(testfile, O_RDWR | O_CREAT | O_TRUNC);
21     if (fp < 0) {
22         amp_warn(MOD_STR, "check_fs_is_support open fail\n");
23         return 0;
24     }
25 
26     ret = aos_write(fp, (char *)string, strlen(string));
27     if (ret <= 0) {
28         amp_warn(MOD_STR, "check_fs_is_support write fail\n");
29         aos_close(fp);
30         return 0;
31     }
32 
33     aos_close(fp);
34 
35     ret = aos_remove(testfile);
36     if (ret) {
37         amp_warn(MOD_STR, "check_fs_is_support sync fail\n");
38         return 0;
39     }
40 
41     return 1;
42 }
43 
44 /*****************************************************************************
45  * Function:    native_fs_issupport
46  * Description: js native addon for FILE.issupport()
47  *            check if the js FILE object is support
48  * Called by:   js api
49  * Input:       none
50  * Output:      1 :support ,0 :not support
51  *****************************************************************************/
native_fs_is_support(duk_context * ctx)52 static duk_ret_t native_fs_is_support(duk_context *ctx)
53 {
54     int ret;
55     ret = check_fs_is_support();
56     duk_push_int(ctx, ret);
57     return 1;
58 }
59 
60 /*****************************************************************************
61  * Function:    native_fs_read
62  * Description: js native addon for FILE.read(filepath)
63  *            read the file content
64  * Called by:   js api
65  * Input:       filepath : string
66  * Output:      a String object which the file content is
67  *****************************************************************************/
native_fs_read(duk_context * ctx)68 static duk_ret_t native_fs_read(duk_context *ctx)
69 {
70     int fp   = -1;
71     int len  = 0;
72     int size = 0;
73     const char *path;
74     char *buf = NULL;
75 
76     if (!duk_is_string(ctx, 0)) {
77         amp_warn(MOD_STR, "invalid parameter\n");
78         goto out;
79     }
80 
81     path = duk_get_string(ctx, 0);
82     fp   = aos_open(path, O_RDONLY);
83     if (fp < 0) {
84         amp_warn(MOD_STR, "jse_open failed\n");
85         goto out;
86     }
87 
88     size = aos_lseek(fp, 0, HAL_SEEK_END);
89 
90     aos_lseek(fp, 0, HAL_SEEK_SET);
91 
92     buf = (char *)aos_malloc(size + 1);
93     if (!buf) {
94         amp_warn(MOD_STR, "malloc failed\n");
95         aos_close(fp);
96         goto out;
97     }
98 
99     len = aos_read(fp, buf, size);
100     if (len > 0) {
101         buf[len] = 0;
102         amp_debug(MOD_STR, "read data: %s\n", buf);
103     }
104     aos_close(fp);
105 
106 out:
107     if (len > 0)
108         duk_push_string(ctx, buf);
109     else
110         duk_push_undefined(ctx);
111     aos_free(buf);
112     return 1;
113 }
114 
115 /*****************************************************************************
116  * Function:    native_fs_write
117  * Description: js native addon for FILE.write(filepath,buffer,mode)
118  *            write the content to the file
119  * Called by:   js api
120  * Input:       filepath : string ;
121  *            buffer: the content buffer which is a String object
122  *            mode: could be "w","r","w+","r+","a","a+"
123  * Output:      0 write ok ;other write fail
124  *****************************************************************************/
native_fs_write(duk_context * ctx)125 static duk_ret_t native_fs_write(duk_context *ctx)
126 {
127     int ret = -1;
128     int fp = -1;
129     size_t str_len = 0;
130     size_t nwrite  = 0;
131     const char *path;
132     const char *content;
133     const char *flag;
134     int   aos_flag = 0, m = 0;
135 
136     if (!duk_is_string(ctx, 0) || !duk_is_string(ctx, 1) || !duk_is_object(ctx, 2)) {
137         amp_warn(MOD_STR, "parameter must be [string, string, object]\n");
138         goto out;
139     }
140 
141     path = duk_get_string(ctx, 0);
142     content = duk_get_lstring(ctx, 1, &str_len);
143 
144  /* get device certificate */
145     duk_get_prop_string(ctx, 2, "flag");
146 
147     if (!duk_is_string(ctx, -1))
148     {
149         amp_warn(MOD_STR, "Parameter must be an object like {flag: string}");
150         ret = -1;
151         goto out;
152     }
153 
154     flag  = duk_get_string(ctx, -1);
155 
156     switch (flag[0]) {
157         case 'r':
158             m = O_RDONLY;
159             aos_flag = 0;
160             break;
161 
162         case 'w':
163             m = O_WRONLY;
164             aos_flag = O_CREAT | O_TRUNC;
165             break;
166 
167         case 'a':
168             m = O_WRONLY;
169             aos_flag = O_CREAT | O_APPEND;
170             break;
171          default:
172             return -1;
173             goto out;
174     }
175 
176     while (*++flag) {
177         switch (*flag) {
178             case '+':
179                 m = (m & ~O_ACCMODE) | O_RDWR;
180                 break;
181             default:
182                 break;
183         }
184     }
185     aos_flag = m | aos_flag;
186 
187     fp   = aos_open(path, aos_flag);
188     if (fp < 0) {
189         amp_error(MOD_STR, "be_osal_open fail\n");
190         goto out;
191     }
192 
193     nwrite = aos_write(fp, (char *)content, str_len);
194     if (nwrite <= 0) {
195         amp_error(MOD_STR, "be_osal_write fail\n");
196         aos_close(fp);
197         goto out;
198     }
199 
200     amp_debug(MOD_STR, "FS.write(%s,%s,%s);\n", path, content, flag);
201 
202     aos_sync(fp);
203     aos_close(fp);
204 
205 out:
206     duk_push_int(ctx, nwrite == str_len ? 0 : -1);
207     return 1;
208 }
209 
210 /*****************************************************************************
211  * Function:    native_fs_delete
212  * Description: js native addon for FILE.delete(filepath)
213  *            delete the file
214  * Called by:   js api
215  * Input:       filepath : string
216  * Output:      0 delete ok ;other delete fail
217  *****************************************************************************/
native_fs_delete(duk_context * ctx)218 static duk_ret_t native_fs_delete(duk_context *ctx)
219 {
220     int ret = -1;
221     const char *path;
222 
223     if (!duk_is_string(ctx, 0)) {
224         amp_warn(MOD_STR, "invalid parameter\n");
225         goto out;
226     }
227 
228     path = duk_get_string(ctx, 0);
229     ret  = aos_remove(path);
230 
231 out:
232     duk_push_int(ctx, ret);
233     return 1;
234 }
235 
236 /*****************************************************************************
237  * Function:    native_fs_totalsize
238  * Description: js native addon for FILE.totalsize()
239  *            get file system total size in bytes
240  * Called by:   js api
241  * Output:      file system total size in bytes; negative if failed.
242  *****************************************************************************/
native_fs_totalsize(duk_context * ctx)243 static duk_ret_t native_fs_totalsize(duk_context *ctx)
244 {
245     int ret = -1;
246     int size;
247     struct aos_statfs buf;
248 
249     aos_statfs(AMP_FS_ROOT_DIR, &buf);
250 
251     size = buf.f_bsize * buf.f_blocks;
252     if (size < 0) {
253         amp_error(MOD_STR, "get fs totalsize fail");
254         goto out;
255     }
256     ret = size;
257 out:
258     duk_push_int(ctx, ret);
259     return 1;
260 }
261 
262 /*****************************************************************************
263  * Function:    native_fs_usedsize
264  * Description: js native addon for FILE.usedsize()
265  *            get file system used size in bytes
266  * Called by:   js api
267  * Output:      file system used size in bytes; negative if failed.
268  *****************************************************************************/
native_fs_usedsize(duk_context * ctx)269 static duk_ret_t native_fs_usedsize(duk_context *ctx)
270 {
271     int ret = -1;
272     int size;
273     struct aos_statfs buf;
274 
275     aos_statfs(AMP_FS_ROOT_DIR, &buf);
276 
277     size = buf.f_bsize * buf.f_blocks - buf.f_bsize * buf.f_bavail;
278     if (size < 0) {
279         amp_error(MOD_STR, "get fs usedsize fail");
280         goto out;
281     }
282     ret = size;
283 out:
284     duk_push_int(ctx, ret);
285     return 1;
286 }
287 
288 /*****************************************************************************
289  * Function:    native_fs_freesize
290  * Description: js native addon for FILE.freesize()
291  *            get file system free size in bytes
292  * Called by:   js api
293  * Output:      file system free size in bytes; negative if failed.
294  *****************************************************************************/
native_fs_freesize(duk_context * ctx)295 static duk_ret_t native_fs_freesize(duk_context *ctx)
296 {
297     int ret = -1;
298     int size;
299     struct aos_statfs buf;
300 
301     aos_statfs(AMP_FS_ROOT_DIR, &buf);
302 
303     size = buf.f_bsize * buf.f_bavail;
304     if (size < 0) {
305         amp_error(MOD_STR, "get fs freesize fail");
306         goto out;
307     }
308     ret = size;
309 out:
310     duk_push_int(ctx, ret);
311     return 1;
312 }
313 
module_fs_register(void)314 void module_fs_register(void)
315 {
316     duk_context *ctx = be_get_context();
317 
318     duk_push_object(ctx);
319 
320     AMP_ADD_FUNCTION("issupport", native_fs_is_support, 0);
321     AMP_ADD_FUNCTION("read",      native_fs_read, 1);
322     AMP_ADD_FUNCTION("write",     native_fs_write, 3);
323     AMP_ADD_FUNCTION("delete",    native_fs_delete, 1);
324     AMP_ADD_FUNCTION("totalsize", native_fs_totalsize, 0);
325     AMP_ADD_FUNCTION("usedsize",  native_fs_usedsize, 0);
326     AMP_ADD_FUNCTION("freesize",  native_fs_freesize, 0);
327 
328     duk_put_prop_string(ctx, -2, "FS");
329 }
330