summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common')
-rw-r--r--firmware/common/dir.c3
-rw-r--r--firmware/common/file.c178
-rw-r--r--firmware/common/file.h16
3 files changed, 140 insertions, 57 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index 70aa4946dc..6bf9a53cad 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -105,8 +105,7 @@ struct dirent* readdir(DIR* dir)
105 return NULL; 105 return NULL;
106 106
107 if ( !entry.name[0] ) 107 if ( !entry.name[0] )
108 return NULL; 108 return NULL;
109
110 109
111 strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) ); 110 strncpy(theent->d_name, entry.name, sizeof( theent->d_name ) );
112 theent->attribute = entry.attr; 111 theent->attribute = entry.attr;
diff --git a/firmware/common/file.c b/firmware/common/file.c
index 2c00c3e3f6..27258e4603 100644
--- a/firmware/common/file.c
+++ b/firmware/common/file.c
@@ -42,23 +42,25 @@ struct filedesc {
42 int size; 42 int size;
43 struct fat_file fatfile; 43 struct fat_file fatfile;
44 bool busy; 44 bool busy;
45 bool write;
45}; 46};
46 47
47static struct filedesc openfiles[MAX_OPEN_FILES]; 48static struct filedesc openfiles[MAX_OPEN_FILES];
48 49
49int open(char* pathname, int flags) 50int creat(const char *pathname, int mode)
51{
52 (void)mode;
53 return open(pathname, O_WRONLY);
54}
55
56int open(const char* pathname, int flags)
50{ 57{
51 DIR* dir; 58 DIR* dir;
52 struct dirent* entry; 59 struct dirent* entry;
53 int fd; 60 int fd;
54 char* name; 61 char* name;
55 62
56 /* For now, we don't support writing */ 63 LDEBUGF("open(\"%s\",%d)\n",pathname,flags);
57 if(flags & (O_WRONLY | O_RDWR))
58 {
59 errno = EROFS;
60 return -1;
61 }
62 64
63 if ( pathname[0] != '/' ) { 65 if ( pathname[0] != '/' ) {
64 DEBUGF("'%s' is not an absolute path.\n",pathname); 66 DEBUGF("'%s' is not an absolute path.\n",pathname);
@@ -75,44 +77,74 @@ int open(char* pathname, int flags)
75 if ( fd == MAX_OPEN_FILES ) { 77 if ( fd == MAX_OPEN_FILES ) {
76 DEBUGF("Too many files open\n"); 78 DEBUGF("Too many files open\n");
77 errno = EMFILE; 79 errno = EMFILE;
78 return -1; 80 return -2;
79 } 81 }
80 82
83 switch ( flags ) {
84 case O_RDONLY:
85 openfiles[fd].write = false;
86 break;
87
88 case O_WRONLY:
89 openfiles[fd].write = true;
90 break;
91
92 default:
93 DEBUGF("Only O_RDONLY and O_WRONLY is supported\n");
94 errno = EROFS;
95 return -3;
96 }
81 openfiles[fd].busy = true; 97 openfiles[fd].busy = true;
82 98
83 /* locate filename */ 99 /* locate filename */
84 name=strrchr(pathname+1,'/'); 100 name=strrchr(pathname+1,'/');
85 if ( name ) { 101 if ( name ) {
86 *name = 0; 102 *name = 0;
87 dir = opendir(pathname); 103 dir = opendir((char*)pathname);
88 *name = '/'; 104 *name = '/';
89 name++; 105 name++;
90 } 106 }
91 else { 107 else {
92 dir = opendir("/"); 108 dir = opendir("/");
93 name = pathname+1; 109 name = (char*)pathname+1;
94 } 110 }
95 if (!dir) { 111 if (!dir) {
96 DEBUGF("Failed opening dir\n"); 112 DEBUGF("Failed opening dir\n");
97 errno = EIO; 113 errno = EIO;
98 openfiles[fd].busy = false; 114 openfiles[fd].busy = false;
99 return -1; 115 return -4;
100 } 116 }
101 117
102 /* scan dir for name */ 118 /* scan dir for name */
103 while ((entry = readdir(dir))) { 119 while ((entry = readdir(dir))) {
104 if ( !strcasecmp(name, entry->d_name) ) { 120 if ( !strcasecmp(name, entry->d_name) ) {
105 fat_open(entry->startcluster, &(openfiles[fd].fatfile)); 121 fat_open(entry->startcluster,
122 &(openfiles[fd].fatfile),
123 &(dir->fatdir));
106 openfiles[fd].size = entry->size; 124 openfiles[fd].size = entry->size;
107 break; 125 break;
108 } 126 }
109 } 127 }
110 closedir(dir); 128 closedir(dir);
111 if ( !entry ) { 129 if ( !entry ) {
112 DEBUGF("Couldn't find %s in %s\n",name,pathname); 130 LDEBUGF("Didn't find file %s\n",name);
113 errno = ENOENT; 131 if ( openfiles[fd].write ) {
114 openfiles[fd].busy = false; 132 if (fat_create_file(name,
115 return -1; 133 &(openfiles[fd].fatfile),
134 &(dir->fatdir)) < 0) {
135 DEBUGF("Couldn't create %s in %s\n",name,pathname);
136 errno = EIO;
137 openfiles[fd].busy = false;
138 return -5;
139 }
140 openfiles[fd].size = 0;
141 }
142 else {
143 DEBUGF("Couldn't find %s in %s\n",name,pathname);
144 errno = ENOENT;
145 openfiles[fd].busy = false;
146 return -6;
147 }
116 } 148 }
117 149
118 openfiles[fd].cacheoffset = -1; 150 openfiles[fd].cacheoffset = -1;
@@ -122,19 +154,37 @@ int open(char* pathname, int flags)
122 154
123int close(int fd) 155int close(int fd)
124{ 156{
157 int rc = 0;
158
159 LDEBUGF("close(%d)\n",fd);
160
125 if (fd < 0 || fd > MAX_OPEN_FILES-1) { 161 if (fd < 0 || fd > MAX_OPEN_FILES-1) {
126 errno = EINVAL; 162 errno = EINVAL;
127 return -1; 163 return -1;
128 } 164 }
129 if (!openfiles[fd].busy) { 165 if (!openfiles[fd].busy) {
130 errno = EBADF; 166 errno = EBADF;
131 return -1; 167 return -2;
168 }
169 if (openfiles[fd].write) {
170 /* flush sector cache */
171 if ( openfiles[fd].cacheoffset != -1 ) {
172 if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
173 &(openfiles[fd].cache),true) < 0 ) {
174 DEBUGF("Failed flushing cache\n");
175 errno = EIO;
176 rc = -1;
177 }
178 }
179
180 /* tie up all loose ends */
181 fat_closewrite(&(openfiles[fd].fatfile), openfiles[fd].size);
132 } 182 }
133 openfiles[fd].busy = false; 183 openfiles[fd].busy = false;
134 return 0; 184 return rc;
135} 185}
136 186
137int read(int fd, void* buf, int count) 187static int readwrite(int fd, void* buf, int count, bool write)
138{ 188{
139 int sectors; 189 int sectors;
140 int nread=0; 190 int nread=0;
@@ -144,9 +194,16 @@ int read(int fd, void* buf, int count)
144 return -1; 194 return -1;
145 } 195 }
146 196
147 /* attempt to read past EOF? */ 197 LDEBUGF( "readwrite(%d,%x,%d,%s)\n",
148 if ( count > openfiles[fd].size - openfiles[fd].fileoffset ) 198 fd,buf,count,write?"write":"read");
149 count = openfiles[fd].size - openfiles[fd].fileoffset; 199
200 /* attempt to access past EOF? */
201 if (count > openfiles[fd].size - openfiles[fd].fileoffset) {
202 if ( write )
203 openfiles[fd].size = openfiles[fd].fileoffset + count;
204 else
205 count = openfiles[fd].size - openfiles[fd].fileoffset;
206 }
150 207
151 /* any head bytes? */ 208 /* any head bytes? */
152 if ( openfiles[fd].cacheoffset != -1 ) { 209 if ( openfiles[fd].cacheoffset != -1 ) {
@@ -163,23 +220,38 @@ int read(int fd, void* buf, int count)
163 openfiles[fd].cacheoffset = -1; 220 openfiles[fd].cacheoffset = -1;
164 } 221 }
165 222
166 /* eof? */ 223 if (write) {
167 if ( openfiles[fd].fileoffset + headbytes > openfiles[fd].size ) 224 memcpy( openfiles[fd].cache + offs, buf, headbytes );
168 headbytes = openfiles[fd].size - openfiles[fd].fileoffset; 225 if (offs+headbytes == SECTOR_SIZE) {
226 int rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
227 openfiles[fd].cache, true );
228 if ( rc < 0 ) {
229 DEBUGF("Failed read/writing %d sectors\n",sectors);
230 errno = EIO;
231 return -2;
232 }
233 openfiles[fd].cacheoffset = -1;
234 }
235 }
236 else {
237 memcpy( buf, openfiles[fd].cache + offs, headbytes );
238 }
169 239
170 memcpy( buf, openfiles[fd].cache + offs, headbytes );
171 nread = headbytes; 240 nread = headbytes;
172 count -= headbytes; 241 count -= headbytes;
242
243 LDEBUGF("readwrite incache: offs=%d\n",openfiles[fd].cacheoffset);
173 } 244 }
174 245
175 /* read whole sectors right into the supplied buffer */ 246 /* read whole sectors right into the supplied buffer */
176 sectors = count / SECTOR_SIZE; 247 sectors = count / SECTOR_SIZE;
177 if ( sectors ) { 248 if ( sectors ) {
178 int rc = fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ); 249 int rc = fat_readwrite(&(openfiles[fd].fatfile), sectors,
250 buf+nread, write );
179 if ( rc < 0 ) { 251 if ( rc < 0 ) {
180 DEBUGF("Failed reading %d sectors\n",sectors); 252 DEBUGF("Failed read/writing %d sectors\n",sectors);
181 errno = EIO; 253 errno = EIO;
182 return -1; 254 return -2;
183 } 255 }
184 else { 256 else {
185 if ( rc > 0 ) { 257 if ( rc > 0 ) {
@@ -197,18 +269,19 @@ int read(int fd, void* buf, int count)
197 269
198 /* any tail bytes? */ 270 /* any tail bytes? */
199 if ( count ) { 271 if ( count ) {
200 if ( fat_read(&(openfiles[fd].fatfile), 1, 272 if (write) {
201 &(openfiles[fd].cache)) < 0 ) { 273 memcpy( openfiles[fd].cache, buf + nread, count );
202 DEBUGF("Failed caching sector\n");
203 errno = EIO;
204 return -1;
205 } 274 }
206 275 else {
207 /* eof? */ 276 if ( fat_readwrite(&(openfiles[fd].fatfile), 1,
208 if ( openfiles[fd].fileoffset + count > openfiles[fd].size ) 277 &(openfiles[fd].cache),false) < 0 ) {
209 count = openfiles[fd].size - openfiles[fd].fileoffset; 278 DEBUGF("Failed caching sector\n");
210 279 errno = EIO;
211 memcpy( buf + nread, openfiles[fd].cache, count ); 280 return -1;
281 }
282 memcpy( buf + nread, openfiles[fd].cache, count );
283 }
284
212 nread += count; 285 nread += count;
213 openfiles[fd].cacheoffset = count; 286 openfiles[fd].cacheoffset = count;
214 } 287 }
@@ -217,6 +290,17 @@ int read(int fd, void* buf, int count)
217 return nread; 290 return nread;
218} 291}
219 292
293int write(int fd, void* buf, int count)
294{
295 return readwrite(fd, buf, count, true);
296}
297
298int read(int fd, void* buf, int count)
299{
300 return readwrite(fd, buf, count, false);
301}
302
303
220int lseek(int fd, int offset, int whence) 304int lseek(int fd, int offset, int whence)
221{ 305{
222 int pos; 306 int pos;
@@ -225,6 +309,8 @@ int lseek(int fd, int offset, int whence)
225 int sectoroffset; 309 int sectoroffset;
226 int rc; 310 int rc;
227 311
312 LDEBUGF("lseek(%d,%d,%d)\n",fd,offset,whence);
313
228 if ( !openfiles[fd].busy ) { 314 if ( !openfiles[fd].busy ) {
229 errno = EBADF; 315 errno = EBADF;
230 return -1; 316 return -1;
@@ -245,11 +331,11 @@ int lseek(int fd, int offset, int whence)
245 331
246 default: 332 default:
247 errno = EINVAL; 333 errno = EINVAL;
248 return -1; 334 return -2;
249 } 335 }
250 if ((pos < 0) || (pos > openfiles[fd].size)) { 336 if ((pos < 0) || (pos > openfiles[fd].size)) {
251 errno = EINVAL; 337 errno = EINVAL;
252 return -1; 338 return -3;
253 } 339 }
254 340
255 /* new sector? */ 341 /* new sector? */
@@ -263,14 +349,14 @@ int lseek(int fd, int offset, int whence)
263 rc = fat_seek(&(openfiles[fd].fatfile), newsector); 349 rc = fat_seek(&(openfiles[fd].fatfile), newsector);
264 if ( rc < 0 ) { 350 if ( rc < 0 ) {
265 errno = EIO; 351 errno = EIO;
266 return -1; 352 return -4;
267 } 353 }
268 } 354 }
269 rc = fat_read(&(openfiles[fd].fatfile), 1, 355 rc = fat_readwrite(&(openfiles[fd].fatfile), 1,
270 &(openfiles[fd].cache)); 356 &(openfiles[fd].cache),false);
271 if ( rc < 0 ) { 357 if ( rc < 0 ) {
272 errno = EIO; 358 errno = EIO;
273 return -1; 359 return -5;
274 } 360 }
275 openfiles[fd].cacheoffset = sectoroffset; 361 openfiles[fd].cacheoffset = sectoroffset;
276 } 362 }
diff --git a/firmware/common/file.h b/firmware/common/file.h
index c95811fc55..7a7c63d665 100644
--- a/firmware/common/file.h
+++ b/firmware/common/file.h
@@ -40,24 +40,22 @@
40#endif 40#endif
41 41
42#if defined(__MINGW32__) && defined(SIMULATOR) 42#if defined(__MINGW32__) && defined(SIMULATOR)
43int open (const char*, int, ...); 43extern int open(const char*, int, ...);
44extern int close(int fd); 44extern int close(int fd);
45int read (int, void*, unsigned int); 45extern int read(int, void*, unsigned int);
46long lseek (int, long, int); 46extern long lseek(int, long, int);
47 47
48#else 48#else
49 49
50#ifndef SIMULATOR 50#ifndef SIMULATOR
51extern int open(char* pathname, int flags); 51extern int open(const char* pathname, int flags);
52extern int close(int fd); 52extern int close(int fd);
53extern int read(int fd, void* buf, int count); 53extern int read(int fd, void* buf, int count);
54extern int lseek(int fd, int offset, int whence); 54extern int lseek(int fd, int offset, int whence);
55 55extern int creat(const char *pathname, int mode);
56#ifdef DISK_WRITE
57extern int write(int fd, void* buf, int count); 56extern int write(int fd, void* buf, int count);
58extern int remove(char* pathname); 57extern int remove(const char* pathname);
59extern int rename(char* oldname, char* newname); 58extern int rename(const char* oldname, const char* newname);
60#endif
61 59
62#else 60#else
63#ifdef WIN32 61#ifdef WIN32