Subversion Repositories Kolibri OS

Rev

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

  1. /* Reentrant versions of open system call. */
  2.  
  3. #include <reent.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <_syslist.h>
  7. #include <sys/errno.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <stdarg.h>
  11.  
  12. /* Some targets provides their own versions of this functions.  Those
  13.    targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS.  */
  14.  
  15. #ifdef _REENT_ONLY
  16. #ifndef REENTRANT_SYSCALLS_PROVIDED
  17. #define REENTRANT_SYSCALLS_PROVIDED
  18. #endif
  19. #endif
  20.  
  21. #ifndef REENTRANT_SYSCALLS_PROVIDED
  22.  
  23. /* We use the errno variable used by the system dependent layer.  */
  24.  
  25. /*
  26. FUNCTION
  27.         <<_open_r>>---Reentrant version of open
  28.  
  29. INDEX
  30.         _open_r
  31.  
  32. ANSI_SYNOPSIS
  33.         #include <reent.h>
  34.         int _open_r(struct _reent *<[ptr]>,
  35.                     const char *<[file]>, int <[flags]>, int <[mode]>);
  36.  
  37. TRAD_SYNOPSIS
  38.         #include <reent.h>
  39.         int _open_r(<[ptr]>, <[file]>, <[flags]>, <[mode]>)
  40.         struct _reent *<[ptr]>;
  41.         char *<[file]>;
  42.         int <[flags]>;
  43.         int <[mode]>;
  44.  
  45. DESCRIPTION
  46.         This is a reentrant version of <<open>>.  It
  47.         takes a pointer to the global data block, which holds
  48.         <<errno>>.
  49. */
  50.  
  51.  
  52. #pragma pack(push, 1)
  53. typedef struct
  54. {
  55.     char sec;
  56.     char min;
  57.     char hour;
  58.     char rsv;
  59. }detime_t;
  60.  
  61. typedef struct
  62. {
  63.     char  day;
  64.     char  month;
  65.     short year;
  66. }dedate_t;
  67.  
  68. typedef struct
  69. {
  70.     unsigned    attr;
  71.     unsigned    flags;
  72.     union
  73.     {
  74.         detime_t  ctime;
  75.         unsigned  cr_time;
  76.     };
  77.     union
  78.     {
  79.         dedate_t  cdate;
  80.         unsigned  cr_date;
  81.     };
  82.     union
  83.     {
  84.         detime_t  atime;
  85.         unsigned  acc_time;
  86.     };
  87.     union
  88.     {
  89.         dedate_t  adate;
  90.         unsigned  acc_date;
  91.     };
  92.     union
  93.     {
  94.         detime_t  mtime;
  95.         unsigned  mod_time;
  96.     };
  97.     union
  98.     {
  99.         dedate_t  mdate;
  100.         unsigned  mod_date;
  101.     };
  102.     unsigned    size;
  103.     unsigned    size_high;
  104. } fileinfo_t;
  105.  
  106. #pragma pack(pop)
  107.  
  108.  
  109. #define NULL_HANDLE  (int)-1
  110. #define DUMMY_HANDLE (int)-2
  111.  
  112. #define _READ   0x0001  /* file opened for reading */
  113. #define _WRITE  0x0002  /* file opened for writing */
  114. #define _UNGET  0x0004  /* ungetc has been done */
  115. #define _BIGBUF 0x0008  /* big buffer allocated */
  116. #define _EOF    0x0010  /* EOF has occurred */
  117. #define _SFERR  0x0020  /* error has occurred on this file */
  118. #define _APPEND 0x0080  /* file opened for append */
  119. #define _BINARY 0x0040  /* file is binary, skip CRLF processing */
  120. #define _TMPFIL 0x0800  /* this is a temporary file */
  121. #define _DIRTY  0x1000  /* buffer has been modified */
  122. #define _ISTTY  0x2000  /* is console device */
  123. #define _DYNAMIC 0x4000 /* FILE is dynamically allocated   */
  124. #define _FILEEXT 0x8000 /* lseek with positive offset has been done */
  125. #define _COMMIT 0x0001  /* extended flag: commit OS buffers on flush */
  126.  
  127. extern int       _fmode;
  128.  
  129. int create_file(const char *path)
  130. {
  131.      int retval;
  132.      __asm__ __volatile__ (
  133.      "pushl $0 \n\t"
  134.      "pushl $0 \n\t"
  135.      "movl %0, 1(%%esp) \n\t"
  136.      "pushl $0 \n\t"
  137.      "pushl $0 \n\t"
  138.      "pushl $0 \n\t"
  139.      "pushl $0 \n\t"
  140.      "pushl $2 \n\t"
  141.      "movl %%esp, %%ebx \n\t"
  142.      "movl $70, %%eax \n\t"
  143.      "int $0x40 \n\t"
  144.      "addl $28, %%esp \n\t"
  145.      :"=a" (retval)
  146.      :"r" (path)
  147.      :"ebx");
  148.   return retval;
  149. };
  150.  
  151. int set_file_size(const char *path, unsigned size)
  152. {
  153.      int retval;
  154.      __asm__ __volatile__(
  155.      "pushl $0 \n\t"
  156.      "pushl $0 \n\t"
  157.      "movl %%eax, 1(%%esp) \n\t"
  158.      "pushl $0 \n\t"
  159.      "pushl $0 \n\t"
  160.      "pushl $0 \n\t"
  161.      "pushl %%ebx \n\t"
  162.      "push $4 \n\t"
  163.      "movl %%esp, %%ebx \n\t"
  164.      "movl $70, %%eax \n\t"
  165.      "int $0x40 \n\t"
  166.      "addl $28, %%esp \n\t"
  167.      :"=a" (retval)
  168.      :"a" (path), "b" (size));
  169.      return retval;
  170. };
  171.  
  172. int get_fileinfo(const char *path, fileinfo_t *info)
  173. {
  174.     int retval;
  175.  
  176.     __asm__ __volatile__ (
  177.     "pushl $0 \n\t"
  178.     "pushl $0 \n\t"
  179.     "movl %1, 1(%%esp) \n\t"
  180.     "pushl %%ebx \n\t"
  181.     "pushl $0 \n\t"
  182.     "pushl $0 \n\t"
  183.     "pushl $0 \n\t"
  184.     "pushl $5 \n\t"
  185.     "movl %%esp, %%ebx \n\t"
  186.     "movl $70, %%eax \n\t"
  187.     "int $0x40 \n\t"
  188.     "addl $28, %%esp \n\t"
  189.     :"=a" (retval)
  190.     :"r" (path), "b" (info));
  191.    return retval;
  192. };
  193.  
  194.  
  195. int read_file(const char *path, void *buff,
  196.                size_t offset, size_t count, size_t *reads)
  197. {
  198.     int  retval;
  199.     int  d0;
  200.     __asm__ __volatile__(
  201.     "pushl $0 \n\t"
  202.     "pushl $0 \n\t"
  203.     "movl %%eax, 1(%%esp) \n\t"
  204.     "pushl %%ebx \n\t"
  205.     "pushl %%edx \n\t"
  206.     "pushl $0 \n\t"
  207.     "pushl %%ecx \n\t"
  208.     "pushl $0 \n\t"
  209.     "movl %%esp, %%ebx \n\t"
  210.     "mov $70, %%eax \n\t"
  211.     "int $0x40 \n\t"
  212.     "testl %%esi, %%esi \n\t"
  213.     "jz 1f \n\t"
  214.     "movl %%ebx, (%%esi) \n\t"
  215. "1:"
  216.     "addl $28, %%esp \n\t"
  217.     :"=a" (retval)
  218.     :"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(reads));
  219.     return retval;
  220. };
  221.  
  222.  
  223. static inline void debug_out(const char val)
  224. {
  225.     __asm__ __volatile__(
  226.     "int $0x40 \n\t"
  227.     ::"a"(63), "b"(1),"c"(val));
  228. }
  229.  
  230. int   debugwrite(const char *path, const void *buff,
  231.                  size_t offset, size_t count, size_t *writes)
  232. {
  233.     int ret = count;
  234.     const char *p = buff;
  235.  
  236.     while (count--)
  237.     {
  238.         debug_out(*p++);
  239.     };
  240.     *writes = ret;
  241.     return ret;
  242. };
  243.  
  244.  
  245. int write_file(const char *path,const void *buff,
  246.                size_t offset, size_t count, size_t *writes)
  247. {
  248.      int retval;
  249.      __asm__ __volatile__(
  250.      "pushl $0 \n\t"
  251.      "pushl $0 \n\t"
  252.      "movl %%eax, 1(%%esp) \n\t"
  253.      "pushl %%ebx \n\t"
  254.      "pushl %%edx \n\t"
  255.      "pushl $0 \n\t"
  256.      "pushl %%ecx \n\t"
  257.      "pushl $3 \n\t"
  258.      "movl %%esp, %%ebx \n\t"
  259.      "mov $70, %%eax \n\t"
  260.      "int $0x40 \n\t"
  261.      "testl %%esi, %%esi \n\t"
  262.      "jz 1f \n\t"
  263.      "movl %%ebx, (%%esi) \n\t"
  264. "1:"
  265.      "addl $28, %%esp \n\t"
  266.      :"=a" (retval)
  267.      :"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes));
  268.     return retval;
  269. };
  270.  
  271. static int __openFileHandle(const char *path, int mode, int *err)
  272. {
  273.     fileinfo_t     info;
  274.     __file_handle *handle;
  275.  
  276. //    path = getfullpath(name);
  277.  
  278.     *err = get_fileinfo(path, &info);
  279.  
  280.     if( mode & O_EXCL && mode & O_CREAT )
  281.     {
  282.         if( ! *err)
  283.         {
  284.             *err = EEXIST;
  285.             return -1;
  286.         };
  287.     }
  288.  
  289.     if( *err)
  290.     {
  291.         if(mode & O_CREAT)
  292.             *err=create_file(path);
  293.  
  294.         if( *err)
  295.         {
  296.             return -1;
  297.         };
  298.     };
  299.     if( mode & O_TRUNC )
  300.         set_file_size(path, 0);
  301.  
  302.     if ( !(handle=(__file_handle*)malloc(sizeof( __file_handle) )))
  303.     {
  304.         *err = ENOMEM;
  305.         return -1;
  306.     };
  307.  
  308.     handle->name   = strdup(path);
  309.     handle->offset = 0;
  310.     handle->write  = write_file;
  311.  
  312.     *err = 0;
  313.  
  314.     return (int)handle;
  315. };
  316.  
  317.  
  318.  
  319. int
  320. _DEFUN (_open_r, (ptr, file, flags, dmode),
  321.      struct _reent *ptr _AND
  322.      _CONST char *file _AND
  323.      int flags _AND
  324.      int dmode)
  325. {
  326.     int         hid;
  327.     int         handle;
  328.     int         err = 0;
  329.     unsigned    iomode_flags;
  330.     int         rwmode;
  331.  
  332. /*
  333.     if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
  334.     {
  335.         ptr->_errno = ENOSYS;
  336.         return -1;
  337.     }
  338. */
  339.  
  340.     // First try to get the required slot.
  341.     // No point in creating a file only to not use it.  JBS 99/10/26
  342.     hid = __allocPOSIXHandle( DUMMY_HANDLE );
  343.     if( hid == -1 )
  344.     {
  345.         ptr->_errno = EMFILE;
  346.         return( -1 );
  347.     }
  348.  
  349.     handle = __openFileHandle( file, flags, &err);
  350.  
  351.     if( handle == -1 )
  352.     {
  353.         __freePOSIXHandle( hid );
  354.         ptr->_errno = err;
  355.         return( -1 );
  356.     }
  357.  
  358.     __setOSHandle( hid, handle );   // JBS 99/11/01
  359.  
  360.     rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT );
  361.  
  362.     iomode_flags = 0;
  363.  
  364.     if( rwmode == O_RDWR )       iomode_flags |= _READ | _WRITE;
  365.     else if( rwmode == O_RDONLY) iomode_flags |= _READ;
  366.     else if( rwmode == O_WRONLY) iomode_flags |= _WRITE;
  367.     if( flags & O_APPEND )        iomode_flags |= _APPEND;
  368.     if( flags & (O_BINARY|O_TEXT) ) {
  369.         if( flags & O_BINARY )    iomode_flags |= _BINARY;
  370.     } else {
  371.         if( _fmode == O_BINARY ) iomode_flags |= _BINARY;
  372.     }
  373.     __SetIOMode( hid, iomode_flags );
  374.  
  375.     ptr->_errno = 0;
  376.  
  377.     return (hid);
  378. }
  379.  
  380. int
  381. _DEFUN (open, (file, flags, ...),
  382.         const char *file _AND
  383.         int flags _DOTS)
  384. {
  385.   va_list ap;
  386.   int ret;
  387.  
  388.   va_start (ap, flags);
  389.   ret = _open_r (_REENT, file, flags, va_arg (ap, int));
  390.   va_end (ap);
  391.   return ret;
  392. }
  393.  
  394.  
  395.  
  396. #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */
  397.