Subversion Repositories Kolibri OS

Rev

Rev 711 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Win32 implementation of open() and sopen().
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #include "variety.h"
  33. #include "widechar.h"
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <stdarg.h>
  37. #include <string.h>
  38. #include <errno.h>
  39. #include <io.h>
  40. #include <fcntl.h>
  41. #include <sys/stat.h>
  42. #include <share.h>
  43. #include "liballoc.h"
  44. #include "iomode.h"
  45. #include "fileacc.h"
  46. #include "openmode.h"
  47. #include "rtdata.h"
  48. #include "seterrno.h"
  49.  
  50. extern unsigned __NFiles;
  51. extern char *__appcwd;
  52. extern int __appcwdlen;
  53.  
  54. #if (defined(__WINDOWS__) || defined(__NT__))
  55.  
  56. typedef struct
  57. {   DWORD    attr;
  58.     DWORD    flags;
  59.     DWORD    cr_time;
  60.     DWORD    cr_date;
  61.     DWORD    acc_time;
  62.     DWORD    acc_date;
  63.     DWORD    mod_time;
  64.     DWORD    mod_date;
  65.     DWORD    size;
  66.     DWORD    size_high;
  67. } FILEINFO;
  68.  
  69. int _stdcall get_fileinfo(const char *name,FILEINFO* pinfo);
  70. int _stdcall create_file(const char *name);
  71.  
  72.  
  73. typedef struct
  74. {
  75.   char     *name;
  76.   unsigned int offset;
  77. }__file_handle;
  78.  
  79.  
  80. char* getfullpath(const char* path)
  81. {
  82.     int prev_is_slash=0;
  83.     int len=0, depth=0, i;
  84.     char* buff;
  85.     char c;
  86.    
  87.     if(*path == '/')
  88.     {
  89.       buff = (char*)lib_malloc(strlen(path)+1);
  90.       buff[0] = '\0';
  91.       len=0;
  92.     }  
  93.     else
  94.     {
  95.       len= __appcwdlen;
  96.       buff = (char*)lib_malloc(len+strlen(path)+1);
  97.       strncpy(buff, __appcwd, __appcwdlen);
  98.      
  99.       prev_is_slash = 1;
  100.       buff[len] = 0;
  101.       for(i=0; buff[i]; i++)
  102.         if(buff[i] == '/' && i < len-1) depth++;
  103.     }
  104.    
  105.     while(c=*path++)
  106.     {
  107.       switch (c)
  108.       {
  109.      
  110.         case '.':
  111.           if((*path == '.')&&
  112.              (*path+1)== '/')
  113.           { if(!depth)
  114.             {  free(buff);
  115.                return 0;
  116.             };
  117.             buff[len-1] = 0;
  118.             len = strrchr(buff, '/') + 1 - buff;
  119.             buff[len] = 0;
  120.             depth--;
  121.             path +=2;
  122.             prev_is_slash = 1;
  123.             continue;
  124.           }
  125.           if(*path == '/')
  126.           {
  127.             path++;
  128.             prev_is_slash = 1;
  129.             continue;
  130.           }
  131.           buff[len++] = c;
  132.           continue;
  133.      
  134.         case '/':
  135.           prev_is_slash = 1;
  136.           buff[len++] = c;
  137.           continue;
  138.          
  139.         default:
  140.           prev_is_slash = 0;
  141.           buff[len++] = c;
  142.           continue;
  143.         };
  144.     };
  145.     buff[len]= '\0';
  146.     return buff;
  147. };
  148.  
  149.  
  150. size_t FileSize(FILE *fp)
  151. {
  152.   int hdl;
  153.   __file_handle *fh;
  154.   FILEINFO info;
  155.  
  156.   hdl = fileno( fp );
  157.  // __handle_check( hdl, -1 );
  158.  
  159.   fh = (__file_handle*) __getOSHandle(hdl);
  160.  
  161.    
  162.   get_fileinfo(fh->name,&info);
  163.  
  164.   return info.size;
  165.  
  166. }
  167.  
  168. int access(const char *path, int mode)
  169. { size_t retval;
  170.   FILEINFO info;
  171.   char *p;
  172.  
  173.   p = getfullpath(path);
  174.   retval=get_fileinfo(p,&info);
  175.   free(p);
  176.  
  177.   return retval;
  178.  
  179. }
  180.  
  181. static HANDLE __openFileHandle(const CHAR_TYPE *name, int mode)
  182. {
  183.   FILEINFO info;
  184.   __file_handle *handle;
  185.   char *path;
  186.   int err;
  187.  
  188.   path = getfullpath(name);
  189.  
  190.   if(err=get_fileinfo(path,&info))
  191.   {
  192. //    printf("failed getfileinfo %s\n\r", path);
  193.      
  194.     if(mode & O_CREAT)
  195.       err=create_file(path);
  196.      
  197.     if(err)
  198.     {        
  199.       lib_free(path);
  200.       return (HANDLE)-1;
  201.     };
  202.   };
  203.  
  204.   if ( !(handle=(__file_handle*)lib_malloc(sizeof( __file_handle) )))
  205.   { lib_free(path);
  206.     return (HANDLE)-1;
  207.   };
  208.  
  209.   handle->name = path;
  210.   handle->offset = 0;  
  211.  
  212.   return (HANDLE)handle;
  213. };    
  214.  
  215.  
  216. static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode, int share, va_list args )
  217. {
  218.     HANDLE              handle;
  219.     int                 hid, rwmode;
  220.     unsigned            iomode_flags;
  221.  
  222.     // First try to get the required slot.
  223.     // No point in creating a file only to not use it.  JBS 99/10/26
  224.     hid = __allocPOSIXHandle( DUMMY_HANDLE );
  225.     if( hid == -1 )
  226.      {
  227.         return( -1 );
  228.     }
  229.  
  230.     rwmode = mode;
  231.  
  232.  
  233.     /*** Open the file ***/
  234.        
  235.     handle = __openFileHandle( name, mode);
  236.    
  237.     if( handle==(HANDLE)-1 )
  238.     {
  239.       __freePOSIXHandle( hid );
  240.       return( -1 ); //error
  241.     }
  242.  
  243. // Now use the slot we got.
  244.     __setOSHandle( hid, handle );   // JBS 99/11/01
  245.  
  246.     iomode_flags = 0;
  247.  
  248.  
  249.     if( rwmode == O_RDWR )       iomode_flags |= _READ | _WRITE;
  250.     else if( rwmode == O_RDONLY) iomode_flags |= _READ;
  251.     else if( rwmode == O_WRONLY) iomode_flags |= _WRITE;
  252.     if( mode & O_APPEND )        iomode_flags |= _APPEND;
  253.     if( mode & (O_BINARY|O_TEXT) ) {
  254.         if( mode & O_BINARY )    iomode_flags |= _BINARY;
  255.     } else {
  256.         if( _RWD_fmode == O_BINARY ) iomode_flags |= _BINARY;
  257.     }
  258.     __SetIOMode( hid, iomode_flags );
  259.     return( hid );
  260. }
  261.  
  262. #elif
  263. static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode, int share, va_list args )
  264. {
  265.     DWORD               create_disp, exists_disp;
  266.     DWORD               perm, fileattr;
  267.     DWORD               desired_access, share_mode;
  268.     SECURITY_ATTRIBUTES security;
  269.     HANDLE              handle;
  270.     int                 hid, rwmode;
  271.     unsigned            iomode_flags;
  272.  
  273.     // First try to get the required slot.
  274.     // No point in creating a file only to not use it.  JBS 99/10/26
  275.     hid = __allocPOSIXHandle( DUMMY_HANDLE );
  276.     if( hid == -1 ) {
  277.         return( -1 );
  278.     }
  279.  
  280.     rwmode = mode & OPENMODE_ACCESS_MASK;
  281.     __GetNTAccessAttr( rwmode, &desired_access, &perm );
  282.     __GetNTShareAttr( share|rwmode, &share_mode );
  283.     fileattr = FILE_ATTRIBUTE_NORMAL;
  284.  
  285.     security.nLength = sizeof( SECURITY_ATTRIBUTES );
  286.     security.lpSecurityDescriptor = NULL;
  287.     security.bInheritHandle = mode&O_NOINHERIT ? FALSE : TRUE;
  288.  
  289. #ifdef DEFAULT_WINDOWING
  290. #ifdef __WIDECHAR__
  291.     if( _WindowsNewWindow != 0 && !_wcsicmp( name, L"con" ) )
  292. #else
  293.     if( _WindowsNewWindow != 0 && !stricmp( name, "con" ) )
  294. #endif
  295.     {
  296.         handle = (HANDLE) __NTGetFakeHandle();
  297.  
  298.         // Now use the slot we got.
  299.         __setOSHandle( hid, handle );   // JBS 99/11/01
  300.         _WindowsNewWindow( NULL, hid, -1 );
  301.  
  302.         iomode_flags = _ISTTY;
  303.     } else {
  304. #endif
  305.         if( mode & O_CREAT ) {
  306.             perm = va_arg( args, int );
  307.                 va_end( args );
  308.                 perm &= ~_RWD_umaskval;             /* 05-jan-95 */
  309.             if( ( perm & S_IREAD ) && !( perm & S_IWRITE ) ) {
  310.                 fileattr = FILE_ATTRIBUTE_READONLY;
  311.             }
  312.             if( mode & O_EXCL ) {
  313.                 create_disp = CREATE_NEW;
  314.                 exists_disp = CREATE_NEW;
  315.             } else if( mode & O_TRUNC ) {
  316.                 create_disp = CREATE_ALWAYS;
  317.                 exists_disp = CREATE_NEW;
  318.             } else {
  319.                 create_disp = OPEN_ALWAYS;
  320.                 exists_disp = OPEN_EXISTING;
  321.             }
  322.         } else if( mode & O_TRUNC ) {
  323.             exists_disp = TRUNCATE_EXISTING;
  324.         } else {
  325.             exists_disp = OPEN_EXISTING;
  326.         }
  327.  
  328.         /*** Open the file ***/
  329.         #ifdef __WIDECHAR__
  330.             handle = __lib_CreateFileW( name, desired_access, share_mode,
  331.                                         &security, exists_disp, fileattr,
  332.                                         NULL );
  333.         #else
  334.             handle = CreateFileA( name, desired_access, share_mode,
  335.                                   &security, exists_disp, fileattr, NULL );
  336.         #endif
  337.         if( handle==(HANDLE)-1 ) {
  338.             if( mode&O_CREAT ) {
  339.                 #ifdef __WIDECHAR__
  340.                     handle = __lib_CreateFileW( name, desired_access,
  341.                                                 share_mode, NULL, create_disp,
  342.                                                 fileattr, NULL );
  343.                 #else
  344.                     handle = CreateFileA( name, desired_access,
  345.                                           share_mode, NULL, create_disp,
  346.                                           fileattr, NULL );
  347.                 #endif
  348.             }
  349.             if( handle == (HANDLE)-1 ) {
  350.                 __freePOSIXHandle( hid );
  351.                 return( __set_errno_nt() );
  352.             }
  353.         }
  354.  
  355.         // Now use the slot we got.
  356.         __setOSHandle( hid, handle );   // JBS 99/11/01
  357.  
  358.         iomode_flags = 0;
  359.  
  360.         if( isatty(hid) ) {
  361.             iomode_flags = _ISTTY;
  362.         }
  363. #ifdef DEFAULT_WINDOWING
  364.     }
  365. #endif
  366.  
  367.     if( rwmode == O_RDWR )       iomode_flags |= _READ | _WRITE;
  368.     else if( rwmode == O_RDONLY) iomode_flags |= _READ;
  369.     else if( rwmode == O_WRONLY) iomode_flags |= _WRITE;
  370.     if( mode & O_APPEND )        iomode_flags |= _APPEND;
  371.     if( mode & (O_BINARY|O_TEXT) ) {
  372.         if( mode & O_BINARY )    iomode_flags |= _BINARY;
  373.     } else {
  374.         if( _RWD_fmode == O_BINARY ) iomode_flags |= _BINARY;
  375.     }
  376.     __SetIOMode( hid, iomode_flags );
  377.     return( hid );
  378. }
  379. #endif
  380.  
  381. _WCRTLINK int __F_NAME(open,_wopen)( const CHAR_TYPE *name, int mode, ... )
  382. {
  383.     int         permission;
  384.     va_list     args;
  385.  
  386.     va_start( args, mode );
  387.     permission = va_arg( args, int );
  388.     va_end( args );
  389.     return( __F_NAME(sopen,_wsopen)( name, mode, SH_COMPAT, permission ) );
  390. }
  391.  
  392.  
  393. _WCRTLINK int __F_NAME(sopen,_wsopen)( const CHAR_TYPE *name, int mode, int shflag, ... )
  394. {
  395.     va_list             args;
  396.  
  397.     va_start( args, shflag );
  398.     return( __F_NAME(_sopen,__wsopen)( name, mode, shflag, args ) );
  399. }
  400.