moduos_file.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2017 SummerGift <zhangyuan@rt-thread.com>
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include "py/mpconfig.h"
  27. #if MICROPY_PY_MODUOS_FILE
  28. #include <stdint.h>
  29. #include <string.h>
  30. #include <dfs_posix.h>
  31. #include "py/runtime.h"
  32. #include "py/objstr.h"
  33. #include "py/mperrno.h"
  34. #include "moduos_file.h"
  35. mp_obj_t mp_posix_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  36. return mp_const_none;
  37. }
  38. MP_DEFINE_CONST_FUN_OBJ_KW(mp_posix_mount_obj, 2, mp_posix_mount);
  39. mp_obj_t mp_posix_umount(mp_obj_t mnt_in) {
  40. return mp_const_none;
  41. }
  42. MP_DEFINE_CONST_FUN_OBJ_1(mp_posix_umount_obj, mp_posix_umount);
  43. mp_obj_t mp_posix_mkfs(size_t n_args, const mp_obj_t *args) {
  44. int result = RT_EOK;
  45. char *type = "elm"; /* use the default file system type as 'fatfs' */
  46. if (n_args == 1)
  47. {
  48. result = dfs_mkfs(type, mp_obj_str_get_str(args[0]));
  49. }else if (n_args == 2)
  50. {
  51. type = (char *)mp_obj_str_get_str(args[0]);
  52. result = dfs_mkfs(type, mp_obj_str_get_str(args[1]));
  53. }
  54. if (result != RT_EOK)
  55. {
  56. mp_raise_ValueError("mkfs failed, please check filesystem type and device name.");
  57. }
  58. return mp_const_none;
  59. }
  60. MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_posix_mkfs_obj, 1, 2, mp_posix_mkfs);
  61. mp_obj_t mp_posix_chdir(mp_obj_t path_in) {
  62. const char *changepath = mp_obj_str_get_str(path_in);
  63. if (chdir(changepath) != 0) {
  64. mp_printf(&mp_plat_print, "No such directory: %s\n", changepath);
  65. }
  66. return mp_const_none;
  67. }
  68. MP_DEFINE_CONST_FUN_OBJ_1(mp_posix_chdir_obj, mp_posix_chdir);
  69. mp_obj_t mp_posix_getcwd(void) {
  70. char buf[MICROPY_ALLOC_PATH_MAX + 1];
  71. getcwd(buf, sizeof(buf));
  72. return mp_obj_new_str(buf, strlen(buf));
  73. }
  74. MP_DEFINE_CONST_FUN_OBJ_0(mp_posix_getcwd_obj, mp_posix_getcwd);
  75. #include <dfs_file.h>
  76. static struct dfs_fd fd;
  77. static struct dirent dirent;
  78. mp_obj_t mp_posix_listdir(size_t n_args, const mp_obj_t *args) {
  79. mp_obj_t dir_list = mp_obj_new_list(0, NULL);
  80. struct stat stat;
  81. int length;
  82. char *fullpath, *path;
  83. const char *pathname;
  84. if (n_args == 0) {
  85. #ifdef DFS_USING_WORKDIR
  86. extern char working_directory[];
  87. pathname = working_directory;
  88. #else
  89. pathname = "/";
  90. #endif
  91. } else {
  92. pathname = mp_obj_str_get_str(args[0]);
  93. }
  94. fullpath = NULL;
  95. if (pathname == NULL)
  96. {
  97. #ifdef DFS_USING_WORKDIR
  98. extern char working_directory[];
  99. /* open current working directory */
  100. path = rt_strdup(working_directory);
  101. #else
  102. path = rt_strdup("/");
  103. #endif
  104. if (path == NULL)
  105. mp_raise_OSError(MP_ENOMEM); /* out of memory */
  106. }
  107. else
  108. {
  109. path = (char *)pathname;
  110. }
  111. /* list directory */
  112. if (dfs_file_open(&fd, path, O_DIRECTORY) == 0)
  113. {
  114. do {
  115. memset(&dirent, 0, sizeof(struct dirent));
  116. length = dfs_file_getdents(&fd, &dirent, sizeof(struct dirent));
  117. if (length > 0) {
  118. memset(&stat, 0, sizeof(struct stat));
  119. /* build full path for each file */
  120. fullpath = dfs_normalize_path(path, dirent.d_name);
  121. if (fullpath == NULL)
  122. break;
  123. if (dfs_file_stat(fullpath, &stat) == 0) {
  124. mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
  125. t->items[0] = mp_obj_new_str(dirent.d_name, strlen(dirent.d_name));
  126. t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR);
  127. t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // no inode number
  128. mp_obj_t next = MP_OBJ_FROM_PTR(t);
  129. mp_obj_t *items;
  130. mp_obj_get_array_fixed_n(next, 3, &items);
  131. mp_obj_list_append(dir_list, items[0]);
  132. } else {
  133. mp_printf(&mp_plat_print, "BAD file: %s\n", dirent.d_name);
  134. }
  135. rt_free(fullpath);
  136. }
  137. } while (length > 0);
  138. dfs_file_close(&fd);
  139. }
  140. else
  141. {
  142. // mp_printf(&mp_plat_print, "No such directory\n");
  143. }
  144. if (pathname == NULL)
  145. rt_free(path);
  146. return dir_list;
  147. }
  148. MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_posix_listdir_obj, 0, 1, mp_posix_listdir);
  149. mp_obj_t mp_posix_mkdir(mp_obj_t path_in) {
  150. const char *createpath = mp_obj_str_get_str(path_in);
  151. int res = mkdir(createpath, 0);
  152. if (res != 0) {
  153. mp_raise_OSError(MP_EEXIST);
  154. }
  155. return mp_const_none;
  156. }
  157. MP_DEFINE_CONST_FUN_OBJ_1(mp_posix_mkdir_obj, mp_posix_mkdir);
  158. mp_obj_t mp_posix_remove(uint n_args, const mp_obj_t *arg) {
  159. int index;
  160. if (n_args == 0) {
  161. mp_printf(&mp_plat_print, "Usage: rm FILE...\n");
  162. mp_printf(&mp_plat_print, "Remove (unlink) the FILE(s).\n");
  163. return mp_const_none;
  164. }
  165. for (index = 0; index < n_args; index++) {
  166. //mp_printf(&mp_plat_print, "Remove %s.\n", mp_obj_str_get_str(arg[index]));
  167. unlink(mp_obj_str_get_str(arg[index]));
  168. }
  169. // TODO recursive deletion
  170. return mp_const_none;
  171. }
  172. MP_DEFINE_CONST_FUN_OBJ_VAR(mp_posix_remove_obj, 0, mp_posix_remove);
  173. mp_obj_t mp_posix_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) {
  174. const char *old_path = mp_obj_str_get_str(old_path_in);
  175. const char *new_path = mp_obj_str_get_str(new_path_in);
  176. int res = rename(old_path, new_path);
  177. if (res != 0) {
  178. mp_raise_OSError(MP_EPERM);
  179. }
  180. return mp_const_none;
  181. }
  182. MP_DEFINE_CONST_FUN_OBJ_2(mp_posix_rename_obj, mp_posix_rename);
  183. mp_obj_t mp_posix_rmdir(uint n_args, const mp_obj_t *arg) {
  184. int index;
  185. if (n_args == 0) {
  186. mp_printf(&mp_plat_print, "Usage: rm FILE...\n");
  187. mp_printf(&mp_plat_print, "Remove (unlink) the FILE(s).\n");
  188. return mp_const_none;
  189. }
  190. for (index = 0; index < n_args; index++) {
  191. //mp_printf(&mp_plat_print, "Remove %s.\n", mp_obj_str_get_str(arg[index]));
  192. rmdir(mp_obj_str_get_str(arg[index]));
  193. }
  194. // TODO recursive deletion
  195. return mp_const_none;
  196. }
  197. MP_DEFINE_CONST_FUN_OBJ_VAR(mp_posix_rmdir_obj, 0, mp_posix_rmdir);
  198. mp_obj_t mp_posix_stat(mp_obj_t path_in) {
  199. struct stat buf;
  200. const char *createpath = mp_obj_str_get_str(path_in);
  201. int res = stat(createpath, &buf);
  202. if (res != 0) {
  203. mp_raise_OSError(MP_EPERM);
  204. }
  205. mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL));
  206. t->items[0] = MP_OBJ_NEW_SMALL_INT(buf.st_mode); // st_mode
  207. t->items[1] = MP_OBJ_NEW_SMALL_INT(buf.st_ino); // st_ino
  208. t->items[2] = MP_OBJ_NEW_SMALL_INT(buf.st_dev); // st_dev
  209. t->items[3] = MP_OBJ_NEW_SMALL_INT(buf.st_nlink); // st_nlink
  210. t->items[4] = MP_OBJ_NEW_SMALL_INT(buf.st_uid); // st_uid
  211. t->items[5] = MP_OBJ_NEW_SMALL_INT(buf.st_gid); // st_gid
  212. t->items[6] = mp_obj_new_int_from_uint(buf.st_size); // st_size
  213. t->items[7] = MP_OBJ_NEW_SMALL_INT(buf.st_atime); // st_atime
  214. t->items[8] = MP_OBJ_NEW_SMALL_INT(buf.st_mtime); // st_mtime
  215. t->items[9] = MP_OBJ_NEW_SMALL_INT(buf.st_ctime); // st_ctime
  216. return MP_OBJ_FROM_PTR(t);
  217. }
  218. MP_DEFINE_CONST_FUN_OBJ_1(mp_posix_stat_obj, mp_posix_stat);
  219. static uint32_t calc_crc32(const char* pathname)
  220. {
  221. #define CALC_BUFFER_SIZE 512
  222. extern uint32_t mp_calc_crc32(uint32_t crc, const void *buf, size_t len);
  223. int fd;
  224. uint32_t temp_crc = 0;
  225. void *buffer = malloc(CALC_BUFFER_SIZE);
  226. if (buffer == RT_NULL)
  227. {
  228. mp_raise_OSError(MP_ENOMEM);
  229. }
  230. fd = open(pathname, O_RDONLY, 0);
  231. if (fd < 0)
  232. {
  233. return -MP_EINVAL;
  234. }
  235. while (1)
  236. {
  237. int len = read(fd, buffer, CALC_BUFFER_SIZE);
  238. if (len < 0)
  239. {
  240. close(fd);
  241. return -MP_EIO;
  242. }
  243. else if (len == 0)
  244. break;
  245. temp_crc = mp_calc_crc32(temp_crc, buffer, len);
  246. }
  247. close(fd);
  248. free(buffer);
  249. return temp_crc;
  250. }
  251. mp_obj_t mp_posix_file_crc32(mp_obj_t path_in) {
  252. extern void mp_hex_to_str(char *pbDest, char *pbSrc, int nLen);
  253. uint32_t value = 0;
  254. char str[9];
  255. const char *createpath = mp_obj_str_get_str(path_in);
  256. value = calc_crc32((char *)createpath);
  257. mp_hex_to_str(str,(char *)&value, 4);
  258. return mp_obj_new_str(str, strlen(str));
  259. }
  260. MP_DEFINE_CONST_FUN_OBJ_1(mp_posix_file_crc32_obj, mp_posix_file_crc32);
  261. mp_import_stat_t mp_posix_import_stat(const char *path) {
  262. struct stat stat;
  263. if (dfs_file_stat(path, &stat) == 0) {
  264. if (S_ISDIR(stat.st_mode)) {
  265. return MP_IMPORT_STAT_DIR;
  266. } else {
  267. return MP_IMPORT_STAT_FILE;
  268. }
  269. } else {
  270. return MP_IMPORT_STAT_NO_EXIST;
  271. }
  272. }
  273. #endif //MICROPY_MODUOS_FILE