APM:Libraries
posix.c
Go to the documentation of this file.
1 
110 #include <string.h>
111 #include "posix.h"
112 #include "stdio.h"
113 #undef strerror_r
114 
116 
118 int errno;
119 
120 
128 FILE *__iob[MAX_FILES];
129 
133 const char *sys_errlist[] =
134 {
135  "OK",
136  "Operation not permitted",
137  "No such file or directory",
138  "No such process",
139  "Interrupted system call",
140  "I/O error",
141  "No such device or address",
142  "Argument list too long",
143  "Exec format error",
144  "Bad file number",
145  "No child processes",
146  "Try again",
147  "Out of memory",
148  "Permission denied",
149  "Bad address",
150  "Block device required",
151  "Device or resource busy",
152  "File exists",
153  "Cross-device link",
154  "No such device",
155  "Not a directory",
156  "Is a directory",
157  "Invalid argument",
158  "File table overflow",
159  "Too many open files",
160  "Not a typewriter",
161  "Text file busy",
162  "File too large",
163  "No space left on device",
164  "Illegal seek",
165  "Read-only file system",
166  "Too many links",
167  "Broken pipe",
168  "Math argument out of domain of func",
169  "Math result not representable",
170  "Bad Message",
171  NULL
172 };
173 
174 // =============================================
184 
185 int isatty(int fileno)
186 {
188  if(fileno >= 0 && fileno <= 2)
189  return(1);
190  return 0;
191 }
192 
203 
204 int
205 fgetc(FILE *stream)
206 {
207  int c;
208 
209  if(stream == NULL)
210  {
211  errno = EBADF; // Bad File Number
212  return(EOF);
213  }
214 
215  if ((stream->flags & __SRD) == 0)
216  return EOF;
217 
218  if ((stream->flags & __SUNGET) != 0) {
219  stream->flags &= ~__SUNGET;
220  stream->len++;
221  return stream->unget;
222  }
223 
224  if (stream->flags & __SSTR) {
225  c = *stream->buf;
226  if (c == '\0') {
227  stream->flags |= __SEOF;
228  return EOF;
229  } else {
230  stream->buf++;
231  }
232  } else {
233  if(!stream->get)
234  {
235  return(EOF);
236  }
237  // get character from device or file
238  c = stream->get(stream);
239  if (c < 0) {
240  /* if != _FDEV_ERR, assume its _FDEV_EOF */
241  stream->flags |= (c == _FDEV_ERR)? __SERR: __SEOF;
242  return EOF;
243  }
244  }
245 
246  stream->len++;
247  return (c);
248 }
249 
250 int getc(FILE *fp) {
251  return (fgetc (fp));
252 }
262 
263 int
264 fputc(int c, FILE *stream)
265 {
266  errno = 0;
267  int ret;
268 
269  if(stream != stdout && stream != stderr)
270  {
271  return(fatfs_putc(c,stream));
272  }
273 
274  // TTY outputs
275 
276  if ((stream->flags & __SWR) == 0)
277  return EOF;
278 
279  if (stream->flags & __SSTR) {
280  if (stream->len < stream->size)
281  *stream->buf++ = c;
282  stream->len++;
283  return c;
284  } else {
285  if(!stream->put)
286  {
287  return(EOF);
288  }
289  ret = stream->put(c, stream);
290  if(ret != EOF)
291  stream->len++;
292  return(ret);
293  }
294 }
295 
296 void clearerr(FILE *stream)
297 {
298  stream->flags = 0;
299 }
300 
301 
303 #ifndef IO_MACROS
304 
313 int
315 {
316  return(fgetc(stdin));
317 }
318 
327 
328 int
329 putchar(int c)
330 {
331  return(fputc(c,stdout));
332 }
333 #endif
334 
344 /*
345 int
346 ungetc(int c, FILE *stream)
347 {
348  int fd = fileno(stream);
349  if(!isatty(fd))
350  return(EOF);
351 
352  if(c == EOF)
353  return EOF;
354  if((stream->flags & __SUNGET) != 0 )
355  return EOF;
356  if ((stream->flags & __SRD) == 0 )
357  return EOF;
358 
359  stream->flags |= __SUNGET;
360  stream->flags &= ~__SEOF;
361 
362  stream->unget = c;
363  stream->len--;
364 
365  return (c);
366 }
367 */
368 #ifndef IO_MACROS
369 // =============================================
377 
378 int
379 putc(int c, FILE *stream)
380 {
381  return(fputc(c, stream));
382 }
383 
384 #endif
385 
386 // =============================================
396 
397 char *
398 fgets(char *str, int size, FILE *stream)
399 {
400  int c;
401  int ind = 0;
402  while(size--)
403  {
404  c = fgetc(stream);
405  if(c == EOF)
406  {
407  if( ind == 0)
408  return(NULL);
409  break;
410  }
411  if(c == '\n')
412  break;
413  if(c == 0x08)
414  {
415  if(ind > 0)
416  --ind;
417  continue;
418  }
419  str[ind++] = c;
420  }
421  str[ind] = 0;
422  return(str);
423 }
424 
425 
428 char *
429 gets (char *p)
430 {
431  char *s;
432  int n;
433 
434  s = fgets (p, MAXLN, stdin);
435  if (s == 0)
436  return (0);
437  n = strlen (p);
438  if (n && p[n - 1] == '\n')
439  p[n - 1] = 0;
440  return (s);
441 }
450 
451 int
452 fputs(const char *str, FILE *stream)
453 {
454  while(*str)
455  {
456  if(fputc(*str, stream) == EOF)
457  return(EOF);
458  ++str;
459  }
460  return(0);
461 }
462 
463 
464 #ifndef IO_MACROS
465 
474 int
475 puts(const char *str)
476 {
477  while(*str)
478  {
479  if(fputc(*str, stdout) == EOF)
480  return(EOF);
481  ++str;
482  }
483  return ( fputc('\n',stdout) );
484 }
485 
486 #endif
487 
488 
489 // =============================================
490 // =============================================
492 // =============================================
493 // =============================================
499 
500 int feof(FILE *stream)
501 {
502  if(stream->flags & __SEOF)
503  return(1);
504  return(0);
505 }
506 
516 
517 int fgetpos(FILE *stream, size_t *pos)
518 {
519  long offset = ftell(stream);
520  *pos = offset;
521  if(offset == -1)
522  return(-1);
523  return( 0 );
524 }
525 
539 
540 int fseek(FILE *stream, long offset, int whence)
541 {
542  long ret;
543 
544  int fn = fileno(stream);
545  if(fn < 0)
546  return(-1);
547 
548  ret = lseek(fn, offset, whence);
549 
550  if(ret == -1)
551  return(-1);
552 
553  return(0);
554 }
555 
565 
566 int fsetpos(FILE *stream, size_t *pos)
567 {
568  return (fseek(stream, (size_t) *pos, SEEK_SET) );
569 }
570 
579 
580 long ftell(FILE *stream)
581 {
582  errno = 0;
583 
584  int fn = fileno(stream);
585  if(isatty(fn))
586  return(-1);
587  // fileno_to_fatfs checks for fd out of bounds
588  FIL *fh = fileno_to_fatfs(fn);
589  if ( fh == NULL )
590  {
591  errno = EBADF;
592  return(-1);
593  }
594 
595  return( fh->fptr );
596 }
597 
611 
612 off_t lseek(int fileno, off_t position, int whence)
613 {
614  FRESULT res;
615  FIL *fh;
616  errno = 0;
617  FILE *stream;
618 
619 
620  // fileno_to_fatfs checks for fd out of bounds
621  fh = fileno_to_fatfs(fileno);
622  if(fh == NULL)
623  {
624  errno = EMFILE;
625  return(-1);
626  }
627  if(isatty(fileno))
628  return(-1);
629 
630 
631  stream = fileno_to_stream(fileno);
632  stream->flags |= __SUNGET;
633 
634  if(whence == SEEK_END)
635  position += f_size(fh);
636  else if(whence==SEEK_CUR)
637  position += fh->fptr;
638 
639  res = f_lseek(fh, position);
640  if(res)
641  {
642  errno = fatfs_to_errno(res);
643  return -1;
644  }
645  return (fh->fptr);
646 }
647 
655 
656 void rewind( FILE *stream)
657 {
658  fseek(stream, 0L, SEEK_SET);
659 }
660 
661 // =============================================
662 // =============================================
664 // =============================================
665 // =============================================
674 
675 int close(int fileno)
676 {
677  FILE *stream;
678  FIL *fh;
679  int res;
680 
681  errno = 0;
682 
683  // checks if fileno out of bounds
684  stream = fileno_to_stream(fileno);
685  if(stream == NULL)
686  {
687  return(-1);
688  }
689 
690  // fileno_to_fatfs checks for fileno out of bounds
691  fh = fileno_to_fatfs(fileno);
692  if(fh == NULL)
693  {
694  return(-1);
695  }
696  res = f_close(fh);
697  free_file_descriptor(fileno);
698  if (res != FR_OK)
699  {
700  errno = fatfs_to_errno(res);
701  return(-1);
702  }
703  return(0);
704 }
705 
713 
714 int fileno(FILE *stream)
715 {
716  int fileno;
717 
718  if(stream == NULL)
719  {
720  errno = EBADF;
721  return(-1);
722  }
723 
724  for(fileno=0; fileno<MAX_FILES; ++fileno)
725  {
726  if ( __iob[fileno] == stream)
727  return(fileno);
728  }
729  return(-1);
730 }
731 
743 
745 {
746  FILE *stream;
747  if(fileno < 0 || fileno >= MAX_FILES)
748  {
749  errno = EBADF;
750  return(NULL);
751  }
752 
753  stream = __iob[fileno];
754  if(stream == NULL)
755  {
756  errno = EBADF;
757  return(NULL);
758  }
759  return(stream);
760 }
761 
771 
772 FILE *fopen(const char *path, const char *mode)
773 {
774  int flags = posix_fopen_modes_to_open(mode);
775  int fileno = open(path, flags);
776 
777  // checks if fileno out of bounds
778  return( fileno_to_stream(fileno) );
779 }
780 
792 
793 size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
794 {
795  size_t count = size * nmemb;
796  int fn = fileno(stream);
797  ssize_t ret;
798 
799  // read() checks for fn out of bounds
800  ret = read(fn, ptr, count);
801  if(ret < 0)
802  return(0);
803 
804  return((size_t) ret);
805 }
806 
816 
817 int ftruncate(int fd, off_t length)
818 {
819  errno = 0;
820  FIL *fh;
821  FRESULT rc;
822 
823  if(isatty(fd))
824  return(-1);
825  // fileno_to_fatfs checks for fd out of bounds
826  fh = fileno_to_fatfs(fd);
827  if(fh == NULL)
828  {
829  return(-1);
830  }
831  rc = f_lseek(fh, length);
832  if (rc != FR_OK)
833  {
834  errno = fatfs_to_errno(rc);
835  return(-1);
836  }
837  rc = f_truncate(fh);
838  if (rc != FR_OK)
839  {
840  errno = fatfs_to_errno(rc);
841  return(-1);
842  }
843  return(0);
844 }
845 
857 
858 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
859 {
860  size_t count = size * nmemb;
861  int fn = fileno(stream);
862  ssize_t ret;
863 
864  // write () checks for fn out of bounds
865  ret = write(fn, ptr, count);
866 
867  if(ret < 0)
868  return(0);
869 
870  return((size_t) ret);
871 }
872 
873 
874 
884 
885 int open(const char *pathname, int flags)
886 {
887  int fileno;
888  int fatfs_modes;
889  FILE *stream;
890  FIL *fh;
891  int res;
892 
893  errno = 0;
894 // FIXME Assume here that the disk interface mmc_init was already called
895 #if 0
896 // Checks Disk status
897  res = mmc_init(0);
898 
899  if(res != RES_OK)
900  {
901  errno = fatfs_to_errno(res);
902  return(-1);
903  }
904 #endif
905 
906  if((flags & O_ACCMODE) == O_RDWR)
907  fatfs_modes = FA_READ | FA_WRITE;
908  else if((flags & O_ACCMODE) == O_RDONLY)
909  fatfs_modes = FA_READ;
910  else
911  fatfs_modes = FA_WRITE;
912 
913  if(flags & O_CREAT)
914  {
915  if(flags & O_TRUNC)
916  fatfs_modes |= FA_CREATE_ALWAYS;
917  else
918  fatfs_modes |= FA_OPEN_ALWAYS;
919  }
920 
921  fileno = new_file_descriptor();
922 
923  // checks if fileno out of bounds
924  stream = fileno_to_stream(fileno);
925  if(stream == NULL)
926  {
927  free_file_descriptor(fileno);
928  return(-1);
929  }
930 
931  // fileno_to_fatfs checks for fileno out of bounds
932  fh = fileno_to_fatfs(fileno);
933  if(fh == NULL)
934  {
935  free_file_descriptor(fileno);
936  errno = EBADF;
937  return(-1);
938  }
939  res = f_open(fh, pathname, (BYTE) (fatfs_modes & 0xff));
940  if(res != FR_OK)
941  {
942  errno = fatfs_to_errno(res);
943  free_file_descriptor(fileno);
944  return(-1);
945  }
946  if(flags & O_APPEND)
947  {
949  res = f_lseek(fh, f_size(fh));
950  if (res != FR_OK)
951  {
952  errno = fatfs_to_errno(res);
953  f_close(fh);
954  free_file_descriptor(fileno);
955  return(-1);
956  }
957  }
958 
959  if((flags & O_ACCMODE) == O_RDWR)
960  {
961  // FIXME fdevopen should do this
962  stream->put = fatfs_putc;
963  stream->get = fatfs_getc;
964  stream->flags = _FDEV_SETUP_RW;
965  }
966  else if((flags & O_ACCMODE) == O_RDONLY)
967  {
968  // FIXME fdevopen should do this
969  stream->put = NULL;
970  stream->get = fatfs_getc;
971  stream->flags = _FDEV_SETUP_READ;
972  }
973  else
974  {
975  // FIXME fdevopen should do this
976  stream->put = fatfs_putc;
977  stream->get = NULL;
978  stream->flags = _FDEV_SETUP_WRITE;
979  }
980 
981  return(fileno);
982 }
983 
994 
995 ssize_t read(int fd, void *buf, size_t count)
996 {
997  UINT size;
998  UINT bytes = count;
999  int res;
1000  int ret;
1001  FIL *fh;
1002  FILE *stream;
1003 
1004  //FIXME
1005  *(char *) buf = 0;
1006 
1007  errno = 0;
1008 
1009  // TTY read function
1010  // FIXME should we really be blocking ???
1011  stream = fileno_to_stream(fd);
1012  if(stream == stdin)
1013  {
1014  char *ptr = (char *) buf;
1015  // ungetc is undefined for read
1016  stream->flags |= __SUNGET;
1017  size = 0;
1018  while(count--)
1019  {
1020  ret = fgetc(stream);
1021  if(ret < 0)
1022  break;
1023 
1024  *ptr++ = ret;
1025  ++size;
1026  }
1027  return(size);
1028  }
1029  if(stream == stdout || stream == stderr)
1030  {
1031  return(-1);
1032  }
1033 
1034  // fileno_to_fatfs checks for fd out of bounds
1035  fh = fileno_to_fatfs(fd);
1036  if ( fh == NULL )
1037  {
1038  errno = EBADF;
1039  return(-1);
1040  }
1041 
1042  res = f_read(fh, (void *) buf, bytes, &size);
1043  if(res != FR_OK)
1044  {
1045  errno = fatfs_to_errno(res);
1046  return(-1);
1047  }
1048  return ((ssize_t) size);
1049 }
1050 
1051 
1057 
1058 void sync(void)
1059 {
1060  FIL *fh;
1061  int i;
1062 
1063  for(i=0;i<MAX_FILES;++i)
1064  {
1065  if(isatty(i))
1066  continue;
1067 
1068  // fileno_to_fatfs checks for i out of bounds
1069  fh = fileno_to_fatfs(i);
1070  if(fh == NULL)
1071  continue;
1072 
1073  (void ) syncfs(i);
1074  }
1075 }
1076 
1084 
1085 int syncfs(int fd)
1086 {
1087  FIL *fh;
1088  FRESULT res;
1089  FILE *stream;
1090 
1091  errno = 0;
1092 
1093  if(isatty(fd))
1094  {
1095  errno = EBADF;
1096  return(-1);
1097  }
1098  stream = fileno_to_stream(fd);
1099  // reset unget on sync
1100  stream->flags |= __SUNGET;
1101 
1102  // fileno_to_fatfs checks for fd out of bounds
1103  fh = fileno_to_fatfs(fd);
1104  if(fh == NULL)
1105  {
1106  errno = EBADF;
1107  return(-1);
1108  }
1109 
1110  res = f_sync ( fh );
1111  if (res != FR_OK)
1112  {
1113  errno = fatfs_to_errno(res);
1114  return(-1);
1115  }
1116  return(0);
1117 }
1118 
1119 
1120 
1130 
1131 int truncate(const char *path, off_t length)
1132 {
1133  errno = 0;
1134  FIL fh;
1135  FRESULT rc;
1136 
1137  rc = f_open(&fh , path, FA_OPEN_EXISTING | FA_READ | FA_WRITE);
1138  if (rc != FR_OK)
1139  {
1140  errno = fatfs_to_errno(rc);
1141  return(-1);
1142  }
1143  rc = f_lseek(&fh, length);
1144  if (rc != FR_OK)
1145  {
1146  errno = fatfs_to_errno(rc);
1147  return(-1);
1148  }
1149  rc = f_truncate(&fh);
1150  if (rc != FR_OK)
1151  {
1152  errno = fatfs_to_errno(rc);
1153  return(-1);
1154  }
1155  return(0);
1156 }
1157 
1158 
1168 
1169 ssize_t write(int fd, const void *buf, size_t count)
1170 {
1171  UINT size;
1172  UINT bytes = count;
1173  FRESULT res;
1174  FIL *fh;
1175  FILE *stream;
1176  errno = 0;
1177 
1178  // TTY read function
1179  stream = fileno_to_stream(fd);
1180  if(stream == stdout || stream == stderr)
1181  {
1182  char *ptr = (char *) buf;
1183  size = 0;
1184  while(count--)
1185  {
1186  int c,ret;
1187  c = *ptr++;
1188  ret = fputc(c, stream);
1189  if(c != ret)
1190  break;
1191 
1192  ++size;
1193  }
1194  return(size);
1195  }
1196  if(stream == stdin)
1197  {
1198  return(-1);
1199  }
1200 
1201  // fileno_to_fatfs checks for fd out of bounds
1202  fh = fileno_to_fatfs(fd);
1203  if ( fh == NULL )
1204  {
1205  errno = EBADF;
1206  return(-1);
1207  }
1208 
1209  res = f_write(fh, buf, bytes, &size);
1210  if(res != FR_OK)
1211  {
1212  errno = fatfs_to_errno(res);
1213  return(-1);
1214  }
1215  return ((ssize_t) size);
1216 }
1217 
1218 FILE * __wrap_freopen ( const char * filename, const char * mode, FILE * stream )
1219 {
1220  int fn = fileno(stream);
1221  int ret = close(fn);
1222  if (ret < 0) {
1223  return NULL;
1224  }
1225  return fopen(filename, mode);
1226 }
1232 
1235 
1236 int __wrap_fclose(FILE *stream)
1237 {
1238  int fn = fileno(stream);
1239  if(fn < 0)
1240  return(EOF);
1241 
1242  return( close(fn) );
1243 }
1244 // =============================================
1245 // =============================================
1247 // =============================================
1248 // =============================================
1249 
1255 /*
1256 void dump_stat(struct stat *sp)
1257 {
1258  mode_t mode = sp->st_mode;
1259 
1260  printf("\tSize: %lu\n", (uint32_t)sp->st_size);
1261 
1262  printf("\tType: ");
1263  if(S_ISDIR(mode))
1264  printf("DIR\n");
1265  else if(S_ISREG(mode))
1266  printf("File\n");
1267  else
1268  printf("Unknown\n");
1269 
1270 
1271  printf("\tMode: %lo\n", (uint32_t)sp->st_mode);
1272  printf("\tUID: %lu\n", (uint32_t)sp->st_uid);
1273  printf("\tGID: %lu\n", (uint32_t)sp->st_gid);
1274  printf("\tatime: %s\n",mctime((time_t)sp->st_atime));
1275  printf("\tmtime: %s\n",mctime((time_t)sp->st_mtime));
1276  printf("\tctime: %s\n",mctime((time_t)sp->st_ctime));
1277 }
1278 */
1279 #if 0
1280 
1295 int fstat(int fd, struct stat *buf)
1296 {
1297  FIL *fh;
1298  FRESULT rc;
1299 
1300  if(isatty(fd))
1301  return(-1);
1302 
1303  //FIXME TODO
1304  return(-1);
1305 
1306 }
1307 #endif
1308 
1318 
1319 int stat(const char *name, struct stat *buf)
1320 {
1321  FILINFO info;
1322  int res;
1323  time_t epoch;
1324  uint16_t mode;
1325  errno = 0;
1326 
1327  // f_stat does not handle / or . as root directory
1328  if (strcmp(name,"/") == 0 || strcmp(name,".") == 0)
1329  {
1330  buf->st_atime = 0;
1331  buf->st_mtime = 0;
1332  buf->st_ctime = 0;
1333  buf->st_uid= 0;
1334  buf->st_gid= 0;
1335  buf->st_size = 0;
1336  buf->st_mode = S_IFDIR;
1337  return(0);
1338  }
1339 
1340  res = f_stat(name, &info);
1341  if(res != FR_OK)
1342  {
1343  errno = fatfs_to_errno(res);
1344  return(-1);
1345  }
1346 
1347  buf->st_size = info.fsize;
1348  epoch = fat_time_to_unix(info.fdate, info.ftime);
1349  buf->st_atime = epoch; // Access time
1350  buf->st_mtime = epoch; // Modification time
1351  buf->st_ctime = epoch; // Creation time
1352 
1353  // We only handle read only case
1354  mode = (FATFS_R | FATFS_X);
1355  if( !(info.fattrib & AM_RDO))
1356  mode |= (FATFS_W); // enable write if NOT read only
1357 
1358  if(info.fattrib & AM_SYS)
1359  {
1360  buf->st_uid= 0;
1361  buf->st_gid= 0;
1362  }
1363  {
1364  buf->st_uid=1000;
1365  buf->st_gid=1000;
1366  }
1367 
1368  if(info.fattrib & AM_DIR)
1369  mode |= S_IFDIR;
1370  else
1371  mode |= S_IFREG;
1372  buf->st_mode = mode;
1373 
1374  return(0);
1375 }
1376 
1381 
1382 int utime(const char *filename, const struct utimbuf *times)
1383 {
1384 
1385  FILINFO fno;
1386  uint16_t fdate,ftime;
1387  time_t ut = 0;
1388  int res;
1389 
1390  if(times)
1391  ut = times->modtime;
1392 
1393 
1394  unix_time_to_fat(ut, (uint16_t *) &fdate, (uint16_t *) &ftime);
1395 
1396 
1397  fno.fdate = fdate;
1398  fno.ftime = ftime;
1399 
1400  res = f_utime(filename, (FILINFO *) &fno);
1401 
1402  return( fatfs_to_errno(res) );
1403 }
1404 
1405 int64_t fs_getfree() {
1406  FATFS *fs;
1407  DWORD fre_clust, fre_sect;
1408 
1409 
1410  /* Get volume information and free clusters of drive 1 */
1411  FRESULT res = f_getfree("/", &fre_clust, &fs);
1412  if (res) return(res);
1413 
1414  /* Get total sectors and free sectors */
1415  fre_sect = fre_clust * fs->csize;
1416  return (int64_t)(fre_sect)*512;
1417 }
1418 
1419 
1420 int64_t fs_gettotal() {
1421  FATFS *fs;
1422  DWORD fre_clust, tot_sect;
1423 
1424 
1425  /* Get volume information and free clusters of drive 1 */
1426  FRESULT res = f_getfree("/", &fre_clust, &fs);
1427  if (res) return(res);
1428 
1429  /* Get total sectors and free sectors */
1430  tot_sect = (fs->n_fatent - 2) * fs->csize;
1431  return (int64_t)(tot_sect)*512;
1432 }
1433 // =============================================
1434 // =============================================
1436 // =============================================
1437 // =============================================
1445 
1446 char *basename(const char *str)
1447 {
1448  const char *base = str;
1449  if(!str)
1450  return("");
1451  while(*str)
1452  {
1453  if(*str++ == '/')
1454  base = str;
1455  }
1456 
1457  return (char*)base;
1458 }
1459 
1466 
1467 char *baseext(char *str)
1468 {
1469  char *ext = "";
1470 
1471  while(*str)
1472  {
1473  if(*str++ == '.')
1474  ext = str;
1475  }
1476  return(ext);
1477 }
1478 
1479 
1488 
1489 int chdir(const char *pathname)
1490 {
1491  errno = 0;
1492 
1493  int res = f_chdir(pathname);
1494  if(res != FR_OK)
1495  {
1496  errno = fatfs_to_errno(res);
1497  return(-1);
1498  }
1499  return(0);
1500 }
1501 
1513 
1514 int chmod(const char *pathname, mode_t mode)
1515 {
1516  int rc;
1517  errno = 0;
1518 
1519  // FIXME for now we combine user,group and other perms and ask if anyone has write perms ?
1520 
1521  // Read only ???
1522  if ( !( mode & ( S_IWUSR | S_IWGRP | S_IWOTH)))
1523  {
1524  // file is read only
1525  rc = f_chmod(pathname, AM_RDO, AM_RDO);
1526  if (rc != FR_OK)
1527  {
1528  errno = fatfs_to_errno(rc);
1529  return(-1);
1530  }
1531  }
1532 
1533  return(0);
1534 }
1535 
1551 
1552 int dirname(char *str)
1553 {
1554  int end = 0;
1555  int ind = 0;
1556 
1557  if(!str)
1558  return(0);
1559 
1560  while(*str)
1561  {
1562  if(*str == '/')
1563  end = ind;
1564  ++str;
1565  ++ind;
1566  }
1567  return(end);
1568 }
1569 
1570 #if 0
1571 
1581 int fchmod(int fd, mode_t mode)
1582 {
1583  //FIXME TODO
1584  return (-1);
1585 }
1586 #endif
1587 
1596 
1597 char *getcwd(char *pathname, int len)
1598 {
1599  int res;
1600  errno = 0;
1601 
1602  res = f_getcwd(pathname, len);
1603  if(res != FR_OK)
1604  {
1605  errno = fatfs_to_errno(res);
1606  return(NULL);
1607  }
1608  return(pathname);
1609 }
1610 
1619 
1620 int mkdir(const char *pathname, mode_t mode)
1621 {
1622  errno = 0;
1623 
1624  int res = f_mkdir(pathname);
1625  if(res != FR_OK)
1626  {
1627  errno = fatfs_to_errno(res);
1628  return(-1);
1629  }
1630 
1631  if (mode) {
1632  chmod(pathname, mode);
1633  }
1634 
1635  return(0);
1636 }
1637 
1647 
1648 int rename(const char *oldpath, const char *newpath)
1649 {
1650 /* Rename an object */
1651  int rc;
1652  errno = 0;
1653  rc = f_rename(oldpath, newpath);
1654  if(rc)
1655  {
1656  errno = fatfs_to_errno(rc);
1657  return(-1);
1658  }
1659  return(0);
1660 }
1661 
1670 
1671 int rmdir(const char *pathname)
1672 {
1673  errno = 0;
1674  int res = f_unlink(pathname);
1675  if(res != FR_OK)
1676  {
1677  errno = fatfs_to_errno(res);
1678  return(-1);
1679  }
1680  return(0);
1681 }
1682 
1683 
1692 
1693 int unlink(const char *pathname)
1694 {
1695  errno = 0;
1696  int res = f_unlink(pathname);
1697  if(res != FR_OK)
1698  {
1699  errno = fatfs_to_errno(res);
1700  return(-1);
1701  }
1702  return(0);
1703 }
1704 
1705 
1706 int remove(const char *pathname)
1707 {
1708  errno = 0;
1709  int res = f_unlink(pathname);
1710  if(res != FR_OK)
1711  {
1712  errno = fatfs_to_errno(res);
1713  return(-1);
1714  }
1715  return(0);
1716 }
1717 
1718 // =============================================
1719 // =============================================
1721 // =============================================
1722 // =============================================
1730 int closedir(DIR *dirp)
1731 {
1732  int res = f_closedir (dirp);
1733  if(res != FR_OK)
1734  {
1735  errno = fatfs_to_errno(res);
1736  return(-1);
1737  }
1738  return(0);
1739 }
1740 
1748 static DIR _dp;
1749 DIR *opendir(const char *pathdir)
1750 {
1751  int res = f_opendir((DIR *) &_dp, pathdir);
1752  if(res != FR_OK)
1753  {
1754  errno = fatfs_to_errno(res);
1755  return(NULL);
1756  }
1757  return ((DIR *) &_dp);
1758 }
1759 
1767 static dirent_t _de;
1768 dirent_t * readdir(DIR *dirp)
1769 {
1770  FILINFO fno;
1771  int len;
1772  int res;
1773 
1774  _de.d_name[0] = 0;
1775  res = f_readdir ( dirp, &fno );
1776  if(res != FR_OK || fno.fname[0] == 0)
1777  {
1778  errno = fatfs_to_errno(res);
1779  return(NULL);
1780  }
1781  len = strlen(fno.fname);
1782  strncpy(_de.d_name,fno.fname,len);
1783  _de.d_name[len] = 0;
1784  return( (dirent_t *) &_de);
1785 }
1786 
1787 // =============================================
1788 // =============================================
1790 // =============================================
1791 // =============================================
1792 
1798 
1799 void clrerror(FILE *stream)
1800 {
1801  stream->flags &= ~__SEOF;
1802  stream->flags &= ~__SERR;
1803 }
1804 
1810 
1811 int ferror(FILE *stream)
1812 {
1813  if(stream->flags & __SERR)
1814  return(1);
1815  return(0);
1816 }
1817 
1826 
1827 void perror(const char *s)
1828 {
1829  const char *ptr = NULL;
1830 
1831 
1832  if(errno >=0 && errno < EBADMSG)
1833  ptr = sys_errlist[errno];
1834  else
1835  ptr = sys_errlist[EBADMSG];
1836 
1837  if(s && *s)
1838  printf("%s: %s\n", s, ptr);
1839  else
1840  printf("%s\n", ptr);
1841 }
1842 
1851 
1852 char *strerror(int errnum)
1853 {
1854  return( (char *)sys_errlist[errnum] );
1855 }
1856 
1857 
1868 
1869 char *__wrap_strerror_r(int errnum, char *buf, size_t buflen)
1870 {
1871  strncpy(buf, sys_errlist[errnum], buflen);
1872  return(buf);
1873 }
1874 
1875 
1876 // =============================================
1877 // =============================================
1879 // =============================================
1880 // =============================================
1886 
1887 FILE *
1888 fdevopen(int (*put)(char, FILE *), int (*get)(FILE *))
1889 {
1890  FILE *s;
1891 
1892  if (put == 0 && get == 0)
1893  return 0;
1894 
1895  if ((s = calloc(1, sizeof(FILE))) == 0)
1896  return 0;
1897 
1898  s->flags = __SMALLOC;
1899 
1900  if (get != 0) {
1901  s->get = get;
1902  s->flags |= __SRD;
1903  // We assign the first device with a read discriptor to stdin
1904  // Only assign once
1905  if (stdin == 0)
1906  stdin = s;
1907  }
1908 
1909  if (put != 0) {
1910  s->put = put;
1911  s->flags |= __SWR;
1912  // NOTE: We assign the first device with a write to both STDOUT andd STDERR
1913 
1914  // Only assign in unassigned
1915  if (stdout == 0)
1916  stdout = s;
1917  if (stderr == 0)
1918  stderr = s;
1919  }
1920 
1921  return s;
1922 }
1923 
1924 
1925 // =============================================
1926 // =============================================
1928 // =============================================
1929 // =============================================
1930 
1934 /*
1935 int mkfs(char *name)
1936 {
1937  FATFS fs;
1938  uint8_t *mem;
1939  int res;
1940  int len;
1941  int c;
1942  char dev[4];
1943 
1944  len = MATCH(name,"/dev/sd");
1945  if(!len)
1946  {
1947  printf("Expected /dev/sda .. /dev/sdj\n");
1948  return(0);
1949  }
1950  // Convert /dev/sd[a-j] to 0: .. 9:
1951  dev[1] = ':';
1952  dev[2] = 0;
1953  c = tolower( name[len-1] );
1954  if(c >= 'a' && c <= ('a' + 9))
1955  dev[0] = (c - 'a');
1956  dev[3] = 0;
1957 
1958  // Register work area to the logical drive 0:
1959  res = f_mount(&fs, dev, 0);
1960  if(!res)
1961  {
1962  put_rc(res);
1963  return(0);
1964  }
1965 
1966  // Allocate memory for mkfs function
1967  mem = malloc(1024);
1968  if(!mem)
1969  return(0);
1970 
1971  // Create FAT volume on the logical drive 0
1972  // 2nd argument is ignored.
1973  res = f_mkfs(dev, FM_FAT32, 0, mem, 1024);
1974  if(res)
1975  {
1976  put_rc(res);
1977  free(mem);
1978  return(0);
1979  }
1980  free(mem);
1981  return(1);
1982 }
1983 */
1996 
1997 int fatfs_getc(FILE *stream)
1998 {
1999  FIL *fh;
2000  UINT size;
2001  int res;
2002  uint8_t c;
2003  long pos;
2004 
2005  errno = 0;
2006 
2007  if(stream == NULL)
2008  {
2009  errno = EBADF; // Bad File Number
2010  return(EOF);
2011  }
2012 
2013  fh = (FIL *) fdev_get_udata(stream);
2014  if(fh == NULL)
2015  {
2016  errno = EBADF; // Bad File Number
2017  return(EOF);
2018  }
2019 
2020  res = f_read(fh, &c, 1, (UINT *) &size);
2021  if( res != FR_OK || size != 1)
2022  {
2023  errno = fatfs_to_errno(res);
2024  stream->flags |= __SEOF;
2025  return(EOF);
2026  }
2027 
2028  // AUTOMATIC end of line METHOD detection
2029  // ALWAYS return '\n' for ALL methods
2030  // History: End of line (EOL) characters sometimes differ, mostly legacy systems, and modern UNIX (which uses just '\n')
2031  // '\r' ONLY
2032  // '\r\n'
2033  // '\n'
2034  // The difference was mostly from the way old mechanical printers were controlled.
2035  // '\n' (New Line = NL) advanced the line
2036  // '\r' (Charage Return = CR) moved the print head to start of line
2037  // '\t' (Tabstop = TAB)
2038  // '\f' (Form feed = FF)
2039  // The problem with mechanical devices is that each had differing control and time delays to deal with.
2040  // (TAB, CR, NL and FF) did different things and took differing times depending on the device.
2041  //
2042  // Long before DOS UNIX took the position that controlling physical devices must be a device drivers problem only.
2043  // They reasoned if users had to worry about all the ugly controll and timing issues no code would be portable.
2044  // Therefore they made NL just a SYMBOL for the driver to determine what to do.
2045  // This design philosophy argued if you needed better control its better to use a real designed purposed tool for it.
2046  // (ie. like curses or termcap).
2047 
2048  // Here to deal with those other old ugly stupid pointless EOL methods we convert to just a symbol '\n'
2049  // FROM '\n' OR '\r'char OR '\r\n' TO '\n'
2050  // Note: char != '\n'
2051  if(c == '\r')
2052  {
2053  // PEEK forward 1 character
2054  pos = f_tell(fh);
2055  // Check for trailing '\n' or EOF
2056  res = f_read(fh, &c, 1, (UINT *) &size);
2057  if(res != FR_OK || size != 1)
2058  {
2059  // '\r' with EOF impiles '\n'
2060  return('\n');
2061  }
2062  // This file must be '\r' ONLY for end of line
2063  if(c != '\n')
2064  {
2065  // Not '\n' or EOF o move file pointer back to just after the '\r'
2066  f_lseek(fh, pos);
2067  return('\n');
2068  }
2069  c = '\n';
2070  }
2071  return(c & 0xff);
2072 }
2073 
2086 
2087 int fatfs_putc(char c, FILE *stream)
2088 {
2089  int res;
2090  FIL *fh;
2091  UINT size;
2092 
2093  errno = 0;
2094  if(stream == NULL)
2095  {
2096  errno = EBADF; // Bad File Number
2097  return(EOF);
2098  }
2099 
2100  fh = (FIL *) fdev_get_udata(stream);
2101  if(fh == NULL)
2102  {
2103  errno = EBADF; // Bad File Number
2104  return(EOF);
2105  }
2106 
2107  res = f_write(fh, &c, 1, (UINT *) &size);
2108  if( res != FR_OK || size != 1)
2109  {
2110  errno = fatfs_to_errno(res);
2111  stream->flags |= __SEOF;
2112  return(EOF);
2113  }
2114  return(c);
2115 }
2116 
2126 
2128 {
2129  switch( Result )
2130  {
2131  case FR_OK: /* FatFS (0) Succeeded */
2132  return (0); /* POSIX OK */
2133  case FR_DISK_ERR: /* FatFS (1) A hard error occurred in the low level disk I/O layer */
2134  return (EIO); /* POSIX Input/output error (POSIX.1) */
2135 
2136  case FR_INT_ERR: /* FatFS (2) Assertion failed */
2137  return (EPERM); /* POSIX Operation not permitted (POSIX.1) */
2138 
2139  case FR_NOT_READY: /* FatFS (3) The physical drive cannot work */
2140  return (EBUSY); /* POSIX Device or resource busy (POSIX.1) */
2141 
2142  case FR_NO_FILE: /* FatFS (4) Could not find the file */
2143  return (ENOENT); /* POSIX No such file or directory (POSIX.1) */
2144 
2145  case FR_NO_PATH: /* FatFS (5) Could not find the path */
2146  return (ENOENT); /* POSIX No such file or directory (POSIX.1) */
2147 
2148  case FR_INVALID_NAME: /* FatFS (6) The path name format is invalid */
2149  return (EINVAL); /* POSIX Invalid argument (POSIX.1) */
2150 
2151  case FR_DENIED: /* FatFS (7) Access denied due to prohibited access or directory full */
2152  return (EACCES); /* POSIX Permission denied (POSIX.1) */
2153 
2154  case FR_EXIST: /* file exists */
2155  return (EEXIST); /* file exists */
2156 
2157  case FR_INVALID_OBJECT: /* FatFS (9) The file/directory object is invalid */
2158  return (EINVAL); /* POSIX Invalid argument (POSIX.1) */
2159 
2160  case FR_WRITE_PROTECTED: /* FatFS (10) The physical drive is write protected */
2161  return(EROFS); /* POSIX Read-only filesystem (POSIX.1) */
2162 
2163  case FR_INVALID_DRIVE: /* FatFS (11) The logical drive number is invalid */
2164  return(ENXIO); /* POSIX No such device or address (POSIX.1) */
2165 
2166  case FR_NOT_ENABLED: /* FatFS (12) The volume has no work area */
2167  return (ENOSPC); /* POSIX No space left on device (POSIX.1) */
2168 
2169  case FR_NO_FILESYSTEM: /* FatFS (13) There is no valid FAT volume */
2170  return(ENXIO); /* POSIX No such device or address (POSIX.1) */
2171 
2172  case FR_MKFS_ABORTED: /* FatFS (14) The f_mkfs() aborted due to any parameter error */
2173  return (EINVAL); /* POSIX Invalid argument (POSIX.1) */
2174 
2175  case FR_TIMEOUT: /* FatFS (15) Could not get a grant to access the volume within defined period */
2176  return (EBUSY); /* POSIX Device or resource busy (POSIX.1) */
2177 
2178  case FR_LOCKED: /* FatFS (16) The operation is rejected according to the file sharing policy */
2179  return (EBUSY); /* POSIX Device or resource busy (POSIX.1) */
2180 
2181 
2182  case FR_NOT_ENOUGH_CORE: /* FatFS (17) LFN working buffer could not be allocated */
2183  return (ENOMEM); /* POSIX Not enough space (POSIX.1) */
2184 
2185  case FR_TOO_MANY_OPEN_FILES:/* FatFS (18) Number of open files > _FS_SHARE */
2186  return (EMFILE); /* POSIX Too many open files (POSIX.1) */
2187 
2188  case FR_INVALID_PARAMETER:/* FatFS (19) Given parameter is invalid */
2189  return (EINVAL); /* POSIX Invalid argument (POSIX.1) */
2190 
2191  }
2192  return (EBADMSG); /* POSIX Bad message (POSIX.1) */
2193 }
2194 
2195 
2203 
2205 {
2206  int i;
2207 
2208  FILE *stream;
2209 
2210  if(fh == NULL)
2211  {
2212  errno = EBADF;
2213  return(-1);
2214  }
2215 
2216  for(i=0;i<MAX_FILES;++i)
2217  {
2218  stream = __iob[i];
2219  if(stream)
2220  {
2221  if( fh == (FIL *) fdev_get_udata(stream) )
2222  return(i);
2223  }
2224  }
2225  errno = EBADF;
2226  return(-1);
2227 }
2228 
2229 /*
2230  mktime replacement from Samba
2231  */
2232 static time_t replace_mktime(const struct tm *t)
2233 {
2234  time_t epoch = 0;
2235  int n;
2236  int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, y, m, i;
2237  const unsigned MINUTE = 60;
2238  const unsigned HOUR = 60*MINUTE;
2239  const unsigned DAY = 24*HOUR;
2240  const unsigned YEAR = 365*DAY;
2241 
2242  if (t->tm_year < 70) {
2243  return((time_t)-1);
2244  }
2245 
2246  n = t->tm_year + 1900 - 1;
2247  epoch = (t->tm_year - 70) * YEAR +
2248  ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
2249 
2250  y = t->tm_year + 1900;
2251  m = 0;
2252 
2253  for(i = 0; i < t->tm_mon; i++) {
2254  epoch += mon [m] * DAY;
2255  if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
2256  epoch += DAY;
2257 
2258  if(++m > 11) {
2259  m = 0;
2260  y++;
2261  }
2262  }
2263 
2264  epoch += (t->tm_mday - 1) * DAY;
2265  epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
2266 
2267  return epoch;
2268 }
2269 
2281 
2282 time_t fat_time_to_unix(uint16_t date, uint16_t time)
2283 {
2284  struct tm tp;
2285  time_t unix;
2286 
2287  memset(&tp, 0, sizeof(struct tm));
2288 
2289  tp.tm_sec = (time << 1) & 0x3e; // 2 second resolution
2290  tp.tm_min = ((time >> 5) & 0x3f);
2291  tp.tm_hour = ((time >> 11) & 0x1f);
2292  tp.tm_mday = (date & 0x1f);
2293  tp.tm_mon = ((date >> 5) & 0x0f) - 1;
2294  tp.tm_year = ((date >> 9) & 0x7f) + 80;
2295  unix = replace_mktime( &tp );
2296  return( unix );
2297 }
2298 
2306 
2307 void unix_time_to_fat(time_t epoch, uint16_t *date, uint16_t *time)
2308 {
2309  struct tm *t = gmtime((time_t *) &epoch);
2310 
2311 /* Pack date and time into a uint32_t variable */
2312  *date = ((uint16_t)(t->tm_year - 80) << 9)
2313  | (((uint16_t)t->tm_mon+1) << 5)
2314  | (((uint16_t)t->tm_mday));
2315 
2316  *time = ((uint16_t)t->tm_hour << 11)
2317  | ((uint16_t)t->tm_min << 5)
2318  | ((uint16_t)t->tm_sec >> 1);
2319 }
2320 
2330 
2332 {
2333  FILE *stream;
2334  FIL *fh;
2335 
2336  if(isatty( fileno ))
2337  {
2338  errno = EBADF;
2339  return(NULL);
2340  }
2341 
2342  // checks if fileno out of bounds
2343  stream = fileno_to_stream(fileno);
2344  if( stream == NULL )
2345  return(NULL);
2346 
2347  fh = fdev_get_udata(stream);
2348  if(fh == NULL)
2349  {
2350  errno = EBADF;
2351  return(NULL);
2352  }
2353  return(fh);
2354 }
2355 
2356 
2357 
2365 
2367 {
2368  FILE *stream;
2369  FIL *fh;
2370 
2371  if(isatty( fileno ))
2372  {
2373  errno = EBADF;
2374  return(-1);
2375  }
2376 
2377  // checks if fileno out of bounds
2378  stream = fileno_to_stream(fileno);
2379  if(stream == NULL)
2380  {
2381  return(-1);
2382  }
2383 
2384  fh = fdev_get_udata(stream);
2385 
2386  if(fh != NULL)
2387  {
2388  free(fh);
2389  }
2390 
2391  if(stream->buf != NULL && stream->flags & __SMALLOC)
2392  {
2393  free(stream->buf);
2394  }
2395 
2396  __iob[fileno] = NULL;
2397  free(stream);
2398  return(fileno);
2399 }
2400 
2401 
2402 
2403 // =============================================
2409 
2411 {
2412  int i;
2413  FILE *stream;
2414  FIL *fh;
2415 
2416  for(i=0;i<MAX_FILES;++i)
2417  {
2418  if(isatty(i))
2419  continue;
2420  if( __iob[i] == NULL)
2421  {
2422  stream = (FILE *) calloc(sizeof(FILE),1);
2423  if(stream == NULL)
2424  {
2425  errno = ENOMEM;
2426  return(-1);
2427  }
2428  fh = (FIL *) calloc(sizeof(FIL),1);
2429  if(fh == NULL)
2430  {
2431  free(stream);
2432  errno = ENOMEM;
2433  return(-1);
2434  }
2435 
2436  __iob[i] = stream;
2437  fdev_set_udata(stream, (void *) fh);
2438  return(i);
2439  }
2440  }
2441  errno = ENFILE;
2442  return(-1);
2443 }
2444 
2472 
2473 int posix_fopen_modes_to_open(const char *mode)
2474 {
2475  int flag = 0;
2476 
2477  if(modecmp(mode,"r") || modecmp(mode,"rb"))
2478  {
2479  flag = O_RDONLY;
2480  return(flag);
2481  }
2482  if(modecmp(mode,"r+") || modecmp(mode, "r+b" ) || modecmp(mode, "rb+" ))
2483  {
2484  flag = O_RDWR | O_TRUNC;
2485  return(flag);
2486  }
2487  if(modecmp(mode,"w") || modecmp(mode,"wb"))
2488  {
2489  flag = O_WRONLY | O_CREAT | O_TRUNC;
2490  return(flag);
2491  }
2492  if(modecmp(mode,"w+") || modecmp(mode, "w+b" ) || modecmp(mode, "wb+" ))
2493  {
2494  flag = O_RDWR | O_CREAT | O_TRUNC;
2495  return(flag);
2496  }
2497  if(modecmp(mode,"a") || modecmp(mode,"ab"))
2498  {
2499  flag = O_WRONLY | O_CREAT | O_APPEND;
2500  return(flag);
2501  }
2502  if(modecmp(mode,"a+") || modecmp(mode, "a+b" ) || modecmp(mode, "ab+" ))
2503  {
2504  flag = O_RDWR | O_CREAT | O_APPEND;
2505  return(-1);
2506  }
2507  return(-1); // nvalid mode
2508 }
2509 
2510 // =============================================
2511 // =============================================
2513 // =============================================
2514 // =============================================
2515 
2516 
2517 
2522 /*
2523 static void _fprintf_putc(struct _printf_t *p, char ch)
2524 {
2525  p->sent++;
2526  fputc(ch, (FILE *) p->buffer);
2527 }
2528 
2529 */
2537 
2538 int
2539 fprintf(FILE *fp, const char *fmt, ...)
2540 {
2541  va_list va;
2542  char* buf;
2543  int16_t len, i;
2544  va_start(va, fmt);
2545  len = vasprintf(&buf, fmt, va);
2546  if (len > 0) {
2547  for(i = 0; i < len; i++) {
2548  fputc(buf[i], fp);
2549  }
2550  } else {
2551  return -1;
2552  }
2553  va_end(va);
2554 
2555  return len;
2556 }
2557 
2558 /*
2559  fsync file
2560  */
2561 int
2563 {
2564  FILE *stream;
2565  FIL *fh;
2566  int res;
2567 
2568  errno = 0;
2569 
2570  // checks if fileno out of bounds
2571  stream = fileno_to_stream(fileno);
2572  if(stream == NULL)
2573  {
2574  return(-1);
2575  }
2576 
2577  // fileno_to_fatfs checks for fileno out of bounds
2578  fh = fileno_to_fatfs(fileno);
2579  if(fh == NULL)
2580  {
2581  return(-1);
2582  }
2583  res = f_sync(fh);
2584  if (res != FR_OK)
2585  {
2586  errno = fatfs_to_errno(res);
2587  return(-1);
2588  }
2589  return(0);
2590 }
TCHAR fname[12+1]
Definition: ff.h:235
int printf(const char *fmt,...)
Definition: stdio.c:113
int syncfs(int fd)
POSIX Sync pending file changes and metadata for specified fileno.
Definition: posix.c:1085
int fileno(FILE *stream)
Convert POSIX stream pointer to POSIX fileno (index of __iob[])
Definition: posix.c:714
char * baseext(char *str)
File extention of a file name. NOT POSIX.
Definition: posix.c:1467
DWORD n_fatent
Definition: ff.h:137
int rename(const char *oldpath, const char *newpath)
POSIX rename a file by name.
Definition: posix.c:1648
FRESULT f_closedir(DIR *dp)
Definition: ff.c:4467
int vasprintf(char **strp, const char *fmt, va_list ap)
Definition: stdio.c:76
FRESULT f_lseek(FIL *fp, FSIZE_t ofs)
Definition: ff.c:4240
int64_t fs_gettotal()
Definition: posix.c:1420
void rewind(FILE *stream)
POSIX rewind file to the beginning.
Definition: posix.c:656
dirent_t * readdir(DIR *dirp)
Definition: posix.c:1768
int ferror(FILE *stream)
ferror reports if the stream has an error flag set
Definition: posix.c:1811
WORD fdate
Definition: ff.h:228
int open(const char *pathname, int flags)
POSIX Open a file with integer mode flags.
Definition: posix.c:885
int fgetpos(FILE *stream, size_t *pos)
POSIX get position of file stream.
Definition: posix.c:517
static time_t replace_mktime(const struct tm *t)
Definition: posix.c:2232
int fatfs_putc(char c, FILE *stream)
Private FatFs function called by fputc() to put a byte from file stream NOT POSIX open() assigns stre...
Definition: posix.c:2087
Definition: ff.h:226
char * __wrap_strerror_r(int errnum, char *buf, size_t buflen)
POSIX strerror_r() - convert POSIX errno to text with user message.
Definition: posix.c:1869
FRESULT f_unlink(const TCHAR *path)
Definition: ff.c:4759
FRESULT f_close(FIL *fp)
Definition: ff.c:4026
int fatfs_to_errno(FRESULT Result)
Convert FafFs error result to POSIX errno. NOT POSIX.
Definition: posix.c:2127
char * strerror(int errnum)
POSIX strerror() - convert POSIX errno to text with user message.
Definition: posix.c:1852
int utime(const char *filename, const struct utimbuf *times)
Set Modification and Access time of a file.
Definition: posix.c:1382
int dirname(char *str)
POSIX directory name of a filename. Return the index of the last &#39;/&#39; character.
Definition: posix.c:1552
ssize_t write(int fd, const void *buf, size_t count)
POSIX Write count bytes from *buf to fileno fd.
Definition: posix.c:1169
Definition: ff.h:99
int posix_fopen_modes_to_open(const char *mode)
Convert POSIX fopen mode to POSIX open mode flags. NOT POSIX.
Definition: posix.c:2473
WORD ftime
Definition: ff.h:229
#define FA_OPEN_ALWAYS
Definition: ff.h:364
Definition: ff.h:251
#define f_tell(fp)
Definition: ff.h:310
int rmdir(const char *pathname)
POSIX delete a directory.
Definition: posix.c:1671
FRESULT f_chdir(const TCHAR *path)
FRESULT f_chmod(const TCHAR *path, BYTE attr, BYTE mask)
#define FA_WRITE
Definition: ff.h:360
static RC_Channel * rc
Definition: RC_Channel.cpp:17
int new_file_descriptor(void)
Allocate a POSIX FILE descriptor. NOT POSIX.
Definition: posix.c:2410
char * getcwd(char *pathname, int len)
POSIX get current working directory.
Definition: posix.c:1597
const char * name
Definition: BusTest.cpp:11
#define FA_READ
Definition: ff.h:359
int fatfs_getc(FILE *stream)
Formt SD card.
Definition: posix.c:1997
void * calloc(size_t nmemb, size_t size)
Definition: malloc.c:76
int putchar(int c)
put a character to stdout See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:329
int64_t fs_getfree()
Definition: posix.c:1405
time_t fat_time_to_unix(uint16_t date, uint16_t time)
Convert FatFs file date and time to POSIX epoch seconds. NOT POSIX.
Definition: posix.c:2282
#define FA_CREATE_ALWAYS
Definition: ff.h:363
FRESULT f_truncate(FIL *fp)
Definition: ff.c:4709
Definition: ff.h:246
FILE * fdevopen(int(*put)(char, FILE *), int(*get)(FILE *))
Device open functions.
Definition: posix.c:1888
Definition: ff.h:201
unsigned long DWORD
Definition: integer.h:22
int fatfs_to_fileno(FIL *fh)
Convert FatFS file handle to POSIX fileno. NOT POSIX.
Definition: posix.c:2204
Definition: ff.h:252
int fsetpos(FILE *stream, size_t *pos)
POSIX set position of file stream.
Definition: posix.c:566
void perror(const char *s)
POSIX perror() - convert POSIX errno to text with user message.
Definition: posix.c:1827
#define AM_SYS
Definition: ff.h:386
long ftell(FILE *stream)
POSIX file position of open stream.
Definition: posix.c:580
int free_file_descriptor(int fileno)
Free POSIX fileno FILE descriptor. NOT POSIX.
Definition: posix.c:2366
Definition: ff.h:248
unsigned char BYTE
Definition: integer.h:13
int feof(FILE *stream)
feof reports if the stream is at EOF
Definition: posix.c:500
ssize_t read(int fd, void *buf, size_t count)
POSIX read count bytes from *buf to fileno fd.
Definition: posix.c:995
FRESULT f_readdir(DIR *dp, FILINFO *fno)
Definition: ff.c:4497
FRESULT f_read(FIL *fp, void *buff, UINT btr, UINT *br)
Definition: ff.c:3721
int isatty(int fileno)
Test POSIX fileno if it is a Serial Console/TTY.
Definition: posix.c:185
FRESULT f_getfree(const TCHAR *path, DWORD *nclst, FATFS **fatfs)
Definition: ff.c:4620
void unix_time_to_fat(time_t epoch, uint16_t *date, uint16_t *time)
Convert Linux POSIX time_t to FAT32 date and time. NOT POSIX.
Definition: posix.c:2307
Definition: ff.h:249
int puts(const char *str)
put a string to stdout See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:475
int putc(int c, FILE *stream)
Un-Get byte from a TTY device or FatFs file stream.
Definition: posix.c:379
const char * fmt
Definition: Printf.cpp:14
int __wrap_fclose(FILE *stream)
POSIX close a file stream.
Definition: posix.c:1236
#define FA_OPEN_EXISTING
Definition: ff.h:361
int getchar()
functions normally defined as macros
Definition: posix.c:314
Definition: diskio.h:21
FRESULT f_sync(FIL *fp)
Definition: ff.c:3945
int close(int fileno)
POSIX Close a file with fileno handel.
Definition: posix.c:675
FRESULT
Definition: ff.h:243
FRESULT f_stat(const TCHAR *path, FILINFO *fno)
Definition: ff.c:4585
void sync(void)
POSIX Sync all pending file changes and metadata on ALL files.
Definition: posix.c:1058
int unlink(const char *pathname)
POSIX delete a file.
Definition: posix.c:1693
int fputs(const char *str, FILE *stream)
put a string to stdout See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:452
FSIZE_t fsize
Definition: ff.h:227
off_t lseek(int fileno, off_t position, int whence)
POSIX seek to file position.
Definition: posix.c:612
int mkdir(const char *pathname, mode_t mode)
POSIX make a directory.
Definition: posix.c:1620
char * gets(char *p)
Definition: posix.c:429
Definition: ff.h:259
int fseek(FILE *stream, long offset, int whence)
POSIX seek to file possition.
Definition: posix.c:540
#define NULL
Definition: hal_types.h:59
int ftruncate(int fd, off_t length)
POSIX truncate open file to length.
Definition: posix.c:817
static uint8_t buflen
Definition: srxl.cpp:57
static dirent_t _de
POSIX opendir.
Definition: posix.c:1767
void free(void *ptr)
Definition: malloc.c:81
FRESULT f_opendir(DIR *dp, const TCHAR *path)
Definition: ff.c:4401
FSIZE_t fptr
Definition: ff.h:185
FIL * fileno_to_fatfs(int fileno)
Convert POSIX fileno to FatFS handle NOT POSIX.
Definition: posix.c:2331
BYTE fattrib
Definition: ff.h:230
FILE * fileno_to_stream(int fileno)
Convert POSIX fileno to POSIX FILE stream pointer. NOT POSIX.
Definition: posix.c:744
unsigned int UINT
Definition: integer.h:10
#define EOF
Definition: ff.h:318
int stat(const char *name, struct stat *buf)
Display struct stat, from POSIX stat(0 or fstat(), in ASCII. NOT POSIX.
Definition: posix.c:1319
#define AM_RDO
Definition: ff.h:384
#define f_size(fp)
Definition: ff.h:311
FILE * fopen(const char *path, const char *mode)
POSIX Open a file with path name and ascii file mode string.
Definition: posix.c:772
int chdir(const char *pathname)
POSIX change directory.
Definition: posix.c:1489
int closedir(DIR *dirp)
POSIX closedir.
Definition: posix.c:1730
Definition: ff.h:260
int fgetc(FILE *stream)
Get byte from a TTY device or FatFs file stream open() or fopen() sets stream->get = fatfs_getc() for...
Definition: posix.c:205
int chmod(const char *pathname, mode_t mode)
POSIX chmod function - change file access permission Unfortunately file f_open modes and f_chmod mode...
Definition: posix.c:1514
FRESULT f_utime(const TCHAR *path, const FILINFO *fno)
Definition: ff.h:173
FRESULT f_mkdir(const TCHAR *path)
Definition: ff.c:4853
int errno
Note: fdevopen assigns stdin,stdout,stderr.
Definition: posix.c:118
int fprintf(FILE *fp, const char *fmt,...)
fprintf character write function
Definition: posix.c:2539
int fsync(int fileno)
Definition: posix.c:2562
int getc(FILE *fp)
Definition: posix.c:250
int truncate(const char *path, off_t length)
POSIX truncate named file to length.
Definition: posix.c:1131
void uint32_t uint32_t uint32_t flag
Definition: systick.h:80
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
POSIX write nmemb elements from buf, size bytes each, to the stream fd.
Definition: posix.c:858
const char * sys_errlist[]
POSIX error messages for each errno value.
Definition: posix.c:133
int fputc(int c, FILE *stream)
Put a byte to TTY device or FatFs file stream open() or fopen() sets stream->put = fatfs_outc() for F...
Definition: posix.c:264
FILE * __iob[MAX_FILES]
POSIX fileno to POSIX FILE stream table.
Definition: posix.c:128
Definition: ff.h:244
DIR * opendir(const char *pathdir)
Definition: posix.c:1749
FILE * __wrap_freopen(const char *filename, const char *mode, FILE *stream)
Definition: posix.c:1218
#define AM_DIR
Definition: ff.h:387
FRESULT f_rename(const TCHAR *path_old, const TCHAR *path_new)
Definition: ff.c:4941
char * fgets(char *str, int size, FILE *stream)
get a string from stdin See fdevopen() sets stream->put get for TTY devices
Definition: posix.c:398
static DIR _dp
POSIX opendir.
Definition: posix.c:1748
FRESULT f_write(FIL *fp, const void *buff, UINT btw, UINT *bw)
Definition: ff.c:3821
FRESULT f_getcwd(TCHAR *buff, UINT len)
char * basename(const char *str)
POSIX Basename of filename.
Definition: posix.c:1446
void clearerr(FILE *stream)
Definition: posix.c:296
size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
POSIX read nmemb elements from buf, size bytes each, to the stream fd.
Definition: posix.c:793
void clrerror(FILE *stream)
clrerror resets stream EOF and error flags
Definition: posix.c:1799
FRESULT f_open(FIL *fp, const TCHAR *path, BYTE mode)
Definition: ff.c:3530
WORD csize
Definition: ff.h:112