示例#1
0
static PHB_FILE hb_fileNew( HB_FHANDLE hFile, HB_BOOL fShared, HB_BOOL fReadonly,
                            HB_ULONG device, HB_ULONG inode, HB_BOOL fBind )
{
   PHB_FILE pFile = hb_fileFind( device, inode );

   if( ! pFile )
   {
      pFile = ( PHB_FILE ) hb_xgrabz( sizeof( HB_FILE ) );
      pFile->pFuncs   = s_fileMethods();
      pFile->device   = device;
      pFile->inode    = inode;
      pFile->hFile    = hFile;
      pFile->hFileRO  = FS_ERROR;
      pFile->shared   = fShared;
      pFile->readonly = fReadonly;

      if( fBind )
      {
         if( s_openFiles )
         {
            pFile->pNext = s_openFiles;
            pFile->pPrev = s_openFiles->pPrev;
            pFile->pPrev->pNext = pFile;
            s_openFiles->pPrev = pFile;
         }
         else
            s_openFiles = pFile->pNext = pFile->pPrev = pFile;
      }
   }
   pFile->used++;

   return pFile;
}
示例#2
0
static PHB_FILE s_fileExtOpen( PHB_FILE_FUNCS pFuncs, const char * pszFileName, const char * pDefExt,
                               HB_USHORT uiExFlags, const char * pPaths,
                               PHB_ITEM pError )
{
   PHB_FILE pFile = NULL;

#if defined( HB_OS_UNIX )
   HB_BOOL fResult, fSeek = HB_FALSE;
#  if defined( HB_USE_LARGEFILE64 )
   struct stat64 statbuf;
#  else
   struct stat statbuf;
#  endif
#endif
   HB_BOOL fShared, fReadonly;
   HB_FHANDLE hFile;
   char * pszFile;

   HB_SYMBOL_UNUSED( pFuncs );

   fShared = ( uiExFlags & ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ) ) == 0;
   fReadonly = ( uiExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) ) == FO_READ;
   pszFile = hb_fsExtName( pszFileName, pDefExt, uiExFlags, pPaths );

   hb_vmUnlock();
#if defined( HB_OS_UNIX )
#  if defined( HB_USE_LARGEFILE64 )
   fResult = stat64( ( char * ) pszFile, &statbuf ) == 0;
#  else
   fResult = stat( ( char * ) pszFile, &statbuf ) == 0;
#  endif
   hb_fsSetIOError( fResult, 0 );

   if( fResult )
   {
      hb_threadEnterCriticalSection( &s_fileMtx );
      pFile = hb_fileFind( statbuf.st_dev, statbuf.st_ino );
      if( pFile )
      {
         if( ! fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 )
            fResult = HB_FALSE;
         else if( ! fReadonly && pFile->readonly )
            pFile = NULL;
         else
            pFile->used++;

         if( ( uiExFlags & FXO_NOSEEKPOS ) == 0 )
         {
#  if defined( HB_OS_VXWORKS )
            fSeek  = ! S_ISFIFO( statbuf.st_mode );
#  else
            fSeek  = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode );
#  endif
         }
      }
      hb_threadLeaveCriticalSection( &s_fileMtx );
   }

   if( pFile )
   {
      if( ! fResult )
      {
         hb_fsSetError( ( uiExFlags & FXO_TRUNCATE ) ? 5 : 32 );
         pFile = NULL;
      }
      else if( uiExFlags & FXO_COPYNAME )
         hb_strncpy( ( char * ) pszFileName, pszFile, HB_PATH_MAX - 1 );

      if( pError )
      {
         hb_errPutFileName( pError, pszFile );
         if( ! fResult )
         {
            hb_errPutOsCode( pError, hb_fsError() );
            hb_errPutGenCode( pError, ( HB_ERRCODE ) ( ( uiExFlags & FXO_TRUNCATE ) ? EG_CREATE : EG_OPEN ) );
         }
      }
   }
   else
