diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-05-08 15:16:02 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-05-08 15:16:02 +0000 |
commit | 1c3217909b444b86f87f976925f05ac05555cc6d (patch) | |
tree | a88403f37f9ea9cab683c74ff0dd05e50cd45ac9 | |
parent | 6a63f911fef19eae9aaa96b20dbe57aab63399d9 (diff) |
Added lseek()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@518 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/common/file.c | 72 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 36 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 56 |
3 files changed, 145 insertions, 19 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 41aaea570a..a5d9443aeb 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -100,7 +100,7 @@ int open(char* pathname, int flags) return -1; } - openfiles[fd].cacheoffset = 0; + openfiles[fd].cacheoffset = -1; openfiles[fd].fileoffset = 0; openfiles[fd].busy = TRUE; return fd; @@ -127,7 +127,7 @@ int read(int fd, void* buf, int count) count = openfiles[fd].size - openfiles[fd].fileoffset; /* any head bytes? */ - if ( openfiles[fd].cacheoffset ) { + if ( openfiles[fd].cacheoffset != -1 ) { int headbytes; int offs = openfiles[fd].cacheoffset; if ( count <= SECTOR_SIZE - openfiles[fd].cacheoffset ) { @@ -138,7 +138,7 @@ int read(int fd, void* buf, int count) } else { headbytes = SECTOR_SIZE - openfiles[fd].cacheoffset; - openfiles[fd].cacheoffset = 0; + openfiles[fd].cacheoffset = -1; } /* eof? */ @@ -169,7 +169,7 @@ int read(int fd, void* buf, int count) count=0; } - openfiles[fd].cacheoffset = 0; + openfiles[fd].cacheoffset = -1; } } @@ -195,6 +195,70 @@ int read(int fd, void* buf, int count) return nread; } +int lseek(int fd, int offset, int whence) +{ + int pos; + int newsector; + int oldsector; + int sectoroffset; + int rc; + + if ( !openfiles[fd].busy ) { + errno = EBADF; + return -1; + } + + switch ( whence ) { + case SEEK_SET: + pos = offset; + break; + + case SEEK_CUR: + pos = openfiles[fd].fileoffset + offset; + break; + + case SEEK_END: + pos = openfiles[fd].size - offset; + break; + + default: + errno = EINVAL; + return -1; + } + if ( (pos < 0) || + (pos > openfiles[fd].size) ) { + errno = EINVAL; + return -1; + } + + /* new sector? */ + newsector = pos / SECTOR_SIZE; + oldsector = openfiles[fd].fileoffset / SECTOR_SIZE; + sectoroffset = pos % SECTOR_SIZE; + + if ( (newsector != oldsector) || + ((openfiles[fd].cacheoffset==-1) && sectoroffset) ) { + if ( newsector != oldsector ) { + rc = fat_seek(&(openfiles[fd].fatfile), newsector); + if ( rc < 0 ) { + errno = EIO; + return -1; + } + } + rc = fat_read(&(openfiles[fd].fatfile), 1, + &(openfiles[fd].cache)); + if ( rc < 0 ) { + errno = EIO; + return -1; + } + } + + openfiles[fd].cacheoffset = sectoroffset; + openfiles[fd].fileoffset = pos; + + return pos; +} + /* * local variables: * eval: (load-file "../rockbox-mode.el") diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 3a3f63d9f1..a55a8a2864 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -838,22 +838,30 @@ int fat_seek(struct fat_file *file, int seeksector ) int numsec = 0; int i; - for (i=0; i<seeksector; i++) { - numsec++; - if ( numsec >= fat_bpb.bpb_secperclus ) { - cluster = get_next_cluster(cluster); - if (!cluster) - /* end of file */ - return -1; - - sector = cluster2sec(cluster); - if (sector<0) - return -2; - numsec=0; + if ( seeksector ) { + for (i=0; i<seeksector; i++) { + numsec++; + if ( numsec >= fat_bpb.bpb_secperclus ) { + cluster = get_next_cluster(cluster); + if (!cluster) + /* end of file */ + return -1; + + sector = cluster2sec(cluster); + if (sector<0) + return -2; + numsec=0; + } + else + sector++; } - else - sector++; } + else { + sector = cluster2sec(cluster); + if (sector<0) + return -2; + } + file->nextcluster = cluster; file->nextsector = sector; file->sectornum = numsec; diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 5490fa9777..6d05dbe600 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c @@ -129,6 +129,59 @@ void dbg_type(char* name) close(fd); } +void dbg_tail(char* name) +{ + unsigned char buf[SECTOR_SIZE*5]; + int fd,rc; + + fd = open(name,O_RDONLY); + if (fd<0) + return; + DEBUGF("Got file descriptor %d\n",fd); + + rc = lseek(fd,512,SEEK_SET); + if ( rc >= 0 ) { + rc = read(fd, buf, SECTOR_SIZE); + if( rc > 0 ) + { + buf[rc]=0; + printf("%d: %s\n", strlen(buf), buf); + } + else if ( rc == 0 ) { + DEBUGF("EOF\n"); + } + else + { + DEBUGF("Failed reading file: %d\n",rc); + } + } + else { + perror("lseek"); + } + + rc = lseek(fd,-100,SEEK_CUR); + if ( rc >= 0 ) { + rc = read(fd, buf, SECTOR_SIZE); + if( rc > 0 ) + { + buf[rc]=0; + printf("%d: %s\n", strlen(buf), buf); + } + else if ( rc == 0 ) { + DEBUGF("EOF\n"); + } + else + { + DEBUGF("Failed reading file: %d\n",rc); + } + } + else { + perror("lseek"); + } + + close(fd); +} + char current_directory[256] = "\\"; int last_secnum = 0; @@ -221,7 +274,8 @@ int main(int argc, char *argv[]) DEBUGF("*** Failed mounting fat\n"); } - dbg_console(); + //dbg_console(); + dbg_tail("/fat.h"); return 0; } |