diff options
| author | Björn Stenberg <bjorn@haxx.se> | 2002-05-27 09:13:24 +0000 |
|---|---|---|
| committer | Björn Stenberg <bjorn@haxx.se> | 2002-05-27 09:13:24 +0000 |
| commit | 3d25f7825a7e3df85a8077aec8b7bbce5fde8dfa (patch) | |
| tree | 5bdbad1bfbd2215f1e4bbaa4e31a8f95f59956dd /firmware | |
| parent | 9e7ee96b6eccb1060a56375ce19f0a0bdc0471b7 (diff) | |
| download | rockbox-3d25f7825a7e3df85a8077aec8b7bbce5fde8dfa.zip rockbox-3d25f7825a7e3df85a8077aec8b7bbce5fde8dfa.tar.gz rockbox-3d25f7825a7e3df85a8077aec8b7bbce5fde8dfa.tar.bz2 rockbox-3d25f7825a7e3df85a8077aec8b7bbce5fde8dfa.tar.xz | |
Now supports multiple concurrent opendir()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@727 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
| -rw-r--r-- | firmware/common/dir.c | 53 | ||||
| -rw-r--r-- | firmware/common/dir.h | 4 |
2 files changed, 37 insertions, 20 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c index e1f4c06..5fb1415 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c @@ -17,15 +17,16 @@ * ****************************************************************************/ #include <stdio.h> +#include <errno.h> #include <string.h> #include <stdbool.h> #include "fat.h" #include "dir.h" #include "debug.h" -static DIR thedir; -static struct dirent theent; -static bool busy=false; +#define MAX_OPEN_DIRS 8 + +static DIR opendirs[MAX_OPEN_DIRS]; DIR* opendir(char* name) { @@ -33,20 +34,30 @@ DIR* opendir(char* name) char* part; char* end; struct fat_direntry entry; - struct fat_dir* dir = &(thedir.fatdir); + int dd; + + /* find a free dir descriptor */ + for ( dd=0; dd<MAX_OPEN_DIRS; dd++ ) + if ( !opendirs[dd].busy ) + break; - if ( busy ) { - DEBUGF("Only one open dir at a time\n"); + if ( dd == MAX_OPEN_DIRS ) { + DEBUGF("Too many dirs open\n"); + errno = EMFILE; return NULL; } + opendirs[dd].busy = true; + if ( name[0] != '/' ) { DEBUGF("Only absolute paths supported right now\n"); + opendirs[dd].busy = false; return NULL; } - if ( fat_opendir(dir, 0) < 0 ) { + if ( fat_opendir(&(opendirs[dd].fatdir), 0) < 0 ) { DEBUGF("Failed opening root dir\n"); + opendirs[dd].busy = false; return NULL; } @@ -58,15 +69,18 @@ DIR* opendir(char* name) int partlen = strlen(part); /* scan dir for name */ while (1) { - if (fat_getnext(dir,&entry) < 0) - return NULL; - if ( !entry.name[0] ) + if ((fat_getnext(&(opendirs[dd].fatdir),&entry) < 0) || + (!entry.name[0])) { + opendirs[dd].busy = false; return NULL; + } if ( (entry.attr & FAT_ATTR_DIRECTORY) && (!strncmp(part, entry.name, partlen)) ) { - if ( fat_opendir(dir, entry.firstcluster) < 0 ) { + if ( fat_opendir(&(opendirs[dd].fatdir), + entry.firstcluster) < 0 ) { DEBUGF("Failed opening dir '%s' (%d)\n", part, entry.firstcluster); + opendirs[dd].busy = false; return NULL; } break; @@ -74,20 +88,19 @@ DIR* opendir(char* name) } } - busy = true; - - return &thedir; + return &opendirs[dd]; } int closedir(DIR* dir) { - busy=false; + dir->busy=false; return 0; } struct dirent* readdir(DIR* dir) { struct fat_direntry entry; + struct dirent* theent = &(dir->theent); if (fat_getnext(&(dir->fatdir),&entry) < 0) return NULL; @@ -95,12 +108,12 @@ struct dirent* readdir(DIR* dir) if ( !entry.name[0] ) return NULL; - strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); - theent.attribute = entry.attr; - theent.size = entry.filesize; - theent.startcluster = entry.firstcluster; + strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); + theent->attribute = entry.attr; + theent->size = entry.filesize; + theent->startcluster = entry.firstcluster; - return &theent; + return theent; } /* diff --git a/firmware/common/dir.h b/firmware/common/dir.h index 274c0b1..0cd35d0 100644 --- a/firmware/common/dir.h +++ b/firmware/common/dir.h @@ -19,6 +19,8 @@ #ifndef _DIR_H_ #define _DIR_H_ +#include <stdbool.h> + #ifndef DIRENT_DEFINED #define ATTR_READ_ONLY 0x01 @@ -42,8 +44,10 @@ struct dirent { #include "fat.h" typedef struct { + bool busy; int startcluster; struct fat_dir fatdir; + struct dirent theent; } DIR; #else // SIMULATOR |