From d4a24d51a58c260ff3502063e83832c03bc32ea0 Mon Sep 17 00:00:00 2001
From: q3k <q3k@q3k.org>
Date: Mon, 29 Jul 2019 17:45:51 +0000
Subject: [PATCH] feat(fatfs): Add seek and tell implementation

---
 epicardium/epicardium.h    | 10 ++++++++--
 epicardium/modules/fatfs.c | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h
index 9c4a770d..26bdceb7 100644
--- a/epicardium/epicardium.h
+++ b/epicardium/epicardium.h
@@ -54,8 +54,8 @@ typedef unsigned int size_t;
 #define API_FILE_READ          0x32
 #define API_FILE_WRITE         0x34
 #define API_FILE_FLUSH         0x35
-#define API_FILE_SEEK          0x36 //NYI
-#define API_FILE_TELL          0x37 //NYI
+#define API_FILE_SEEK          0x36
+#define API_FILE_TELL          0x37
 #define API_FILE_STAT          0x38
 /* clang-format on */
 
@@ -483,6 +483,12 @@ API(
 /** */
 API(API_FILE_FLUSH, int epic_file_flush(int fd));
 
+/** */
+API(API_FILE_SEEK, int epic_file_seek(int fd, long offset, int whence));
+
+/** */
+API(API_FILE_TELL, int epic_file_tell(int fd));
+
 /** */
 enum epic_stat_type {
 	/** */
diff --git a/epicardium/modules/fatfs.c b/epicardium/modules/fatfs.c
index 649ba730..e9f7205d 100644
--- a/epicardium/modules/fatfs.c
+++ b/epicardium/modules/fatfs.c
@@ -326,6 +326,43 @@ int epic_file_flush(int fd)
 	return 0;
 }
 
+int epic_file_seek(int fd, long offset, int whence)
+{
+	int res;
+	struct FatObject *o;
+	res = get_fat_object(fd, FO_File, &o);
+	if (res) {
+		return -res;
+	}
+
+	switch (whence) {
+	case SEEK_SET:
+		res = f_lseek(&o->file, offset);
+		return -fresult_to_errno_table[res];
+	case SEEK_CUR:
+		res = f_lseek(&o->file, f_tell(&o->file) + offset);
+		return -fresult_to_errno_table[res];
+	case SEEK_END:
+		res = f_lseek(&o->file, f_size(&o->file) + offset);
+		return -fresult_to_errno_table[res];
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int epic_file_tell(int fd)
+{
+	int res;
+	struct FatObject *o;
+	res = get_fat_object(fd, FO_File, &o);
+	if (res) {
+		return -1;
+	}
+
+	return f_tell(&o->file);
+}
+
 int epic_file_stat(const char *filename, epic_stat_t *stat)
 {
 	int res;
-- 
GitLab