Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include "dosemuin.h"
  2. #include <errno.h>
  3.  
  4. static char _io_filename[256];
  5.  
  6. static inline int sys_systree(struct systree_info * i,int * EBX)
  7. {
  8.  int d0,d1;
  9.  __asm__ __volatile__("int $0x40"
  10.      :"=a"(d0),"=b"(d1)
  11.      :"0"(70),"1"((unsigned long)i)
  12.      :"memory");
  13.  if(EBX) *EBX=d1;
  14.  return d0;
  15. }
  16.  
  17. int dosemu_file_exists(const char * filename)
  18. {
  19.         struct systree_info finf;
  20.         struct bdfe_item attr;
  21.         finf.command = 5;
  22.         finf.file_offset_low = 0;
  23.         finf.file_offset_high = 0;
  24.         finf.size = 0;
  25.         finf.data_pointer = (__u32)&attr;
  26.         finf._zero = 0;
  27.         finf.nameptr = filename;
  28.         if (sys_systree(&finf,NULL)!=0)
  29.                 return -1;
  30.         return (int)attr.filesize_low;
  31. }
  32.  
  33. int dosemu_createtrunc(const char * filename)
  34. {
  35.         struct systree_info finf;
  36.         finf.command = 2;
  37.         finf.file_offset_low = finf.file_offset_high = 0;
  38.         finf.size = 0;
  39.         finf.data_pointer = 0;
  40.         finf._zero = 0;
  41.         finf.nameptr = filename;
  42.         if (sys_systree(&finf,NULL))
  43.                 return -1;
  44.         return 0;
  45. }
  46.  
  47. _io_struct * dosemu_getiostruct(int handle)
  48. {
  49.  if(handle<0 || handle>=_MAX_HANDLES) return NULL;
  50.  if(_io_handles[handle].oflags==-1) return NULL;
  51.  return _io_handles+handle;
  52. }
  53.  
  54. int dosemu_allochandle(void)
  55. {
  56.  int i;
  57.  for(i=0;i<_MAX_HANDLES;i++)
  58.   if(_io_handles[i].oflags==-1) return i;
  59.  return -1;
  60. }
  61.  
  62. int dosemu_freehandle(int i)
  63. {
  64.  if(i<0) return;
  65.  _io_handles[i].oflags=-1;
  66. }
  67.  
  68. int dosemu_fileread(_io_struct * sh,char * buffer,int count)
  69. {
  70.         struct systree_info finf;
  71.         int res,ebx;
  72.         finf.command = 0;
  73.         finf.file_offset_low = sh->pointer;
  74.         finf.file_offset_high = 0;
  75.         finf.size = count;
  76.         finf.data_pointer = (__u32)buffer;
  77.         finf._zero = 0;
  78.         finf.nameptr = sh->filename;
  79.         res = sys_systree(&finf,&ebx);
  80.         if (res != 0 && res != 6)
  81.                 return -1;
  82.         sh->pointer += ebx;
  83.         return ebx;
  84. }
  85.  
  86. int dosemu_filewrite(_io_struct * sh,char * buffer,int count)
  87. {
  88.         struct systree_info finf;
  89.         int res,ebx;
  90.         finf.command = 3;
  91.         finf.file_offset_low = sh->pointer;
  92.         finf.file_offset_high = 0;
  93.         finf.size = count;
  94.         finf.data_pointer = (__u32)buffer;
  95.         finf._zero = 0;
  96.         finf.nameptr = sh->filename;
  97.         res = sys_systree(&finf,&ebx);
  98.         if (res != 0 && res != 6)
  99.                 return -1;
  100.         sh->pointer += ebx;
  101.         if (sh->size < sh->pointer)
  102.                 sh->size = sh->pointer;
  103.         return ebx;
  104. }
  105.  
  106. int dosemu_iosize(int handle)
  107. {
  108.  _io_struct * sh=dosemu_getiostruct(handle);
  109.  if(!sh) return -1;
  110.  return sh->size;
  111. }
  112.  
  113. int dosemu_filesize(char * filename)
  114. {
  115.  return dosemu_file_exists(filename);
  116. }
  117.  
  118. static char fn_buf[256];
  119.  
  120. int dosemu_open(char * filename,int oflags)
  121. {
  122.  int baseflags,h,fsize;
  123.  _fixpath(filename,_io_filename);
  124.  baseflags=oflags&(O_RDONLY|O_WRONLY|O_RDWR);
  125.  h=dosemu_allochandle();
  126.  fsize=dosemu_file_exists(_io_filename);
  127.  if(oflags & O_CREAT)
  128.  {
  129.   int creatflags=oflags & (O_EXCL|O_TRUNC);
  130.   if(creatflags & O_EXCL)
  131.   {
  132.    if(fsize>=0)
  133.    {
  134.     dosemu_freehandle(h);
  135.     return -1;
  136.    }
  137.   }
  138.   if(fsize<0 || (creatflags&O_TRUNC))
  139.   {
  140.    if(dosemu_createtrunc(_io_filename)<0)
  141.    {
  142.     dosemu_freehandle(h);
  143.     return -1;
  144.    }
  145.    fsize=0;
  146.   }
  147.  }
  148.  else if (fsize<0)
  149.  {
  150.   dosemu_freehandle(h);
  151.   return -1;
  152.  }
  153.  _io_handles[h].oflags=oflags;
  154.  _io_handles[h].size=fsize;
  155.  _io_handles[h].pointer=0;
  156.  switch (baseflags)
  157.  {
  158.   case O_RDONLY:_io_handles[h].flags=_IO_READ;break;
  159.   case O_WRONLY:_io_handles[h].flags=_IO_WRITE;break;
  160.   case O_RDWR:_io_handles[h].flags=_IO_READ|_IO_WRITE;break;
  161.   default:dosemu_freehandle(h);return -1;
  162.  }
  163.  strcpy(_io_handles[h].filename,_io_filename);
  164.  return h;
  165. }
  166.  
  167. int dosemu_tell(int handle)
  168. {
  169.  _io_struct * sh=dosemu_getiostruct(handle);
  170.  if(!sh) return -1;
  171.  return sh->pointer;
  172. }
  173.  
  174. int dosemu_lseek(int handle,long offset,int origin)
  175. {
  176.  int newpointer=0;
  177.  _io_struct *sh=dosemu_getiostruct(handle);
  178.  if(!sh)return -1;
  179.  if(handle==0 || handle==1 || handle==2 || handle==3) return -1;
  180.  switch(origin)
  181.  {
  182.   case SEEK_SET: newpointer=offset;break;
  183.   case SEEK_CUR: newpointer=sh->pointer+offset;break;
  184.   case SEEK_END: newpointer=sh->size+offset;break;
  185.  }
  186.  if(newpointer<0)return -1;
  187.  sh->pointer=newpointer;
  188.  return newpointer;
  189. }
  190.  
  191. int dosemu_read( int handle, void *buffer, unsigned int count )
  192. {
  193.  _io_struct *sh=dosemu_getiostruct(handle);
  194.  if(!sh)return -1;
  195.  if(!(sh->flags&_IO_READ)) return -1;
  196.  return dosemu_fileread(sh,buffer,count);  
  197. }
  198.  
  199. int dosemu_write( int handle, void *buffer, unsigned int count )
  200. {
  201.  _io_struct *sh=dosemu_getiostruct(handle);
  202.  int k;
  203.  if(!sh)return -1;
  204.  if(!(sh->flags&_IO_WRITE)) return -1;
  205.  return dosemu_filewrite(sh,buffer,count);  
  206. }
  207.  
  208. int dosemu_close( int handle )
  209. {
  210.  _io_struct *sh=dosemu_getiostruct(handle);
  211.  if(!sh)return -1;
  212.  dosemu_freehandle(handle);
  213.  return 0;
  214. }
  215.  
  216. void _dosemu_flush(int handle)
  217. {}
  218.  
  219. int dosemu_truncate(int fd, off_t where)
  220. {
  221.         struct systree_info finf;
  222.         int res;
  223.         _io_struct* sh = dosemu_getiostruct(fd);
  224.         if (!sh) return EBADF;
  225.         if (!(sh->flags & _IO_WRITE)) return EBADF;
  226.         finf.command = 4;
  227.         finf.file_offset_low = where;
  228.         finf.file_offset_high = 0;
  229.         finf.size = 0;
  230.         finf.data_pointer = 0;
  231.         finf._zero = 0;
  232.         finf.nameptr = sh->filename;
  233.         res = sys_systree(&finf,NULL);
  234.         if (res == 8) return ENOSPC;
  235.         if (res) return EACCES;
  236.         sh->size = where;
  237.         return 0;
  238. }
  239.