#endif
   {
      hFile = hb_fsExtOpen( pszFileName, pDefExt, uiExFlags, pPaths, pError );
      if( hFile != FS_ERROR )
      {
         HB_ULONG device = 0, inode = 0;
#if defined( HB_OS_UNIX )
#  if defined( HB_USE_LARGEFILE64 )
         if( fstat64( hFile, &statbuf ) == 0 )
#  else
         if( fstat( hFile, &statbuf ) == 0 )
#  endif
         {
            device = ( HB_ULONG ) statbuf.st_dev;
            inode  = ( HB_ULONG ) statbuf.st_ino;
            if( ( uiExFlags & FXO_NOSEEKPOS ) == 0 )
            {
#  if defined( HB_OS_VXWORKS )
               fSeek  = ! S_ISFIFO( statbuf.st_mode );
#  else
               fSeek  = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode );
#  endif
            }
         }
#endif

         hb_threadEnterCriticalSection( &s_fileMtx );
         pFile = hb_fileNew( hFile, fShared, fReadonly, device, inode, HB_TRUE );
         if( pFile->hFile != hFile )
         {
            if( pFile->hFileRO == FS_ERROR && ! fReadonly && pFile->readonly )
            {
               pFile->hFileRO = pFile->hFile;
               pFile->hFile = hFile;
               pFile->readonly = HB_FALSE;
               hFile = FS_ERROR;
            }
            if( pFile->uiLocks == 0 )
            {
#if ! defined( HB_USE_SHARELOCKS ) || defined( HB_USE_BSDLOCKS )
               if( pFile->hFileRO != FS_ERROR )
               {
                  hb_fsClose( pFile->hFileRO );
                  pFile->hFileRO = FS_ERROR;
               }
#endif
               if( hFile != FS_ERROR )
               {
                  hb_fsClose( hFile );
                  hFile = FS_ERROR;
#if defined( HB_USE_SHARELOCKS ) && ! defined( HB_USE_BSDLOCKS )
                  /* TOFIX: possible race condition */
                  hb_fsLockLarge( hFile, HB_SHARELOCK_POS, HB_SHARELOCK_SIZE,
                                  FL_LOCK | FLX_SHARED );
#endif
               }
            }
         }
         else
            hFile = FS_ERROR;
         hb_threadLeaveCriticalSection( &s_fileMtx );

         if( hFile != FS_ERROR )
         {
            /* TOFIX: possible race condition in MT mode,
             *        close() is not safe due to existing locks
             *        which are removed.
             */
            hb_fsClose( hFile );
         }
      }
   }
   hb_xfree( pszFile );

#if defined( HB_OS_UNIX )
   if( pFile && fSeek )
      pFile = hb_fileposNew( pFile );

#endif
   hb_vmLock();

   return pFile;
}
示例#3
0
文件: filebuf.c 项目: culikr/core
static PHB_FILE s_fileExtOpen( PHB_FILE_FUNCS pFuncs, const char * pszFileName, const char * pDefExt,
                               HB_FATTR nExFlags, const char * pPaths,
                               PHB_ITEM pError )
{
   PHB_FILE pFile = NULL;
#if defined( HB_OS_UNIX )
   HB_BOOL fSeek = HB_FALSE;
#  if defined( HB_USE_LARGEFILE64 )
   struct stat64 statbuf;
#  else
   struct stat statbuf;
#  endif
#endif
   HB_BOOL fResult, fShared;
   int iMode;
   HB_FHANDLE hFile;
   char * pszFile;

   HB_SYMBOL_UNUSED( pFuncs );

   fShared = ( nExFlags & ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ) ) == 0;
   iMode = ( int ) ( nExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) );
   pszFile = hb_fsExtName( pszFileName, pDefExt, nExFlags, pPaths );

   hb_vmUnlock();
#if ! defined( HB_OS_UNIX )
   fResult = HB_TRUE;
#else
#  if defined( HB_USE_SHARELOCKS ) && ! defined( HB_USE_BSDLOCKS )
   if( nExFlags & FXO_SHARELOCK )
   {
      if( iMode == FO_WRITE && fShared )
      {
         if( access( ( char * ) pszFile, R_OK ) == 0 ||
             access( ( char * ) pszFile, F_OK ) != 0 )
         {
            nExFlags = ( nExFlags ^ FO_WRITE ) | FO_READWRITE;
            iMode = FO_READWRITE;
         }
         else
            nExFlags ^= FXO_SHARELOCK;
      }
      else if( iMode == FO_READ && ! fShared )
      {
         nExFlags &= ~ ( HB_FATTR ) ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE );
         fShared = HB_TRUE;
      }
   }
#  endif

   hb_threadEnterCriticalSection( &s_fileMtx );

#  if defined( HB_USE_LARGEFILE64 )
   fResult = stat64( ( char * ) pszFile, &statbuf ) == 0;
#  else
   fResult = stat( ( char * ) pszFile, &statbuf ) == 0;
#  endif
   hb_fsSetIOError( fResult, 0 );

   if( fResult )
   {
      pFile = hb_fileFind( ( HB_ULONG ) statbuf.st_dev,
                           ( HB_ULONG ) statbuf.st_ino );
      if( pFile )
      {
         if( ! fShared || ! pFile->shared || ( nExFlags & FXO_TRUNCATE ) != 0 )
         {
            fResult = HB_FALSE;
            pFile = NULL;
         }
         else if( pFile->mode != FO_READWRITE && pFile->mode != iMode )
         {
            iMode = FO_READWRITE;
            pFile = NULL;
         }
         else
         {
            pFile->used++;
            if( ( nExFlags & FXO_NOSEEKPOS ) == 0 )
            {
#  if defined( HB_OS_VXWORKS )
               fSeek  = ! S_ISFIFO( statbuf.st_mode );
#  else
               fSeek  = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode );
#  endif
            }
         }
      }
   }
   else
      fResult = HB_TRUE;

   if( fResult && pFile == NULL )
