Subversion Repositories Kolibri OS

Rev

Rev 1693 | 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. #include <sys/kos_io.h>
  12.  
  13. /* Some targets provides their own versions of this functions.  Those
  14.    targets should define REENTRANT_SYSCALLS_PROVIDED in TARGET_CFLAGS.  */
  15.  
  16. #ifdef _REENT_ONLY
  17. #ifndef REENTRANT_SYSCALLS_PROVIDED
  18. #define REENTRANT_SYSCALLS_PROVIDED
  19. #endif
  20. #endif
  21.  
  22. #ifndef REENTRANT_SYSCALLS_PROVIDED
  23.  
  24. /* We use the errno variable used by the system dependent layer.  */
  25.  
  26. /*
  27. FUNCTION
  28.         <<_open_r>>---Reentrant version of open
  29.  
  30. INDEX
  31.         _open_r
  32.  
  33. ANSI_SYNOPSIS
  34.         #include <reent.h>
  35.         int _open_r(struct _reent *<[ptr]>,
  36.                     const char *<[file]>, int <[flags]>, int <[mode]>);
  37.  
  38. TRAD_SYNOPSIS
  39.         #include <reent.h>
  40.         int _open_r(<[ptr]>, <[file]>, <[flags]>, <[mode]>)
  41.         struct _reent *<[ptr]>;
  42.         char *<[file]>;
  43.         int <[flags]>;
  44.         int <[mode]>;
  45.  
  46. DESCRIPTION
  47.         This is a reentrant version of <<open>>.  It
  48.         takes a pointer to the global data block, which holds
  49.         <<errno>>.
  50. */
  51.  
  52.  
  53.  
  54. #define NULL_HANDLE  (int)-1
  55. #define DUMMY_HANDLE (int)-2
  56.  
  57. #define _READ   0x0001  /* file opened for reading */
  58. #define _WRITE  0x0002  /* file opened for writing */
  59. #define _UNGET  0x0004  /* ungetc has been done */
  60. #define _BIGBUF 0x0008  /* big buffer allocated */
  61. #define _EOF    0x0010  /* EOF has occurred */
  62. #define _SFERR  0x0020  /* error has occurred on this file */
  63. #define _APPEND 0x0080  /* file opened for append */
  64. #define _BINARY 0x0040  /* file is binary, skip CRLF processing */
  65. #define _TMPFIL 0x0800  /* this is a temporary file */
  66. #define _DIRTY  0x1000  /* buffer has been modified */
  67. #define _ISTTY  0x2000  /* is console device */
  68. #define _DYNAMIC 0x4000 /* FILE is dynamically allocated   */
  69. #define _FILEEXT 0x8000 /* lseek with positive offset has been done */
  70. #define _COMMIT 0x0001  /* extended flag: commit OS buffers on flush */
  71.  
  72. extern int       _fmode;
  73.  
  74.  
  75. static inline void debug_out(const char val)
  76. {
  77.     __asm__ __volatile__(
  78.     "int $0x40 \n\t"
  79.     ::"a"(63), "b"(1),"c"(val));
  80. }
  81.  
  82. int   debugwrite(const char *path, const void *buff,
  83.                  size_t offset, size_t count, size_t *writes)
  84. {
  85.     int ret = count;
  86.     const char *p = buff;
  87.  
  88.     while (count--)
  89.     {
  90.         debug_out(*p++);
  91.     };
  92.     *writes = ret;
  93.     return ret;
  94. };
  95.  
  96. static int __openFileHandle(const char *path, int mode, int *err)
  97. {
  98.     fileinfo_t     info;
  99.     __file_handle *handle;
  100.  
  101. //    path = getfullpath(name);
  102.  
  103.     *err = get_fileinfo(path, &info);
  104.  
  105.     if( mode & O_EXCL && mode & O_CREAT )
  106.     {
  107.         if( ! *err)
  108.         {
  109.             *err = EEXIST;
  110.             return -1;
  111.         };
  112.     }
  113.  
  114.     if( *err)
  115.     {
  116.         if(mode & O_CREAT)
  117.             *err=create_file(path);
  118.  
  119.         if( *err)
  120.         {
  121.             return -1;
  122.         };
  123.     };
  124.     if( mode & O_TRUNC )
  125.         set_file_size(path, 0);
  126.  
  127.     if ( !(handle=(__file_handle*)malloc(sizeof( __file_handle) )))
  128.     {
  129.         *err = ENOMEM;
  130.         return -1;
  131.     };
  132.  
  133.     handle->name   = strdup(path);
  134.     handle->offset = 0;
  135.     handle->write  = write_file;
  136.  
  137.     *err = 0;
  138.  
  139.     return (int)handle;
  140. };
  141.  
  142.  
  143.  
  144. int
  145. _DEFUN (_open_r, (ptr, file, flags, dmode),
  146.      struct _reent *ptr _AND
  147.      _CONST char *file _AND
  148.      int flags _AND
  149.      int dmode)
  150. {
  151.     int         hid;
  152.     int         handle;
  153.     int         err = 0;
  154.     unsigned    iomode_flags;
  155.     int         rwmode;
  156.  
  157. /*
  158.     if (flags & ~(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_APPEND | O_TRUNC))
  159.     {
  160.         ptr->_errno = ENOSYS;
  161.         return -1;
  162.     }
  163. */
  164.  
  165.     // First try to get the required slot.
  166.     // No point in creating a file only to not use it.  JBS 99/10/26
  167.     hid = __allocPOSIXHandle( DUMMY_HANDLE );
  168.     if( hid == -1 )
  169.     {
  170.         ptr->_errno = EMFILE;
  171.         return( -1 );
  172.     }
  173.  
  174.     handle = __openFileHandle( file, flags, &err);
  175.  
  176.     if( handle == -1 )
  177.     {
  178.         __freePOSIXHandle( hid );
  179.         ptr->_errno = err;
  180.         return( -1 );
  181.     }
  182.  
  183.     __setOSHandle( hid, handle );   // JBS 99/11/01
  184.  
  185.     rwmode = flags & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT );
  186.  
  187.     iomode_flags = 0;
  188.  
  189.     if( rwmode == O_RDWR )       iomode_flags |= _READ | _WRITE;
  190.     else if( rwmode == O_RDONLY) iomode_flags |= _READ;
  191.     else if( rwmode == O_WRONLY) iomode_flags |= _WRITE;
  192.     if( flags & O_APPEND )        iomode_flags |= _APPEND;
  193.     if( flags & (O_BINARY|O_TEXT) ) {
  194.         if( flags & O_BINARY )    iomode_flags |= _BINARY;
  195.     } else {
  196.         if( _fmode == O_BINARY ) iomode_flags |= _BINARY;
  197.     }
  198.     __SetIOMode( hid, iomode_flags );
  199.  
  200.     ptr->_errno = 0;
  201.  
  202.     return (hid);
  203. }
  204.  
  205. int
  206. _DEFUN (open, (file, flags, ...),
  207.         const char *file _AND
  208.         int flags _DOTS)
  209. {
  210.   va_list ap;
  211.   int ret;
  212.  
  213.   va_start (ap, flags);
  214.   ret = _open_r (_REENT, file, flags, va_arg (ap, int));
  215.   va_end (ap);
  216.   return ret;
  217. }
  218.  
  219.  
  220.  
  221. #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */
  222.