summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-08 15:16:02 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-08 15:16:02 +0000
commit1c3217909b444b86f87f976925f05ac05555cc6d (patch)
treea88403f37f9ea9cab683c74ff0dd05e50cd45ac9
parent6a63f911fef19eae9aaa96b20dbe57aab63399d9 (diff)
Added lseek()
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@518 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/common/file.c72
-rw-r--r--firmware/drivers/fat.c36
-rw-r--r--firmware/test/fat/main.c56
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;
}