#endif /* HB_OS_UNIX */
   {
      hFile = hb_fsExtOpen( pszFile, NULL,
                            nExFlags & ~ ( HB_FATTR ) ( FXO_DEFAULTS | FXO_COPYNAME ),
                            NULL, NULL );
      if( hFile != FS_ERROR )
      {
         HB_ULONG device = 0, inode = 0;
#if ! defined( HB_OS_UNIX )
         hb_threadEnterCriticalSection( &s_fileMtx );
#else
#  if defined( HB_USE_LARGEFILE64 )
         if( fstat64( hFile, &statbuf ) == 0 )
#  else
         if( fstat( hFile, &statbuf ) == 0 )
#  endif
         {
            device = ( HB_ULONG ) statbuf.st_dev;
            inode  = ( HB_ULONG ) statbuf.st_ino;
            if( ( nExFlags & FXO_NOSEEKPOS ) == 0 )
            {
#  if defined( HB_OS_VXWORKS )
               fSeek  = ! S_ISFIFO( statbuf.st_mode );
#  else
               fSeek  = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode );
#  endif
            }
         }
#endif /* HB_OS_UNIX */

         pFile = hb_fileNew( hFile, fShared, iMode, device, inode, HB_TRUE );
         if( pFile->hFile != hFile )
         {
            if( pFile->mode != FO_READWRITE && iMode == FO_READWRITE )
            {
               HB_FHANDLE hTemp = pFile->hFileRO;
               pFile->hFileRO = pFile->hFile;
               pFile->hFile = hFile;
               pFile->mode = iMode;
               hFile = hTemp;
            }

            if( ! fShared || ! pFile->shared || pFile->mode != FO_READWRITE )
            {
               fResult = HB_FALSE;
               if( pFile->hFileRO == FS_ERROR && pFile->uiLocks != 0 )
               {
                  pFile->hFileRO = hFile;
                  hFile = FS_ERROR;
               }
            }

            if( pFile->uiLocks == 0 )
            {
#if ! defined( HB_USE_SHARELOCKS ) || defined( HB_USE_BSDLOCKS )
               if( pFile->hFileRO != FS_ERROR )
               {
                  hb_fsClose( pFile->hFileRO );
                  pFile->hFileRO = FS_ERROR;
               }
#endif
               if( hFile != FS_ERROR )
               {
                  hb_fsClose( hFile );
                  hFile = FS_ERROR;
#if defined( HB_USE_SHARELOCKS ) && ! defined( HB_USE_BSDLOCKS )
                  /* TOFIX: possible race condition */
                  hb_fsLockLarge( pFile->hFile, HB_SHARELOCK_POS, HB_SHARELOCK_SIZE,
                                  FL_LOCK | FLX_SHARED );
#endif
               }
            }
            if( !fResult )
            {
               if( pFile )
               {
                  --pFile->used;
                  pFile = NULL;
               }
               if( hFile != FS_ERROR )
               {
                  /* TOFIX: possible race condition in MT mode,
                   *        close() is not safe due to existing locks
                   *        which are removed.
                   */
                  hb_fsClose( hFile );
               }
            }
         }
#if ! defined( HB_OS_UNIX )
         hb_threadLeaveCriticalSection( &s_fileMtx );
#endif
      }
   }

#if defined( HB_OS_UNIX )
   hb_threadLeaveCriticalSection( &s_fileMtx );
   if( pFile && fSeek )
      pFile = hb_fileposNew( pFile );
#endif

   if( ! fResult )
      hb_fsSetError( ( nExFlags & FXO_TRUNCATE ) ? 5 : 32 );
   if( ( nExFlags & FXO_COPYNAME ) != 0 && pFile )
      hb_strncpy( ( char * ) HB_UNCONST( pszFileName ), pszFile, HB_PATH_MAX - 1 );
   if( pError )
   {
      hb_errPutFileName( pError, pszFile );
      if( ! fResult )
      {
         hb_errPutOsCode( pError, hb_fsError() );
         hb_errPutGenCode( pError, ( HB_ERRCODE ) ( ( nExFlags & FXO_TRUNCATE ) ? EG_CREATE : EG_OPEN ) );
      }
   }

   hb_xfree( pszFile );

   hb_vmLock();

   return pFile;
}