Subversion Repositories Kolibri OS

Rev

Rev 711 | 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. #include "kolibri.h"
  50.  
  51. extern unsigned __NFiles;
  52. extern char *__appcwd;
  53. extern int __appcwdlen;
  54.  
  55. #if (defined(__WINDOWS__) || defined(__NT__))
  56.  
  57. typedef struct
  58. {
  59.   char     *name;
  60.   unsigned int offset;
  61. }__file_handle;
  62.  
  63.  
  64. char* getfullpath(const char* path)
  65. {
  66.     int prev_is_slash=0;
  67.     int len=0, depth=0, i;
  68.     char* buff;
  69.     char c;
  70.  
  71.  
  72.     buff = (char*)lib_malloc(strlen(path)+2);
  73.     strcpy(buff, path);
  74.  
  75.     if(*path == '/')
  76.     {
  77.       buff = (char*)lib_malloc(strlen(path)+1);
  78.       buff[0] = '\0';
  79.       len=0;
  80.     }  
  81.     else
  82.     {
  83.       len= __appcwdlen;
  84.       buff = (char*)lib_malloc(len+strlen(path)+1);
  85.       strncpy(buff, __appcwd, __appcwdlen);
  86.      
  87.       prev_is_slash = 1;
  88.       buff[len] = 0;
  89.       for(i=0; buff[i]; i++)
  90.         if(buff[i] == '/' && i < len-1) depth++;
  91.     }
  92.    
  93.     while(c=*path++)
  94.     {
  95.       switch (c)
  96.       {
  97.      
  98.         case '.':
  99.           if((*path == '.')&&
  100.              (*path+1)== '/')
  101.           { if(!depth)
  102.             {  free(buff);
  103.                return 0;
  104.             };
  105.             buff[len-1] = 0;
  106.             len = strrchr(buff, '/') + 1 - buff;
  107.             buff[len] = 0;
  108.             depth--;
  109.             path +=2;
  110.             prev_is_slash = 1;
  111.             continue;
  112.           }
  113.           if(*path == '/')
  114.           {
  115.             path++;
  116.             prev_is_slash = 1;
  117.             continue;
  118.           }
  119.           buff[len++] = c;
  120.           continue;
  121.      
  122.         case '/':
  123.           prev_is_slash = 1;
  124.           buff[len++] = c;
  125.           continue;
  126.          
  127.         default:
  128.           prev_is_slash = 0;
  129.           buff[len++] = c;
  130.           continue;
  131.         };
  132.     };
  133.     buff[len]= '\0';
  134.    
  135.     return buff;
  136. };
  137.  
  138.  
  139. size_t FileSize(FILE *fp)
  140. {
  141.   int hdl;
  142.   __file_handle *fh;
  143.   FILEINFO info;
  144.  
  145.   hdl = fileno( fp );
  146.  // __handle_check( hdl, -1 );
  147.  
  148.   fh = (__file_handle*) __getOSHandle(hdl);
  149.  
  150.    
  151.   get_fileinfo(fh->name,&info);
  152.  
  153.   return info.size;
  154.  
  155. }
  156.  
  157. int access(const char *path, int mode)
  158. { size_t retval;
  159.   FILEINFO info;
  160.   char *p;
  161.  
  162.   p = getfullpath(path);
  163.   retval=get_fileinfo(p,&info);
  164.   free(p);
  165.  
  166.   return retval;
  167.  
  168. }
  169.  
  170. static HANDLE __openFileHandle(const CHAR_TYPE *name, int mode)
  171. {
  172.   FILEINFO info;
  173.   __file_handle *handle;
  174.   char *path;
  175.   int err;
  176.  
  177.   path = getfullpath(name);
  178.  
  179.   err=get_fileinfo(path,&info);
  180.  
  181.   if( mode & O_EXCL && mode & O_CREAT )
  182.   {
  183.      if( !err)
  184.      {
  185.        __set_errno( EEXIST );
  186.        return (HANDLE)-1;
  187.      };  
  188.   }
  189.  
  190.   if(err)
  191.   {
  192.     if(mode & O_CREAT)
  193.       err=create_file(path);
  194.      
  195.     if(err)
  196.     {        
  197.       lib_free(path);
  198.       return (HANDLE)-1;
  199.     };
  200.   };
  201.   if( mode & O_TRUNC )
  202.     set_file_size(path, 0);
  203.      
  204.   if ( !(handle=(__file_handle*)lib_malloc(sizeof( __file_handle) )))
  205.   {
  206.     lib_free(path);
  207.     return (HANDLE)-1;
  208.   };
  209.  
  210.   handle->name = path;
  211.   handle->offset = 0;  
  212.  
  213.   return (HANDLE)handle;
  214. };    
  215.  
  216.  
  217. static int __F_NAME(_sopen,__wsopen)( const CHAR_TYPE *name, int mode, int share, va_list args )
  218. {
  219.     HANDLE              handle;
  220.     int                 hid, rwmode;
  221.     unsigned            iomode_flags;
  222.  
  223.     // First try to get the required slot.
  224.     // No point in creating a file only to not use it.  JBS 99/10/26
  225.     hid = __allocPOSIXHandle( DUMMY_HANDLE );
  226.     if( hid == -1 )
  227.      {
  228.         return( -1 );
  229.     }
  230.  
  231.     rwmode = mode & ( O_RDONLY | O_WRONLY | O_RDWR | O_NOINHERIT );
  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.  
  245.     __setOSHandle( hid, handle );   // JBS 99/11/01
  246.  
  247.     iomode_flags = 0;
  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.