00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00020 #include "task.h"
00021
00022 #include <_ansi.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <sys/fcntl.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <time.h>
00029 #include <sys/time.h>
00030 #include <sys/times.h>
00031 #include <errno.h>
00032 #include <reent.h>
00033 #include <signal.h>
00034 #include <unistd.h>
00035 #include <sys/wait.h>
00036
00037 #include "../uart/uart0.h"
00038 #include "../uart/uart1.h"
00039 #include "../usbser/usbser.h"
00040 #include "../rtc/rtc.h"
00041 #include "../fatfs/ff.h"
00042 #ifdef CFG_TELNETD
00043 #include "../uip/apps/telnetd/telnetd.h"
00044 #endif
00045
00046
00047
00048
00049 int _mkdir _PARAMS ((const char *, mode_t));
00050 int _chmod _PARAMS ((const char *, mode_t));
00051 int _read _PARAMS ((int, char *, int));
00052 int _lseek _PARAMS ((int, int, int));
00053 int _write _PARAMS ((int, const char *, int));
00054 int _open _PARAMS ((const char *, int, ...));
00055 int _close _PARAMS ((int));
00056 int _fstat _PARAMS ((int, struct stat *));
00057 int _stat _PARAMS ((const char *, struct stat *));
00058 int _link _PARAMS ((void));
00059 int _unlink _PARAMS ((const char *));
00060 int _rename _PARAMS ((const char *, const char *));
00061 void _sync _PARAMS ((void));
00062 void syscallsInit _PARAMS ((void));
00063
00064 int rename _PARAMS ((const char *, const char *));
00065
00066 static int set_errno _PARAMS ((int));
00067 static int remap_handle _PARAMS ((int));
00068 static int findslot _PARAMS ((int));
00069
00070
00071
00072
00073 register char *stack_ptr asm ("sp");
00074
00075
00076
00077
00078 extern void _EXFUN (__sinit,( struct _reent *));
00079
00080 #define CHECK_INIT(ptr) \
00081 do \
00082 { \
00083 if ((ptr) && !(ptr)->__sdidinit) \
00084 __sinit (ptr); \
00085 } \
00086 while (0)
00087
00088
00089
00090
00091 #define FILE_HANDLE_OFFSET (0x20)
00092
00093 #define MONITOR_STDIN 0
00094 #define MONITOR_STDOUT 1
00095 #define MONITOR_STDERR 2
00096 #define MONITOR_UART0 3
00097 #define MONITOR_UART1 4
00098 #define MONITOR_USB 5
00099 #define MONITOR_FATFS 6
00100
00101
00102
00103
00104 typedef struct
00105 {
00106 int handle;
00107 int pos;
00108 int flags;
00109 FIL *fatfsFCB;
00110 }
00111 openFiles_t;
00112
00113
00114
00115
00116 #define MAX_OPEN_FILES 10
00117 static openFiles_t openfiles [MAX_OPEN_FILES];
00118
00119 static int findslot (int fh)
00120 {
00121 static int slot;
00122 static int lastfh = -1;
00123
00124 if ((fh != -1) && (fh == lastfh))
00125 return slot;
00126
00127 for (slot = 0; slot < MAX_OPEN_FILES; slot++)
00128 if (openfiles [slot].handle == fh)
00129 break;
00130
00131 lastfh = fh;
00132
00133 return slot;
00134 }
00135
00136
00137
00138
00139 static int remap_handle (int fh)
00140 {
00141 CHECK_INIT(_REENT);
00142
00143 if (fh == STDIN_FILENO)
00144 return MONITOR_STDIN;
00145 if (fh == STDOUT_FILENO)
00146 return MONITOR_STDOUT;
00147 if (fh == STDERR_FILENO)
00148 return MONITOR_STDERR;
00149
00150 return fh - FILE_HANDLE_OFFSET;
00151 }
00152
00153
00154 static int remap_fatfs_errors (FRESULT f)
00155 {
00156 switch (f)
00157 {
00158 case FR_NO_FILE : errno = ENOENT; break;
00159 case FR_NO_PATH : errno = ENOENT; break;
00160 case FR_INVALID_NAME : errno = EINVAL; break;
00161 case FR_INVALID_DRIVE : errno = ENODEV; break;
00162 case FR_DENIED : errno = EACCES; break;
00163 case FR_EXIST : errno = EEXIST; break;
00164 case FR_NOT_READY : errno = EIO; break;
00165 case FR_WRITE_PROTECTED : errno = EACCES; break;
00166 case FR_RW_ERROR : errno = EIO; break;
00167 case FR_NOT_ENABLED : errno = EIO; break;
00168 case FR_NO_FILESYSTEM : errno = EIO; break;
00169 case FR_INVALID_OBJECT : errno = EBADF; break;
00170 default : errno = EIO; break;
00171 }
00172
00173 return -1;
00174 }
00175
00176
00177 static time_t fatfs_time_to_timet (FILINFO *f)
00178 {
00179 struct tm tm;
00180
00181 tm.tm_sec = (f->ftime & 0x001f) << 1;
00182 tm.tm_min = (f->ftime & 0x07e0) >> 5;
00183 tm.tm_hour = (f->ftime & 0xf800) >> 11;
00184 tm.tm_mday = (f->fdate & 0x001f);
00185 tm.tm_mon = ((f->fdate & 0x01e0) >> 5) - 1;
00186 tm.tm_year = ((f->fdate & 0xfe00) >> 9) + 80;
00187 tm.tm_isdst = 0;
00188
00189 return mktime (&tm);
00190 }
00191
00192
00193 static int set_errno (int errval)
00194 {
00195 errno = errval;
00196
00197 return -1;
00198 }
00199
00200
00201 void syscallsInit (void)
00202 {
00203 int slot;
00204 static int initialized = 0;
00205
00206 if (initialized)
00207 return;
00208
00209 initialized = 1;
00210
00211 __builtin_memset (openfiles, 0, sizeof (openfiles));
00212
00213 for (slot = 0; slot < MAX_OPEN_FILES; slot++)
00214 openfiles [slot].handle = -1;
00215
00216 openfiles [0].handle = MONITOR_STDIN;
00217 openfiles [1].handle = MONITOR_STDOUT;
00218 openfiles [2].handle = MONITOR_STDERR;
00219 }
00220
00221
00222 int _mkdir (const char *path, mode_t mode __attribute__ ((unused)))
00223 {
00224 FRESULT f;
00225
00226 if ((f = f_mkdir (path)) != FR_OK)
00227 return remap_fatfs_errors (f);
00228
00229 return 0;
00230 }
00231
00232
00233 int _chmod (const char *path, mode_t mode)
00234 {
00235 FRESULT f;
00236
00237 if ((f = f_chmod (path, (mode & S_IWUSR) ? 0 : AM_RDO, AM_RDO)) != FR_OK)
00238 return remap_fatfs_errors (f);
00239
00240 return 0;
00241 }
00242
00243
00244 int _read (int fd, char *ptr, int len)
00245 {
00246 int i;
00247 int fh;
00248 int slot;
00249 portTickType xBlockTime;
00250 int bytesUnRead = -1;
00251
00252 if ((slot = findslot (fh = remap_handle (fd))) == MAX_OPEN_FILES)
00253 return set_errno (EBADF);
00254
00255 if (openfiles [slot].flags & O_WRONLY)
00256 return set_errno (EBADF);
00257
00258 xBlockTime = (openfiles [slot].flags & O_NONBLOCK) ? 0 : portMAX_DELAY;
00259
00260 if (openfiles [slot].fatfsFCB)
00261 {
00262 FRESULT f;
00263 U16 fatfsBytesRead;
00264
00265 if ((f = f_read (openfiles [slot].fatfsFCB, ptr, len, &fatfsBytesRead)) != FR_OK)
00266 return remap_fatfs_errors (f);
00267
00268 bytesUnRead = len - fatfsBytesRead;
00269 }
00270
00271 if (bytesUnRead < 0)
00272 return -1;
00273
00274 openfiles [slot].pos += len - bytesUnRead;
00275
00276 return len - bytesUnRead;
00277 }
00278
00279
00280 int _lseek (int fd, int ptr, int dir)
00281 {
00282 int fh;
00283 int slot;
00284 FRESULT f = FR_INVALID_OBJECT;
00285
00286 if (((slot = findslot (fh = remap_handle (fd))) == MAX_OPEN_FILES) || !openfiles [slot].fatfsFCB)
00287 return set_errno (EBADF);
00288
00289 if (dir == SEEK_SET)
00290 f = f_lseek (openfiles [slot].fatfsFCB, ptr);
00291 else if (dir == SEEK_CUR)
00292 f = f_lseek (openfiles [slot].fatfsFCB, openfiles [slot].fatfsFCB->fptr + ptr);
00293 else if (dir == SEEK_END)
00294 f = f_lseek (openfiles [slot].fatfsFCB, openfiles [slot].fatfsFCB->fsize + ptr);
00295
00296 if (f != FR_OK)
00297 return remap_fatfs_errors (f);
00298
00299 return openfiles [slot].pos = openfiles [slot].fatfsFCB->fptr;
00300 }
00301
00302
00303 int _write (int fd, const char *ptr, int len)
00304 {
00305 int i;
00306 int fh;
00307 int slot;
00308 portTickType xBlockTime;
00309 int bytesUnWritten = -1;
00310
00311 if ((slot = findslot (fh = remap_handle (fd))) == MAX_OPEN_FILES)
00312 return set_errno (EBADF);
00313
00314 if (openfiles [slot].flags & O_RDONLY)
00315 return set_errno (EBADF);
00316
00317 xBlockTime = (openfiles [slot].flags & O_NONBLOCK) ? 0 : portMAX_DELAY;
00318
00319 if (openfiles [slot].fatfsFCB)
00320 {
00321 FRESULT f;
00322 U16 fatfsBytesWritten;
00323
00324 if ((f = f_write (openfiles [slot].fatfsFCB, ptr, len, &fatfsBytesWritten)) != FR_OK)
00325 return remap_fatfs_errors (f);
00326
00327 bytesUnWritten = len - fatfsBytesWritten;
00328 }
00329 else
00330 return set_errno (EBADF);
00331
00332 if (bytesUnWritten == -1 || bytesUnWritten == len)
00333 return -1;
00334
00335 openfiles [slot].pos += len - bytesUnWritten;
00336
00337 return len - bytesUnWritten;
00338 }
00339
00340
00341 int _open (const char *path, int flags, ...)
00342 {
00343 int fh = 0;
00344 int slot;
00345
00346 if ((slot = findslot (-1)) == MAX_OPEN_FILES)
00347 return set_errno (ENFILE);
00348
00349 if (flags & O_APPEND)
00350 flags &= ~O_TRUNC;
00351
00352 U8 fatfsFlags = FA_OPEN_EXISTING;
00353 FRESULT f;
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 if (((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) && (flags & (O_RDWR | O_WRONLY)))
00366 fatfsFlags = FA_CREATE_ALWAYS;
00367 else if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
00368 fatfsFlags = FA_OPEN_EXISTING;
00369 else if ((flags & O_CREAT) == O_CREAT)
00370 fatfsFlags = FA_OPEN_ALWAYS;
00371 else if ((flags == O_RDONLY) || (flags == O_WRONLY) || (flags == O_RDWR))
00372 fatfsFlags = FA_OPEN_EXISTING;
00373 else
00374 return set_errno (EINVAL);
00375
00376 if ((flags & O_ACCMODE) == O_RDONLY)
00377 fatfsFlags |= FA_READ;
00378 else if ((flags & O_ACCMODE) == O_WRONLY)
00379 fatfsFlags |= FA_WRITE;
00380 else if ((flags & O_ACCMODE) == O_RDWR)
00381 fatfsFlags |= (FA_READ | FA_WRITE);
00382 else
00383 return set_errno (EINVAL);
00384
00385 fh = -1;
00386 errno = EIO;
00387
00388 if (!openfiles [slot].fatfsFCB)
00389 if ((openfiles [slot].fatfsFCB = __builtin_calloc (1, sizeof (FIL))))
00390 if ((fh = ((f = f_open (openfiles [slot].fatfsFCB, path, fatfsFlags)) == FR_OK) ? (slot + MONITOR_FATFS) : -1) == -1)
00391 remap_fatfs_errors (f);
00392
00393 if (fh >= 0)
00394 {
00395 openfiles [slot].handle = fh;
00396 openfiles [slot].pos = 0;
00397 openfiles [slot].flags = flags;
00398
00399 if (flags & O_APPEND)
00400 {
00401 if (f_lseek (openfiles [slot].fatfsFCB, openfiles [slot].fatfsFCB->fsize) != FR_OK)
00402 fh = -1;
00403 else
00404 openfiles [slot].pos = openfiles [slot].fatfsFCB->fptr;
00405 }
00406 }
00407
00408 if ((fh < 0) && openfiles [slot].fatfsFCB)
00409 {
00410 free (openfiles [slot].fatfsFCB);
00411 openfiles [slot].fatfsFCB = NULL;
00412 }
00413
00414 return fh >= 0 ? (fh + FILE_HANDLE_OFFSET) : -1;
00415 }
00416
00417
00418 int _close (int fd)
00419 {
00420 int slot;
00421
00422 if ((slot = findslot (remap_handle (fd))) == MAX_OPEN_FILES)
00423 return set_errno (EBADF);
00424
00425 openfiles [slot].handle = -1;
00426
00427 if (openfiles [slot].fatfsFCB)
00428 {
00429 FRESULT f;
00430
00431 f = f_close (openfiles [slot].fatfsFCB);
00432 free (openfiles [slot].fatfsFCB);
00433 openfiles [slot].fatfsFCB = NULL;
00434
00435 if (f != FR_OK)
00436 return remap_fatfs_errors (f);
00437 }
00438
00439 return 0;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 int _fstat (int fd __attribute__ ((unused)), struct stat *st __attribute__ ((unused)))
00451 {
00452 return set_errno (ENOSYS);
00453 }
00454
00455 int _stat (const char *fname, struct stat *st)
00456 {
00457 FRESULT f;
00458 FILINFO fi;
00459
00460 if ((f = f_stat (fname, &fi)) != FR_OK)
00461 return remap_fatfs_errors (f);
00462
00463 __builtin_memset (st, 0, sizeof (* st));
00464
00465 st->st_mode |= (fi.fattrib & AM_DIR) ? S_IFDIR : S_IFREG;
00466 st->st_mode |= (fi.fattrib & AM_RDO) ? ((S_IRWXU & ~S_IWUSR) | (S_IRWXG & ~S_IWGRP) | (S_IRWXO & ~S_IWOTH)) : (S_IRWXU | S_IRWXG | S_IRWXO);
00467 st->st_size = fi.fsize;
00468 st->st_ctime = fatfs_time_to_timet (&fi);
00469 st->st_mtime = st->st_ctime;
00470 st->st_atime = st->st_ctime;
00471 st->st_blksize = 512;
00472
00473 return 0;
00474 }
00475
00476
00477
00478
00479 int _link (void)
00480 {
00481 return set_errno (ENOSYS);
00482 }
00483
00484 int _unlink (const char *path)
00485 {
00486 FRESULT f;
00487
00488 if ((f = f_unlink (path)) != FR_OK)
00489 return remap_fatfs_errors (f);
00490
00491 return 0;
00492 }
00493
00494
00495 int _rename (const char *oldpath, const char *newpath)
00496 {
00497 #ifdef CFG_FATFS
00498 FRESULT f;
00499
00500 if ((f = f_rename (oldpath, newpath)))
00501 return remap_fatfs_errors (f);
00502
00503 return 0;
00504 #else
00505 oldpath = oldpath;
00506 newpath = newpath;
00507 return set_errno (EIO);
00508 #endif
00509 }
00510
00511
00512
00513
00514
00515
00516 int rename (const char *oldpath, const char *newpath)
00517 {
00518 return _rename (oldpath, newpath);
00519 }
00520
00521 void _sync (void)
00522 {
00523 int slot;
00524
00525 for (slot = 0; slot < MAX_OPEN_FILES; slot++)
00526 if (openfiles [slot].fatfsFCB)
00527 f_sync (openfiles [slot].fatfsFCB);
00528 }