LCOV - code coverage report
Current view: top level - tools/source/stream - strmunx.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 151 232 65.1 %
Date: 2015-06-13 12:38:46 Functions: 20 25 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <stdio.h>
      21             : #include <string.h>
      22             : #include <sys/stat.h>
      23             : #include <fcntl.h>
      24             : #include <errno.h>
      25             : #include <unistd.h>
      26             : #include <limits.h>
      27             : 
      28             : #include <tools/stream.hxx>
      29             : #include <vector>
      30             : 
      31             : #include <osl/mutex.hxx>
      32             : #include <osl/thread.h>
      33             : #include <sal/log.hxx>
      34             : 
      35             : // class FileBase
      36             : #include <osl/file.hxx>
      37             : #include <osl/detail/file.h>
      38             : #include <rtl/instance.hxx>
      39             : #include <rtl/strbuf.hxx>
      40             : 
      41             : using namespace osl;
      42             : 
      43             : // InternalLock ----------------------------------------------------------------
      44             : 
      45             : namespace {
      46             : 
      47             : struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {};
      48             : 
      49           0 : struct InternalStreamLock
      50             : {
      51             :     sal_Size           m_nStartPos;
      52             :     sal_Size           m_nEndPos;
      53             :     SvFileStream*      m_pStream;
      54             :     osl::DirectoryItem m_aItem;
      55             : 
      56             :     InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
      57             :     ~InternalStreamLock();
      58             : };
      59             : 
      60             : struct LockList : public rtl::Static< std::vector<InternalStreamLock>, LockList > {};
      61             : 
      62           0 : InternalStreamLock::InternalStreamLock(
      63             :     sal_Size nStart,
      64             :     sal_Size nEnd,
      65             :     SvFileStream* pStream ) :
      66             :         m_nStartPos( nStart ),
      67             :         m_nEndPos( nEnd ),
      68           0 :         m_pStream( pStream )
      69             : {
      70           0 :     osl::DirectoryItem::get( m_pStream->GetFileName(), m_aItem );
      71             : #if OSL_DEBUG_LEVEL > 1
      72             :     OString aFileName(OUStringToOString(m_pStream->GetFileName(),
      73             :                                                   osl_getThreadTextEncoding()));
      74             :     fprintf( stderr, "locked %s", aFileName.getStr() );
      75             :     if( m_nStartPos || m_nEndPos )
      76             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
      77             :     fprintf( stderr, "\n" );
      78             : #endif
      79           0 : }
      80             : 
      81           0 : InternalStreamLock::~InternalStreamLock()
      82             : {
      83             : #if OSL_DEBUG_LEVEL > 1
      84             :     OString aFileName(OUStringToOString(m_pStream->GetFileName(),
      85             :                                                   osl_getThreadTextEncoding()));
      86             :     fprintf( stderr, "unlocked %s", aFileName.getStr() );
      87             :     if( m_nStartPos || m_nEndPos )
      88             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
      89             :     fprintf( stderr, "\n" );
      90             : #endif
      91           0 : }
      92             : 
      93        5775 : bool lockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
      94             : {
      95        5775 :     osl::DirectoryItem aItem;
      96        5775 :     if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
      97             :     {
      98             :         SAL_INFO("tools.stream", "Failed to lookup stream for locking");
      99        5775 :         return true;
     100             :     }
     101             : 
     102           0 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
     103           0 :     if ( aItem.getFileStatus( aStatus ) != osl::FileBase::E_None )
     104             :     {
     105             :         SAL_INFO("tools.stream", "Failed to stat stream for locking");
     106           0 :         return true;
     107             :     }
     108           0 :     if( aStatus.getFileType() == osl::FileStatus::Directory )
     109           0 :         return true;
     110             : 
     111           0 :     osl::MutexGuard aGuard( LockMutex::get() );
     112           0 :     std::vector<InternalStreamLock> &rLockList = LockList::get();
     113           0 :     for( std::vector<InternalStreamLock>::const_iterator i = rLockList.begin();
     114           0 :          i != rLockList.end(); )
     115             :     {
     116           0 :         if( aItem.isIdenticalTo( i->m_aItem ) )
     117             :         {
     118           0 :             bool bDenyByOptions = false;
     119           0 :             StreamMode nLockMode = i->m_pStream->GetStreamMode();
     120           0 :             StreamMode nNewMode = pStream->GetStreamMode();
     121             : 
     122           0 :             if( nLockMode & StreamMode::SHARE_DENYALL )
     123           0 :                 bDenyByOptions = true;
     124           0 :             else if( ( nLockMode & StreamMode::SHARE_DENYWRITE ) &&
     125           0 :                      ( nNewMode & StreamMode::WRITE ) )
     126           0 :                 bDenyByOptions = true;
     127           0 :             else if( ( nLockMode &StreamMode::SHARE_DENYREAD ) &&
     128           0 :                      ( nNewMode & StreamMode::READ ) )
     129           0 :                 bDenyByOptions = true;
     130             : 
     131           0 :             if( bDenyByOptions )
     132             :             {
     133           0 :                 if( i->m_nStartPos == 0 && i->m_nEndPos == 0 ) // whole file is already locked
     134           0 :                     return false;
     135           0 :                 if( nStart == 0 && nEnd == 0) // cannot lock whole file
     136           0 :                     return false;
     137             : 
     138           0 :                 if( ( nStart < i->m_nStartPos && nEnd > i->m_nStartPos ) ||
     139           0 :                     ( nStart < i->m_nEndPos && nEnd > i->m_nEndPos ) )
     140           0 :                     return false;
     141             :             }
     142             :         }
     143             :     }
     144           0 :     rLockList.push_back( InternalStreamLock( nStart, nEnd, pStream ) );
     145        5775 :     return true;
     146             : }
     147             : 
     148       20892 : void unlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     149             : {
     150       20892 :     osl::MutexGuard aGuard( LockMutex::get() );
     151       20892 :     std::vector<InternalStreamLock> &rLockList = LockList::get();
     152       62676 :     for( std::vector<InternalStreamLock>::iterator i = rLockList.begin();
     153       41784 :          i != rLockList.end(); )
     154             :     {
     155           0 :         if ( i->m_pStream == pStream
     156           0 :              && ( ( nStart == 0 && nEnd == 0 )
     157           0 :                   || ( i->m_nStartPos == nStart && i->m_nEndPos == nEnd ) ) )
     158             :         {
     159           0 :             i = rLockList.erase(i);
     160             :         }
     161             :         else
     162             :         {
     163           0 :             ++i;
     164             :         }
     165       20892 :     }
     166       20892 : }
     167             : 
     168             : }
     169             : 
     170             : // StreamData ------------------------------------------------------------------
     171             : 
     172             : class StreamData
     173             : {
     174             : public:
     175             :     oslFileHandle rHandle;
     176             : 
     177       11542 :     StreamData() : rHandle( 0 ) { }
     178             : };
     179             : 
     180           0 : static sal_uInt32 GetSvError( int nErrno )
     181             : {
     182             :     static struct { int nErr; sal_uInt32 sv; } errArr[] =
     183             :     {
     184             :         { 0,            SVSTREAM_OK },
     185             :         { EACCES,       SVSTREAM_ACCESS_DENIED },
     186             :         { EBADF,        SVSTREAM_INVALID_HANDLE },
     187             : #if defined(NETBSD) || \
     188             :     defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
     189             :     defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
     190             :     defined(IOS)
     191             :         { EDEADLK,      SVSTREAM_LOCKING_VIOLATION },
     192             : #else
     193             :         { EDEADLOCK,    SVSTREAM_LOCKING_VIOLATION },
     194             : #endif
     195             :         { EINVAL,       SVSTREAM_INVALID_PARAMETER },
     196             :         { EMFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     197             :         { ENFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     198             :         { ENOENT,       SVSTREAM_FILE_NOT_FOUND },
     199             :         { EPERM,        SVSTREAM_ACCESS_DENIED },
     200             :         { EROFS,        SVSTREAM_ACCESS_DENIED },
     201             :         { EAGAIN,       SVSTREAM_LOCKING_VIOLATION },
     202             :         { EISDIR,       SVSTREAM_PATH_NOT_FOUND },
     203             :         { ELOOP,        SVSTREAM_PATH_NOT_FOUND },
     204             : #if !defined(NETBSD) && !defined (FREEBSD) && \
     205             :     !defined(MACOSX) && !defined(OPENBSD) && !defined(__FreeBSD_kernel__) && \
     206             :     !defined(DRAGONFLY)
     207             :         { EMULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     208             :         { ENOLINK,      SVSTREAM_PATH_NOT_FOUND },
     209             : #endif
     210             :         { ENOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     211             :         { ETXTBSY,      SVSTREAM_ACCESS_DENIED  },
     212             :         { EEXIST,       SVSTREAM_CANNOT_MAKE    },
     213             :         { ENOSPC,       SVSTREAM_DISK_FULL      },
     214             :         { (int)0xFFFF,  SVSTREAM_GENERALERROR }
     215             :     };
     216             : 
     217           0 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     218           0 :     int i=0;
     219           0 :     do
     220             :     {
     221           0 :         if ( errArr[i].nErr == nErrno )
     222             :         {
     223           0 :             nRetVal = errArr[i].sv;
     224           0 :             break;
     225             :         }
     226           0 :         ++i;
     227             :     }
     228           0 :     while( errArr[i].nErr != 0xFFFF );
     229           0 :     return nRetVal;
     230             : }
     231             : 
     232        1773 : static sal_uInt32 GetSvError( oslFileError nErrno )
     233             : {
     234             :     static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
     235             :     {
     236             :         { osl_File_E_None,        SVSTREAM_OK },
     237             :         { osl_File_E_ACCES,       SVSTREAM_ACCESS_DENIED },
     238             :         { osl_File_E_BADF,        SVSTREAM_INVALID_HANDLE },
     239             :         { osl_File_E_DEADLK,      SVSTREAM_LOCKING_VIOLATION },
     240             :         { osl_File_E_INVAL,       SVSTREAM_INVALID_PARAMETER },
     241             :         { osl_File_E_MFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     242             :         { osl_File_E_NFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     243             :         { osl_File_E_NOENT,       SVSTREAM_FILE_NOT_FOUND },
     244             :         { osl_File_E_PERM,        SVSTREAM_ACCESS_DENIED },
     245             :         { osl_File_E_ROFS,        SVSTREAM_ACCESS_DENIED },
     246             :         { osl_File_E_AGAIN,       SVSTREAM_LOCKING_VIOLATION },
     247             :         { osl_File_E_ISDIR,       SVSTREAM_PATH_NOT_FOUND },
     248             :         { osl_File_E_LOOP,        SVSTREAM_PATH_NOT_FOUND },
     249             :         { osl_File_E_MULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     250             :         { osl_File_E_NOLINK,      SVSTREAM_PATH_NOT_FOUND },
     251             :         { osl_File_E_NOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     252             :         { osl_File_E_EXIST,       SVSTREAM_CANNOT_MAKE    },
     253             :         { osl_File_E_NOSPC,       SVSTREAM_DISK_FULL      },
     254             :         { (oslFileError)0xFFFF,   SVSTREAM_GENERALERROR }
     255             :     };
     256             : 
     257        1773 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     258        1773 :     int i=0;
     259       12411 :     do
     260             :     {
     261       14184 :         if ( errArr[i].nErr == nErrno )
     262             :         {
     263        1773 :             nRetVal = errArr[i].sv;
     264        1773 :             break;
     265             :         }
     266       12411 :         ++i;
     267             :     }
     268       12411 :     while( errArr[i].nErr != (oslFileError)0xFFFF );
     269        1773 :     return nRetVal;
     270             : }
     271             : 
     272       11109 : SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nOpenMode )
     273             : {
     274       11109 :     bIsOpen             = false;
     275       11109 :     nLockCounter        = 0;
     276       11109 :     bIsWritable         = false;
     277       11109 :     pInstanceData       = new StreamData;
     278             : 
     279       11109 :     SetBufferSize( 1024 );
     280             :     // convert URL to SystemPath, if necessary
     281       11109 :     OUString aSystemFileName;
     282       11109 :     if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
     283             :         != FileBase::E_None )
     284             :     {
     285        7785 :         aSystemFileName = rFileName;
     286             :     }
     287       11109 :     Open( aSystemFileName, nOpenMode );
     288       11109 : }
     289             : 
     290         433 : SvFileStream::SvFileStream()
     291             : {
     292         433 :     bIsOpen             = false;
     293         433 :     nLockCounter        = 0;
     294         433 :     bIsWritable         = false;
     295         433 :     pInstanceData       = new StreamData;
     296         433 :     SetBufferSize( 1024 );
     297         433 : }
     298             : 
     299       32577 : SvFileStream::~SvFileStream()
     300             : {
     301       11520 :     Close();
     302             : 
     303       11520 :     unlockFile( 0, 0, this );
     304             : 
     305       11520 :     if (pInstanceData)
     306       11520 :         delete pInstanceData;
     307       21057 : }
     308             : 
     309    10173212 : sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
     310             : {
     311             : #ifdef DBG_UTIL
     312             :     OStringBuffer aTraceStr("SvFileStream::GetData(): ");
     313             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     314             :     aTraceStr.append(" Bytes from ");
     315             :     aTraceStr.append(OUStringToOString(aFilename,
     316             :         osl_getThreadTextEncoding()));
     317             :     OSL_TRACE("%s", aTraceStr.getStr());
     318             : #endif
     319             : 
     320    10173212 :     sal_uInt64 nRead = 0;
     321    10173212 :     if ( IsOpen() )
     322             :     {
     323    10173212 :         oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
     324    10173212 :         if ( rc != osl_File_E_None )
     325             :         {
     326           0 :             SetError( ::GetSvError( rc ));
     327           0 :             return -1;
     328             :         }
     329             :     }
     330    10173212 :     return (sal_Size)nRead;
     331             : }
     332             : 
     333      110769 : sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
     334             : {
     335             : #ifdef DBG_UTIL
     336             :     OStringBuffer aTraceStr("SvFileStream::PutData(): ");
     337             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     338             :     aTraceStr.append(" Bytes to ");
     339             :     aTraceStr.append(OUStringToOString(aFilename,
     340             :         osl_getThreadTextEncoding()));
     341             :     OSL_TRACE("%s", aTraceStr.getStr());
     342             : #endif
     343             : 
     344      110769 :     sal_uInt64 nWrite = 0;
     345      110769 :     if ( IsOpen() )
     346             :     {
     347      110769 :         oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
     348      110769 :         if ( rc != osl_File_E_None )
     349             :         {
     350           0 :             SetError( ::GetSvError( rc ) );
     351           0 :             return -1;
     352             :         }
     353      110769 :         else if( !nWrite )
     354           0 :             SetError( SVSTREAM_DISK_FULL );
     355             :     }
     356      110769 :     return (sal_Size)nWrite;
     357             : }
     358             : 
     359    10325753 : sal_uInt64 SvFileStream::SeekPos(sal_uInt64 const nPos)
     360             : {
     361             :     // check if a truncated STREAM_SEEK_TO_END was passed
     362             :     assert(nPos != (sal_uInt64)(sal_uInt32)STREAM_SEEK_TO_END);
     363    10325753 :     if ( IsOpen() )
     364             :     {
     365             :         oslFileError rc;
     366             :         sal_uInt64 nNewPos;
     367    10325753 :         if ( nPos != STREAM_SEEK_TO_END )
     368    10321373 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
     369             :         else
     370        4380 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
     371             : 
     372    10325753 :         if ( rc != osl_File_E_None )
     373             :         {
     374           0 :             SetError( SVSTREAM_SEEK_ERROR );
     375           0 :             return 0L;
     376             :         }
     377    10325753 :         if ( nPos != STREAM_SEEK_TO_END )
     378    10321373 :             return nPos;
     379        4380 :         rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
     380        4380 :         return (sal_Size) nNewPos;
     381             :     }
     382           0 :     SetError( SVSTREAM_GENERALERROR );
     383           0 :     return 0L;
     384             : }
     385             : 
     386        8067 : void SvFileStream::FlushData()
     387             : {
     388             :     // does not exist locally
     389        8067 : }
     390             : 
     391        9394 : bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     392             : {
     393        9394 :     int nLockMode = 0;
     394             : 
     395        9394 :     if ( ! IsOpen() )
     396           0 :         return false;
     397             : 
     398        9394 :     if ( eStreamMode & StreamMode::SHARE_DENYALL )
     399             :         {
     400        5774 :         if (bIsWritable)
     401        5774 :             nLockMode = F_WRLCK;
     402             :         else
     403           0 :             nLockMode = F_RDLCK;
     404             :         }
     405             : 
     406        9394 :     if ( eStreamMode & StreamMode::SHARE_DENYREAD )
     407             :         {
     408           0 :         if (bIsWritable)
     409           0 :             nLockMode = F_WRLCK;
     410             :         else
     411             :         {
     412           0 :             SetError(SVSTREAM_LOCKING_VIOLATION);
     413           0 :             return false;
     414             :         }
     415             :         }
     416             : 
     417        9394 :     if ( eStreamMode & StreamMode::SHARE_DENYWRITE )
     418             :         {
     419        1993 :         if (bIsWritable)
     420           1 :             nLockMode = F_WRLCK;
     421             :         else
     422        1992 :             nLockMode = F_RDLCK;
     423             :         }
     424             : 
     425        9394 :     if (!nLockMode)
     426        3619 :         return true;
     427             : 
     428        5775 :     if( !lockFile( nByteOffset, nByteOffset+nBytes, this ) )
     429             :     {
     430             : #if OSL_DEBUG_LEVEL > 1
     431             :         fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
     432             :                  OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
     433             : #endif
     434           0 :         return false;
     435             :     }
     436             : 
     437        5775 :     return true;
     438             : }
     439             : 
     440       22709 : bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     441             : {
     442       22709 :     if ( ! IsOpen() )
     443       13337 :         return false;
     444             : 
     445        9372 :     unlockFile( nByteOffset, nByteOffset+nBytes, this );
     446             : 
     447        9372 :     return true;
     448             : }
     449             : 
     450        9394 : bool SvFileStream::LockFile()
     451             : {
     452        9394 :   return LockRange( 0UL, 0UL );
     453             : }
     454             : 
     455       22709 : bool SvFileStream::UnlockFile()
     456             : {
     457       22709 :     return UnlockRange( 0UL, 0UL );
     458             : }
     459             : 
     460       11167 : void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
     461             : {
     462             :     sal_uInt32 uFlags;
     463             :     oslFileHandle nHandleTmp;
     464             : 
     465       11167 :     Close();
     466       11167 :     errno = 0;
     467       11167 :     eStreamMode = nOpenMode;
     468       11167 :     eStreamMode &= ~StreamMode::TRUNC; // don't truncat on reopen
     469             : 
     470       11167 :     aFilename = rFilename;
     471             : 
     472             : #ifdef DBG_UTIL
     473             :     OString aLocalFilename(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
     474             :     OStringBuffer aTraceStr("SvFileStream::Open(): ");
     475             :     aTraceStr.append(aLocalFilename);
     476             :     OSL_TRACE( "%s", aTraceStr.getStr() );
     477             : #endif
     478             : 
     479       11167 :     OUString aFileURL;
     480       22334 :     osl::DirectoryItem aItem;
     481       22334 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
     482             : 
     483             :     // FIXME: we really need to switch to a pure URL model ...
     484       11167 :     if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
     485           0 :         aFileURL = aFilename;
     486       20495 :     bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
     487       20495 :                         aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
     488             : 
     489             :     // SvFileStream can't open a directory
     490       11167 :     if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
     491             :     {
     492           0 :         SetError( ::GetSvError( EISDIR ) );
     493       11167 :         return;
     494             :     }
     495             : 
     496       11167 :     if ( !( nOpenMode & StreamMode::WRITE ) )
     497        5235 :         uFlags = osl_File_OpenFlag_Read;
     498        5932 :     else if ( !( nOpenMode & StreamMode::READ ) )
     499         114 :         uFlags = osl_File_OpenFlag_Write;
     500             :     else
     501        5818 :         uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
     502             : 
     503             :     // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
     504             :     // Important for Read-Only-Filesystems (e.g,  CDROM)
     505       11167 :     if ( (!( nOpenMode & StreamMode::NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
     506        5932 :         uFlags |= osl_File_OpenFlag_Create;
     507       11167 :     if ( nOpenMode & StreamMode::TRUNC )
     508         138 :         uFlags |= osl_File_OpenFlag_Trunc;
     509             : 
     510       11167 :     uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
     511             : 
     512       11167 :     if ( nOpenMode & StreamMode::WRITE)
     513             :     {
     514        5932 :         if ( nOpenMode & StreamMode::COPY_ON_SYMLINK )
     515             :         {
     516           0 :             if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
     517           0 :                  aStatus.getLinkTargetURL().getLength() > 0 )
     518             :             {
     519             :                 // delete the symbolic link, and replace it with the contents of the link
     520           0 :                 if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
     521             :                 {
     522           0 :                     File::copy( aStatus.getLinkTargetURL(), aFileURL );
     523             : #if OSL_DEBUG_LEVEL > 0
     524             :                     fprintf( stderr,
     525             :                              "Removing link and replacing with file contents (%s) -> (%s).\n",
     526             :                              OUStringToOString( aStatus.getLinkTargetURL(),
     527             :                                                      RTL_TEXTENCODING_UTF8).getStr(),
     528             :                              OUStringToOString( aFileURL,
     529             :                                                      RTL_TEXTENCODING_UTF8).getStr() );
     530             : #endif
     531             :                 }
     532             :             }
     533             :         }
     534             :     }
     535             : 
     536       11167 :     oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     537       11167 :     if ( rc != osl_File_E_None )
     538             :     {
     539        1773 :         if ( uFlags & osl_File_OpenFlag_Write )
     540             :         {
     541             :             // Change to read-only
     542           0 :             uFlags &= ~osl_File_OpenFlag_Write;
     543           0 :             rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     544             :         }
     545             :     }
     546       11167 :     if ( rc == osl_File_E_None )
     547             :     {
     548        9394 :         pInstanceData->rHandle = nHandleTmp;
     549        9394 :         bIsOpen = true;
     550        9394 :         if ( uFlags & osl_File_OpenFlag_Write )
     551        5932 :             bIsWritable = true;
     552             : 
     553        9394 :         if ( !LockFile() ) // whole file
     554             :         {
     555           0 :             rc = osl_closeFile( nHandleTmp );
     556           0 :             bIsOpen = false;
     557           0 :             bIsWritable = false;
     558           0 :             pInstanceData->rHandle = 0;
     559             :         }
     560             :     }
     561             :     else
     562       12940 :         SetError( ::GetSvError( rc ) );
     563             : }
     564             : 
     565       22709 : void SvFileStream::Close()
     566             : {
     567       22709 :     UnlockFile();
     568             : 
     569       22709 :     if ( IsOpen() )
     570             :     {
     571             : #ifdef DBG_UTIL
     572             :         OStringBuffer aTraceStr("SvFileStream::Close(): ");
     573             :         aTraceStr.append(OUStringToOString(aFilename,
     574             :             osl_getThreadTextEncoding()));
     575             :         OSL_TRACE("%s", aTraceStr.getStr());
     576             : #endif
     577             : 
     578        9372 :         Flush();
     579        9372 :         osl_closeFile( pInstanceData->rHandle );
     580        9372 :         pInstanceData->rHandle = 0;
     581             :     }
     582             : 
     583       22709 :     bIsOpen     = false;
     584       22709 :     bIsWritable = false;
     585       22709 :     SvStream::ClearBuffer();
     586       22709 :     SvStream::ClearError();
     587       22709 : }
     588             : 
     589             : /// set filepointer to beginning of file
     590         195 : void SvFileStream::ResetError()
     591             : {
     592         195 :     SvStream::ClearError();
     593         195 : }
     594             : 
     595         552 : void SvFileStream::SetSize (sal_uInt64 const nSize)
     596             : {
     597         552 :     if (IsOpen())
     598             :     {
     599         552 :         oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
     600         552 :         if (rc != osl_File_E_None )
     601             :         {
     602           0 :             SetError ( ::GetSvError( rc ));
     603             :         }
     604             :     }
     605         552 : }
     606             : 
     607             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11