From 3e251d3a7f44aa26ff38e89f45ec11bf197f8fbb Mon Sep 17 00:00:00 2001
From: swym <0xfd000000@gmail.com>
Date: Tue, 20 Aug 2019 08:28:00 +0000
Subject: [PATCH] feat(fatfs): Add mkdir() and rename()

---
 epicardium/epicardium.h        | 20 ++++++++++++++++++++
 epicardium/fs/filesystem_fat.c | 12 ++++++++++++
 epicardium/fs/internal.h       |  2 ++
 epicardium/modules/fileops.c   | 22 ++++++++++++++++++++++
 pycardium/modules/os.c         | 27 +++++++++++++++++++++++++++
 pycardium/modules/qstrdefs.h   |  2 ++
 6 files changed, 85 insertions(+)

diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 406df58fc..6d73b4610 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -63,6 +63,8 @@ typedef _Bool bool;
 #define API_FILE_OPENDIR           0x49
 #define API_FILE_READDIR           0x4a
 #define API_FILE_UNLINK            0x4b
+#define API_FILE_RENAME            0x4c
+#define API_FILE_MKDIR             0x4d
 
 #define API_RTC_GET_SECONDS        0x50
 #define API_RTC_SCHEDULE_ALARM     0x51
@@ -1146,6 +1148,24 @@ API(API_FILE_READDIR, int epic_file_readdir(int fd, struct epic_stat* stat));
  */
 API(API_FILE_UNLINK, int epic_file_unlink(const char* path));
 
+/**
+ * Rename a file or directory.
+ *
+ * :param char* oldp: old name
+ * :param char* newp: new name
+ *
+ * :return: ``0`` on success, negative on error
+ */
+API(API_FILE_RENAME, int epic_file_rename(const char *oldp, const char* newp));
+
+/**
+ * Create directory in CWD
+ *
+ * :param char* dirname: directory name
+ *
+ * :return: ``0`` on success, negative on error
+ */
+API(API_FILE_MKDIR, int epic_file_mkdir(const char *dirname));
 
 /**
  * RTC
diff --git a/epicardium/fs/filesystem_fat.c b/epicardium/fs/filesystem_fat.c
index 05b7f4a00..ab79b4d6c 100644
--- a/epicardium/fs/filesystem_fat.c
+++ b/epicardium/fs/filesystem_fat.c
@@ -554,6 +554,18 @@ int efs_unlink(EpicFileSystem *fs, const char *path)
 	return -s_libffToErrno[res];
 }
 
+int efs_rename(EpicFileSystem *fs, const char *oldp, const char *newp)
+{
+	int res = f_rename(oldp, newp);
+	return -s_libffToErrno[res];
+}
+
+int efs_mkdir(EpicFileSystem *fs, const char *dirname)
+{
+	int res = f_mkdir(dirname);
+	return -s_libffToErrno[res];
+}
+
 static const int s_libffToErrno[20] = {
 	[FR_OK]                  = 0,
 	[FR_DISK_ERR]            = EIO,
diff --git a/epicardium/fs/internal.h b/epicardium/fs/internal.h
index 97b878f03..8d0fe2536 100644
--- a/epicardium/fs/internal.h
+++ b/epicardium/fs/internal.h
@@ -29,6 +29,8 @@ int efs_stat(EpicFileSystem *fs, const char *filename, struct epic_stat *stat);
 int efs_opendir(EpicFileSystem *fs, const char *path);
 int efs_readdir(EpicFileSystem *fs, int fd, struct epic_stat *stat);
 int efs_unlink(EpicFileSystem *fs, const char *path);
+int efs_rename(EpicFileSystem *fs, const char *oldp, const char *newp);
+int efs_mkdir(EpicFileSystem *fs, const char *dirname);
 /**
  * lock global filesystem
  * 
diff --git a/epicardium/modules/fileops.c b/epicardium/modules/fileops.c
index 53dc7fd41..b0be04c5f 100644
--- a/epicardium/modules/fileops.c
+++ b/epicardium/modules/fileops.c
@@ -138,3 +138,25 @@ int epic_file_unlink(const char *path)
 	}
 	return res;
 }
+
+int epic_file_rename(const char *oldp, const char *newp)
+{
+	EpicFileSystem *fs;
+	int res = efs_lock_global(&fs);
+	if (res == 0) {
+		res = efs_rename(fs, oldp, newp);
+		efs_unlock_global(fs);
+	}
+	return res;
+}
+
+int epic_file_mkdir(const char *dirname)
+{
+	EpicFileSystem *fs;
+	int res = efs_lock_global(&fs);
+	if (res == 0) {
+		res = efs_mkdir(fs, dirname);
+		efs_unlock_global(fs);
+	}
+	return res;
+}
diff --git a/pycardium/modules/os.c b/pycardium/modules/os.c
index e5c625ef4..99af67cb0 100644
--- a/pycardium/modules/os.c
+++ b/pycardium/modules/os.c
@@ -89,12 +89,39 @@ static mp_obj_t mp_os_unlink(mp_obj_t py_path)
 }
 static MP_DEFINE_CONST_FUN_OBJ_1(unlink_obj, mp_os_unlink);
 
+static mp_obj_t mp_os_mkdir(mp_obj_t py_path)
+{
+	const char *path = mp_obj_str_get_str(py_path);
+	int rc           = epic_file_mkdir(path);
+
+	if (rc < 0) {
+		mp_raise_OSError(-rc);
+	}
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_1(mkdir_obj, mp_os_mkdir);
+
+static mp_obj_t mp_os_rename(mp_obj_t py_oldp, mp_obj_t py_newp)
+{
+	const char *oldp = mp_obj_str_get_str(py_oldp);
+	const char *newp = mp_obj_str_get_str(py_newp);
+	int rc           = epic_file_rename(oldp, newp);
+
+	if (rc < 0) {
+		mp_raise_OSError(-rc);
+	}
+	return mp_const_none;
+}
+static MP_DEFINE_CONST_FUN_OBJ_2(rename_obj, mp_os_rename);
+
 static const mp_rom_map_elem_t os_module_globals_table[] = {
 	{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_os) },
 	{ MP_ROM_QSTR(MP_QSTR_exit), MP_ROM_PTR(&exit_obj) },
 	{ MP_ROM_QSTR(MP_QSTR_exec), MP_ROM_PTR(&exec_obj) },
 	{ MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&listdir_obj) },
 	{ MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&unlink_obj) },
+	{ MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mkdir_obj) },
+	{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&rename_obj) },
 };
 
 static MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h
index 49ad16f40..4315a839c 100644
--- a/pycardium/modules/qstrdefs.h
+++ b/pycardium/modules/qstrdefs.h
@@ -100,6 +100,8 @@ Q(exit)
 Q(exec)
 Q(listdir)
 Q(unlink)
+Q(mkdir)
+Q(rename)
 
 /* gpio */
 Q(gpio)
-- 
GitLab