From 0f8f87c3fe4de75b9048f9c92f691be179faf8c6 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Thu, 12 Jul 2012 16:29:41 +0200 Subject: [PATCH] libc_ffat: enhance 'lseek()' support This patch adds support for the 'SEEK_CUR' and 'SEEK_END' values of the 'whence' argument of the 'lseek()' function.. Fixes #277. --- libports/src/lib/libc_ffat/plugin.cc | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/libports/src/lib/libc_ffat/plugin.cc b/libports/src/lib/libc_ffat/plugin.cc index 9182197725..ab88d5abcf 100644 --- a/libports/src/lib/libc_ffat/plugin.cc +++ b/libports/src/lib/libc_ffat/plugin.cc @@ -32,6 +32,12 @@ namespace Ffat { extern "C" { #include } } +/* + * These macros are defined in later versions of the FatFs lib, but not in the + * one currently used for Genode. + */ +#define f_size(fp) ((fp)->fsize) +#define f_tell(fp) ((fp)->fptr) static bool const verbose = false; @@ -373,16 +379,26 @@ class Plugin : public Libc::Plugin { using namespace Ffat; - if (whence != SEEK_SET) { - PERR("only SEEK_SET is supported by the ffat lib"); - errno = EINVAL; - return (::off_t)-1; + switch(whence) { + case SEEK_CUR: + offset += f_tell(_get_ffat_file(fd)); + break; + case SEEK_END: + offset += f_size(_get_ffat_file(fd)); + break; + default: + break; } FRESULT res = f_lseek(_get_ffat_file(fd), offset); switch(res) { case FR_OK: + /* according to the FatFs documentation this can happen */ + if (f_tell(_get_ffat_file(fd)) != offset) { + errno = EINVAL; + return -1; + } return offset; case FR_DISK_ERR: case FR_INT_ERR: