Subversion Repositories Kolibri OS

Rev

Rev 6727 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2. Kolibri OS port for gcc 5.4
  3.  
  4. Started by Siemargl @Nov 2016
  5.  
  6. Contains realization of directory handling functions:
  7.     mkdir()
  8.     closedir()
  9.     opendir()
  10.     readdir()
  11.     rewinddir()
  12.  
  13.     !!non reentrant
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <dirent.h>
  19. #include <errno.h>
  20. #include <sys/stat.h>
  21. #include <assert.h>
  22. #include "kos32sys1.h"
  23. #include "sys/kos_io.h"
  24.  
  25. /* defined in newlib headers
  26. int     _EXFUN(mkdir,( const char *_path, mode_t __mode ));
  27.  
  28. struct dirent {
  29.   char d_namlen;
  30.   char d_name[256];
  31. };
  32.  
  33. typedef struct
  34. {
  35. //    struct systree_info2 fileinfo;
  36.     struct dirent entry;
  37. //    __u8 bdfeheader[0x20];
  38. //    struct bdfe_item bdfebase;
  39. //    __u8 bdfename[264];
  40. } DIR;
  41.  
  42. int     closedir(DIR *dirp);
  43. DIR *       opendir(const char *_dirname);
  44. struct dirent * readdir(DIR *_dirp);
  45. void      rewinddir(DIR *_dirp);
  46. */
  47.  
  48. static int32_t lastread_block = -1; // non reentrant, must me -1ed in closedir, or will assert
  49. static uint32_t lastread_dir_size;
  50. static DIR  lastread_dir;
  51.  
  52. DIR *opendir(const char *_dirname)
  53. {
  54.     assert(sizeof(struct fs_dirinfo) == 25);  // check struct aligment
  55.     assert(lastread_block == -1);
  56.  
  57.     struct fs_dirinfo di;
  58.     struct fs_dirheader dhead;
  59.  
  60.     memset(&di, 0, sizeof di);
  61.     di.ppath = (char*)_dirname;
  62.     di.retval = (uint32_t)&dhead;
  63.     int rc = sf_file(1, &di);  // read dir size
  64.     if(rc) {
  65.         fprintf(stderr, "Error reading dir size %s\n", _dirname);
  66.         errno = rc;
  67.         return NULL;
  68.     }
  69.     lastread_dir_size = dhead.totl_blocks;
  70.  
  71.     lastread_dir.entry.d_namlen = strlen(_dirname);
  72.     assert (lastread_dir.entry.d_namlen < sizeof(lastread_dir.entry.d_name));
  73.     strcpy(lastread_dir.entry.d_name, _dirname);
  74.  
  75.     return &lastread_dir;
  76. };
  77.  
  78.  
  79. int closedir(DIR *dirp)
  80. {
  81.     assert (lastread_block != -1);  // was opened
  82.  
  83.     if (!dirp || lastread_block == -1)
  84.     {
  85.         errno = EBADF;
  86.         return -1;
  87.     }
  88.     lastread_block = -1;
  89.     lastread_dir_size = 0;
  90.     lastread_dir.entry.d_namlen = 0;
  91.     lastread_dir.entry.d_name[0] = '\0';
  92.  
  93.     return 0;
  94. };
  95.  
  96.  
  97. struct dirent* readdir(DIR *dirp)
  98. {
  99.     assert (lastread_block != -1);  // was opened
  100.  
  101.     if (!dirp || lastread_block == -1)
  102.     {
  103.         errno = EBADF;
  104.         return NULL;
  105.     }
  106.     struct fs_dirinfo di;
  107.  
  108.     assert (lastread_block != -1);  // was opened
  109.  
  110.     char retdir[sizeof(struct fs_dirheader) + sizeof(struct fsBDFE)];   // 1 block w/cp866 encoding
  111.     struct fsBDFE *bdfe = (struct fsBDFE *)(retdir + sizeof(struct fs_dirheader));
  112.     memset(&di, 0, sizeof di);
  113.     di.ppath = dirp->entry.d_name;
  114.     di.retval = (uint32_t)retdir;
  115.     di.start = lastread_block;
  116.     di.size = 1;
  117.  
  118.     int rc = sf_file(1, &di);  // read dir
  119.     if(rc) {
  120.         fprintf(stderr, "Error %d reading dir item %s\n", rc, dirp->entry.d_name);
  121.         errno = rc;
  122.         return NULL;
  123.     }
  124.  
  125.     static struct dirent ent;
  126.     ent.d_namlen = strlen(bdfe->fname);
  127.     assert (ent.d_namlen < sizeof(ent.d_name));
  128.     strcpy(ent.d_name, bdfe->fname);
  129.     lastread_block++;
  130.  
  131.     return &ent;
  132. };
  133.  
  134.  
  135. void rewinddir(DIR *dirp)
  136. {
  137.     if (!dirp || lastread_block == -1)
  138.     {
  139.         return;
  140.     }
  141.  
  142.     lastread_block = 0;
  143. }
  144.  
  145.  
  146. int     mkdir(const char *_path, mode_t m)
  147. {
  148.     char   namebuffer[1050]; // need for save data after di!!!
  149.     struct fs_dirinfo *di = (struct fs_dirinfo *)namebuffer;
  150.  
  151. //debug_board_printf("mkdir start (%s)\n", _path);
  152.     memset(di, 0, sizeof(struct fs_dirinfo));
  153.     //di.ppath = (char*)_path;  // dont work with 70.9
  154.     strcpy(di->path, _path);
  155.  
  156.     int rc = sf_file(9, di);  // creat dir
  157.     if(rc) {
  158.         fprintf(stderr, "Error %d creating dir item %s\n", rc, _path);
  159.         errno = rc;
  160.         return -1;
  161.     }
  162.  
  163. //debug_board_printf("mkdir end (%s)\n", _path);
  164.     return 0;
  165. }
  166.  
  167. ////////////////////////////////////////////////////////////////////////////////////////
  168. void __attribute__ ((noinline)) debug_board_write_str(const char* str){
  169.   while(*str)
  170.     debug_board_write_byte(*str++);
  171. }
  172.  
  173. void __attribute__ ((noinline)) debug_board_printf(const char *format,...)
  174. {
  175.         va_list ap;
  176.         char log_board[300];
  177.  
  178.         va_start (ap, format);
  179.         vsnprintf(log_board, sizeof log_board, format, ap);
  180.         va_end(ap);
  181.         debug_board_write_str(log_board);
  182. }
  183.  
  184. __attribute__ ((noinline)) void trap(int n)
  185. {
  186.     // nothing todo, just see n in debugger. use "bp trap" command
  187.     __asm__ __volatile__(
  188.     "nop"
  189.     :
  190.     :"a"(n));
  191. }
  192.  
  193.  
  194.  
  195. /* tested example
  196. void* read_folderdata(char* name)
  197. {
  198.     struct fs_dirinfo di;
  199.     struct fs_dirheader dhead;
  200.     assert(sizeof di == 25);
  201.  
  202.     memset(&di, 0, sizeof di);
  203.     di.ppath = name;
  204.     di.retval = (uint32_t)&dhead;
  205.     int rc = sf_file(1, &di);  // read dir size
  206.     if(rc) {
  207.         debug_board_printf("Error reading dir size %s", name);
  208.         exit(1);
  209.     }
  210.     di.size = dhead.totl_blocks;
  211.  
  212.     char *retdir = malloc(sizeof dhead + dhead.totl_blocks * sizeof(struct fsBDFE));
  213.     if(!retdir) {
  214.         debug_board_printf("No memory for dir %s", name);
  215.         exit(1);
  216.     }
  217.     di.retval = (uint32_t)retdir;
  218.     rc = sf_file(1, &di);  // read dir
  219.     if(rc) {
  220.         debug_board_printf("Error 2 reading dir size %s", name);
  221.         exit(1);
  222.     }
  223.  
  224.     // manual clear mark flag (random junk in fname free space)
  225.     int i;
  226.     for (i = 0; i < dhead.totl_blocks; i++)
  227.         ((struct fsBDFE*)(retdir+32))[i].fname[259] = 0;
  228.  
  229.     debug_board_printf("Loaded dir [%s] etnries %d,\n first file [%s]\n", name, ((struct fs_dirheader*)(retdir))->curn_blocks, ((struct fsBDFE*)(retdir+32))->fname);
  230.  
  231.     return retdir;
  232. }
  233. */
  234.  
  235. // while not in newlib
  236. int set_fileinfo(const char *path, fileinfo_t *info)
  237. {
  238.     int retval;
  239.  
  240.     __asm__ __volatile__ (
  241.     "pushl $0 \n\t"
  242.     "pushl $0 \n\t"
  243.     "movl %1, 1(%%esp) \n\t"
  244.     "pushl %%ebx \n\t"
  245.     "pushl $0 \n\t"
  246.     "pushl $0 \n\t"
  247.     "pushl $0 \n\t"
  248.     "pushl $6 \n\t"
  249.     "movl %%esp, %%ebx \n\t"
  250.     "movl $70, %%eax \n\t"
  251.     "int $0x40 \n\t"
  252.     "addl $28, %%esp \n\t"
  253.     :"=a" (retval)
  254.     :"r" (path), "b" (info));
  255.    return retval;
  256. };
  257.  
  258.