diff options
Diffstat (limited to 'sdk-modifications/libsrc/fs/fs_api.c')
-rwxr-xr-x | sdk-modifications/libsrc/fs/fs_api.c | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/sdk-modifications/libsrc/fs/fs_api.c b/sdk-modifications/libsrc/fs/fs_api.c new file mode 100755 index 0000000..b23a450 --- /dev/null +++ b/sdk-modifications/libsrc/fs/fs_api.c @@ -0,0 +1,452 @@ +//fs_api.c
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "fs_common.h"
+#include "fatfile.h"
+#include "fatdir.h"
+
+typedef unsigned int size_t;
+typedef unsigned int mode_t;
+
+typedef struct {
+ const char* mode; /* mode string */
+ unsigned int flag; /* mode flag */
+// unsigned char mode_r; /* READ */
+// unsigned char mode_w; /* WRITE */
+// unsigned char mode_a; /* APPEND */
+// unsigned char mode_c; /* CREATE */
+} _fat_mode_type;
+
+static const _fat_mode_type _fat_valid_mode[] = {
+ { "r" , O_RDONLY },
+ { "w" , O_WRONLY | O_TRUNC | O_CREAT },
+ { "a" , O_WRONLY | O_APPEND | O_CREAT },
+ { "rb" , O_RDONLY },
+ { "wb" , O_WRONLY | O_TRUNC | O_CREAT },
+ { "ab" , O_WRONLY | O_APPEND | O_CREAT },
+ { "r+" , O_RDWR },
+ { "w+" , O_RDWR | O_TRUNC | O_CREAT },
+ { "a+" , O_RDWR | O_APPEND | O_CREAT },
+ { "r+b" , O_RDWR },
+ { "rb+" , O_RDWR },
+ { "w+b" , O_RDWR | O_TRUNC | O_CREAT },
+ { "wb+" , O_RDWR | O_TRUNC | O_CREAT },
+ { "a+b" , O_RDWR | O_APPEND | O_CREAT },
+ { "ab+" , O_RDWR | O_APPEND | O_CREAT }
+};
+
+#define MAX_OPEN_FILE 16
+#define MAX_OPEN_DIR 32
+#define MAX_PWD_LEN 512
+#define MAX_STDIO_BUF_SIZE 2048
+
+#define FAT_VALID_MODE_NUM (sizeof(_fat_valid_mode)/sizeof(_fat_mode_type))
+
+static FILE_STRUCT __FILEs[MAX_OPEN_FILE];
+struct _reent __REENT;
+static DIR_STATE_STRUCT __DIRs[MAX_OPEN_DIR];
+static char __PWD[MAX_PWD_LEN];
+
+int fat_init(void)
+{
+ int i, flag;
+
+ for(i= 0; i < MAX_OPEN_FILE; i++)
+ __FILEs[i].inUse = false;
+
+ for(i= 0; i < MAX_OPEN_DIR; i++)
+ __DIRs[i].inUse = false;
+
+ flag = -1;
+ if(_FAT_Init() == true) //success
+ flag = 0;
+
+ return flag;
+}
+
+FILE_STRUCT* fat_fopen(const char *file, const char *mode)
+{
+ int i, k;
+ int fd;
+ FILE_STRUCT* fp;
+
+ for(i= 0; i < MAX_OPEN_FILE; i++)
+ if(false == __FILEs[i].inUse) break;
+
+ if(i >= MAX_OPEN_FILE)
+ {
+ __REENT._errno = EMFILE; /* Too many open files */
+ return NULL;
+ }
+
+ for(k = 0; k < FAT_VALID_MODE_NUM; k++)
+ if(!strcasecmp(_fat_valid_mode[k].mode, mode)) break;
+
+ if(k >= FAT_VALID_MODE_NUM)
+ {
+ __REENT._errno = EINVAL;
+ return NULL;
+ }
+
+ fd = _FAT_open_r(&__REENT, (void*)&__FILEs[i], file, _fat_valid_mode[k].flag);
+ if(-1 == fd) return NULL;
+
+ fp = &__FILEs[i];
+ fp -> fd = fd;
+
+ return fp;
+}
+
+size_t fat_fread(void *buf, size_t size, size_t count, FILE_STRUCT *fp)
+{
+ if(0 == size || 0 == count)
+ return 0;
+
+ int len = _FAT_read_r(&__REENT, fp->fd, (char*)buf, size*count);
+ len /= size;
+ return len;
+}
+
+size_t fat_fwrite(const void *buf, size_t size, size_t count, FILE_STRUCT *fp)
+{
+ if(0 == size || 0 == count)
+ return 0;
+
+ int len = _FAT_write_r(&__REENT, fp->fd, (const char*)buf, size*count);
+ len /= size;
+
+ return len;
+}
+
+int fat_fclose(FILE_STRUCT *fp)
+{
+ return( _FAT_close_r(&__REENT, fp->fd) );
+}
+
+int fat_fseek(FILE_STRUCT *fp, long offset, int whence)
+{
+ int flag;
+
+ //When success, _FAT_seek_r return file position pointer
+ flag = _FAT_seek_r (&__REENT, fp->fd, (int)offset, whence);
+ if(flag > 0) flag = 0;
+
+ return flag;
+}
+
+long fat_ftell(FILE_STRUCT *fp)
+{
+ return( (long)fp->currentPosition );
+}
+
+int fat_feof(FILE_STRUCT *fp)
+{
+ int result;
+
+ result = 0;
+ if((fp->currentPosition +1) >= (fp->filesize))
+ result = -1;
+
+ return result;
+}
+
+int fat_ferror(FILE_STRUCT *fp)
+{
+ return( __REENT._errno );
+}
+
+void fat_clearerr(FILE_STRUCT *fp)
+{
+ fp = fp;
+
+ __REENT._errno = 0;
+}
+
+int fat_fflush(FILE_STRUCT *fp)
+{
+ return(_FAT_cache_flush(fp->partition->cache));
+}
+
+int fat_fgetc(FILE_STRUCT *fp)
+{
+ char ch;
+ int result;
+
+ result = _FAT_read_r(&__REENT, fp->fd, &ch, 1);
+ if(0 == result)
+ return EOF;
+
+ return ( (int)ch );
+}
+
+char* fat_fgets(char* buf, int n, FILE_STRUCT* fp)
+{
+ int m;
+ char *s;
+
+ buf[0] = '\0';
+ if(n <= 1) return buf;
+
+ n -= 1;
+ m = _FAT_read_r(&__REENT, fp->fd, buf, n);
+ if(0 == m) return NULL;
+
+ buf[m] = '\0';
+ s = strchr((const char*)buf, 0x0A);
+
+ if(NULL != s)
+ {
+ *(++s)= '\0';
+ m -= s - buf;
+
+ //fix reading pointer
+ _FAT_seek_r (&__REENT, fp->fd, -m, SEEK_CUR);
+ }
+ else if(m == n)
+ {
+ if(0x0D == buf[n-1]) //0x0D,0x0A
+ {
+ buf[n-1] = '\0';
+ _FAT_seek_r (&__REENT, fp->fd, -1, SEEK_CUR);
+ }
+ }
+
+ return buf;
+}
+
+int fat_fputc(int ch, FILE_STRUCT *fp)
+{
+ return( _FAT_write_r(&__REENT, fp->fd, (const char*)&ch, 1) );
+}
+
+int fat_fputs(const char *s, FILE_STRUCT *fp)
+{
+ unsigned int len;
+
+ len = strlen(s);
+ return( _FAT_write_r(&__REENT, fp->fd, s, len) );
+}
+
+int fat_remove(const char *filename)
+{
+ return( _FAT_unlink_r (&__REENT, (const char*)filename) );
+}
+
+int fat_rename(const char *oldName, const char *newName)
+{
+ return( _FAT_rename_r(&__REENT, oldName, newName) );
+}
+
+int fat_setHidden(const char *name, unsigned char hide){
+ return(_FAT_hideAttrib_r (&__REENT, name, hide));
+}
+
+#define S_ISHID(st_mode) ((st_mode & S_IHIDDEN) != 0)
+int fat_isHidden(struct stat *st){
+ return S_ISHID(st->st_mode);
+}
+
+int fat_getShortName(const char *fullName, char *outName){
+ return(_FAT_getshortname_r (&__REENT, fullName, outName));
+}
+
+
+void fat_rewind(FILE_STRUCT *fp)
+{
+ _FAT_seek_r (&__REENT, fp->fd, 0, SEEK_SET);
+}
+
+int fat_fstat(int fildes, struct stat *buf)
+{
+ return( _FAT_fstat_r (&__REENT, fildes, buf) );
+}
+
+//int fat_fprintf(FILE_STRUCT *fp, const char *format, ...)
+int fat_fprintf(void* fp, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+ char buf[MAX_STDIO_BUF_SIZE];
+
+ if(NULL == fp)
+ {
+ __REENT._errno = EINVAL;
+ return -1;
+ }
+
+ //FIXME: stderr, stdout
+ if((void*)stderr == fp) return 0;
+ if((void*)stdout == fp) return 0;
+
+ memset(buf, 0, MAX_STDIO_BUF_SIZE);
+
+ va_start (ap, format);
+ ret = vsnprintf (buf, MAX_STDIO_BUF_SIZE, format, ap);
+ va_end (ap);
+
+ //if output string too long, it will not put out to file
+ if(ret >= MAX_STDIO_BUF_SIZE)
+ return -1;
+
+ return( _FAT_write_r(&__REENT, ((FILE_STRUCT*)fp)->fd, (const char*)buf, strlen(buf)) );
+}
+
+int fat_fscanf(FILE_STRUCT *fp, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+ char buf[MAX_STDIO_BUF_SIZE];
+ char *pt;
+
+ if(NULL == fp)
+ {
+ __REENT._errno = EINVAL;
+ return -1;
+ }
+
+ pt = fat_fgets(buf, MAX_STDIO_BUF_SIZE, fp);
+ if(NULL == pt)
+ return -1;
+
+ va_start (ap, format);
+ ret = vsscanf (buf, format, ap);
+
+ return ret;
+}
+
+DIR_STATE_STRUCT* fat_opendir(const char *name)
+{
+ int i;
+
+ for(i = 0; i < MAX_OPEN_DIR; i++)
+ {
+ if(false == __DIRs[i].inUse) break;
+ }
+
+ if(i>= MAX_OPEN_DIR)
+ {
+ __REENT._errno = EMFILE; /* Too many open files */
+ return NULL;
+ }
+
+ return( _FAT_diropen_r(&__REENT, &__DIRs[i], name) );
+}
+
+DIR_ENTRY* fat_readdir(DIR_STATE_STRUCT *dirp)
+{
+ int isValid;
+
+ isValid = _FAT_dirnext_r (&__REENT, dirp, NULL);
+ if(0 != isValid)
+ return NULL;
+
+ return( &(dirp->currentEntry) );
+}
+
+long int fat_telldir(DIR_STATE_STRUCT *dirp)
+{
+ return( dirp->posEntry );
+}
+
+void fat_seekdir(DIR_STATE_STRUCT *dirp, long int loc)
+{
+ if (!dirp->inUse) {
+ __REENT._errno = EBADF;
+ return;
+ }
+
+ if(0 == loc)
+ {
+ dirp->posEntry = 0;
+ }
+ else if(loc > 0)
+ {
+ while(dirp->posEntry < loc)
+ {
+ dirp->validEntry = _FAT_directory_getNextEntry (dirp->partition, &(dirp->currentEntry));
+ dirp->posEntry += 1;
+
+ if(!dirp->validEntry) break;
+ }
+ }
+
+ return;
+}
+
+int fat_closedir(DIR_STATE_STRUCT *dirp)
+{
+ return(_FAT_dirclose_r (&__REENT, dirp));
+}
+
+int fat_chdir(const char *path)
+{
+ int ret;
+ char *pt;
+
+ ret = _FAT_chdir_r (&__REENT, path);
+ if(0 != ret) return -1;
+
+ pt = strchr(path, ':');
+ if(pt == NULL)
+ strcat(__PWD, path);
+ else
+ strcpy(__PWD, path);
+
+ pt = strchr(__PWD, '\0');
+ while(pt-- != __PWD)
+ {
+ if(pt[0] != DIR_SEPARATOR) break;
+ }
+
+ pt[1] = DIR_SEPARATOR;
+ pt[2] = '\0';
+
+ return 0;
+}
+
+char* fat_getcwd(char *buf, size_t size)
+{
+ int len;
+
+ len = strlen(__PWD);
+ if(len >= size)
+ {
+ __REENT._errno = ERANGE;
+ return NULL;
+ }
+
+ strcpy(buf, __PWD);
+ return buf;
+}
+
+int fat_mkdir(const char *path, mode_t mode)
+{
+ return( _FAT_mkdir_r(&__REENT, path, mode) );
+}
+
+int fat_rmdir(const char *path)
+{
+ return( _FAT_unlink_r(&__REENT, path) );
+}
+
+int fat_lstat(const char *path, struct stat *buf)
+{
+ return( _FAT_stat_r (&__REENT, path, buf) );
+}
+
+DIR_ENTRY* fat_readdir_ex(DIR_STATE_STRUCT *dirp, struct stat *statbuf)
+{
+ int isValid;
+
+ isValid = _FAT_dirnext_r (&__REENT, dirp, statbuf);
+ if(0 != isValid)
+ return NULL;
+
+ return( &(dirp->currentEntry) );
+}
+
|