LCOV - code coverage report
Current view: top level - tools/source/stream - strmunx.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 148 230 64.3 %
Date: 2014-04-11 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/debug.hxx>
      29             : #include <tools/stream.hxx>
      30             : #include <vector>
      31             : 
      32             : #include <osl/mutex.hxx>
      33             : #include <osl/thread.h>
      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         441 : bool lockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
      94             : {
      95         441 :     osl::DirectoryItem aItem;
      96         441 :     if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
      97             :     {
      98             :         SAL_INFO("tools.stream", "Failed to lookup stream for locking");
      99         441 :         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 & STREAM_SHARE_DENYALL )
     123           0 :                 bDenyByOptions = true;
     124           0 :             else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
     125           0 :                      ( nNewMode & STREAM_WRITE ) )
     126           0 :                 bDenyByOptions = true;
     127           0 :             else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
     128           0 :                      ( nNewMode & STREAM_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         441 :     return true;
     146             : }
     147             : 
     148        7242 : void unlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     149             : {
     150        7242 :     osl::MutexGuard aGuard( LockMutex::get() );
     151        7242 :     std::vector<InternalStreamLock> &rLockList = LockList::get();
     152       21726 :     for( std::vector<InternalStreamLock>::iterator i = rLockList.begin();
     153       14484 :          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        7242 :     }
     166        7242 : }
     167             : 
     168             : }
     169             : 
     170             : // StreamData ------------------------------------------------------------------
     171             : 
     172             : class StreamData
     173             : {
     174             : public:
     175             :     oslFileHandle rHandle;
     176             : 
     177        4757 :     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(RS6000) || 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(RS6000) && !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        1123 : 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        1123 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     258        1123 :     int i=0;
     259        7861 :     do
     260             :     {
     261        8984 :         if ( errArr[i].nErr == nErrno )
     262             :         {
     263        1123 :             nRetVal = errArr[i].sv;
     264        1123 :             break;
     265             :         }
     266        7861 :         ++i;
     267             :     }
     268        7861 :     while( errArr[i].nErr != (oslFileError)0xFFFF );
     269        1123 :     return nRetVal;
     270             : }
     271             : 
     272        4502 : SvFileStream::SvFileStream( const OUString& rFileName, StreamMode nOpenMode )
     273             : {
     274        4502 :     bIsOpen             = false;
     275        4502 :     nLockCounter        = 0;
     276        4502 :     bIsWritable         = false;
     277        4502 :     pInstanceData       = new StreamData;
     278             : 
     279        4502 :     SetBufferSize( 1024 );
     280             :     // convert URL to SystemPath, if necessary
     281        4502 :     OUString aSystemFileName;
     282        4502 :     if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
     283             :         != FileBase::E_None )
     284             :     {
     285        2057 :         aSystemFileName = rFileName;
     286             :     }
     287        4502 :     Open( aSystemFileName, nOpenMode );
     288        4502 : }
     289             : 
     290         255 : SvFileStream::SvFileStream()
     291             : {
     292         255 :     bIsOpen             = false;
     293         255 :     nLockCounter        = 0;
     294         255 :     bIsWritable         = false;
     295         255 :     pInstanceData       = new StreamData;
     296         255 :     SetBufferSize( 1024 );
     297         255 : }
     298             : 
     299       11629 : SvFileStream::~SvFileStream()
     300             : {
     301        4292 :     Close();
     302             : 
     303        4292 :     unlockFile( 0, 0, this );
     304             : 
     305        4292 :     if (pInstanceData)
     306        4292 :         delete pInstanceData;
     307        7337 : }
     308             : 
     309      135419 : 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      135419 :     sal_uInt64 nRead = 0;
     321      135419 :     if ( IsOpen() )
     322             :     {
     323      135419 :         oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
     324      135419 :         if ( rc != osl_File_E_None )
     325             :         {
     326           0 :             SetError( ::GetSvError( rc ));
     327           0 :             return -1;
     328             :         }
     329             :     }
     330      135419 :     return (sal_Size)nRead;
     331             : }
     332             : 
     333       21505 : 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       21505 :     sal_uInt64 nWrite = 0;
     345       21505 :     if ( IsOpen() )
     346             :     {
     347       21505 :         oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
     348       21505 :         if ( rc != osl_File_E_None )
     349             :         {
     350           0 :             SetError( ::GetSvError( rc ) );
     351           0 :             return -1;
     352             :         }
     353       21505 :         else if( !nWrite )
     354           0 :             SetError( SVSTREAM_DISK_FULL );
     355             :     }
     356       21505 :     return (sal_Size)nWrite;
     357             : }
     358             : 
     359      192315 : 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      192315 :     if ( IsOpen() )
     364             :     {
     365             :         oslFileError rc;
     366             :         sal_uInt64 nNewPos;
     367      192315 :         if ( nPos != STREAM_SEEK_TO_END )
     368      189745 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
     369             :         else
     370        2570 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
     371             : 
     372      192315 :         if ( rc != osl_File_E_None )
     373             :         {
     374           0 :             SetError( SVSTREAM_SEEK_ERROR );
     375           0 :             return 0L;
     376             :         }
     377      192315 :         rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
     378      192315 :         return (sal_Size) nNewPos;
     379             :     }
     380           0 :     SetError( SVSTREAM_GENERALERROR );
     381           0 :     return 0L;
     382             : }
     383             : 
     384        1682 : void SvFileStream::FlushData()
     385             : {
     386             :     // does not exist locally
     387        1682 : }
     388             : 
     389        3415 : bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     390             : {
     391        3415 :     int nLockMode = 0;
     392             : 
     393        3415 :     if ( ! IsOpen() )
     394           0 :         return false;
     395             : 
     396        3415 :     if ( eStreamMode & STREAM_SHARE_DENYALL )
     397             :         {
     398         441 :         if (bIsWritable)
     399         441 :             nLockMode = F_WRLCK;
     400             :         else
     401           0 :             nLockMode = F_RDLCK;
     402             :         }
     403             : 
     404        3415 :     if ( eStreamMode & STREAM_SHARE_DENYREAD )
     405             :         {
     406           0 :         if (bIsWritable)
     407           0 :             nLockMode = F_WRLCK;
     408             :         else
     409             :         {
     410           0 :             SetError(SVSTREAM_LOCKING_VIOLATION);
     411           0 :             return false;
     412             :         }
     413             :         }
     414             : 
     415        3415 :     if ( eStreamMode & STREAM_SHARE_DENYWRITE )
     416             :         {
     417        1714 :         if (bIsWritable)
     418           0 :             nLockMode = F_WRLCK;
     419             :         else
     420        1714 :             nLockMode = F_RDLCK;
     421             :         }
     422             : 
     423        3415 :     if (!nLockMode)
     424        2974 :         return true;
     425             : 
     426         441 :     if( !lockFile( nByteOffset, nByteOffset+nBytes, this ) )
     427             :     {
     428             : #if OSL_DEBUG_LEVEL > 1
     429             :         fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
     430             :                  OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
     431             : #endif
     432           0 :         return false;
     433             :     }
     434             : 
     435         441 :     return true;
     436             : }
     437             : 
     438        8839 : bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     439             : {
     440        8839 :     if ( ! IsOpen() )
     441        5889 :         return false;
     442             : 
     443        2950 :     unlockFile( nByteOffset, nByteOffset+nBytes, this );
     444             : 
     445        2950 :     return true;
     446             : }
     447             : 
     448        3415 : bool SvFileStream::LockFile()
     449             : {
     450        3415 :   return LockRange( 0UL, 0UL );
     451             : }
     452             : 
     453        8839 : bool SvFileStream::UnlockFile()
     454             : {
     455        8839 :     return UnlockRange( 0UL, 0UL );
     456             : }
     457             : 
     458        4538 : void SvFileStream::Open( const OUString& rFilename, StreamMode nOpenMode )
     459             : {
     460             :     sal_uInt32 uFlags;
     461             :     oslFileHandle nHandleTmp;
     462             : 
     463        4538 :     Close();
     464        4538 :     errno = 0;
     465        4538 :     eStreamMode = nOpenMode;
     466        4538 :     eStreamMode &= ~STREAM_TRUNC; // don't truncat on reopen
     467             : 
     468        4538 :     aFilename = rFilename;
     469             : 
     470             : #ifdef DBG_UTIL
     471             :     OString aLocalFilename(OUStringToOString(aFilename, osl_getThreadTextEncoding()));
     472             :     OStringBuffer aTraceStr("SvFileStream::Open(): ");
     473             :     aTraceStr.append(aLocalFilename);
     474             :     OSL_TRACE( "%s", aTraceStr.getStr() );
     475             : #endif
     476             : 
     477        4538 :     OUString aFileURL;
     478        9076 :     osl::DirectoryItem aItem;
     479        9076 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
     480             : 
     481             :     // FIXME: we really need to switch to a pure URL model ...
     482        4538 :     if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
     483           0 :         aFileURL = aFilename;
     484        7899 :     bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
     485        7899 :                         aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
     486             : 
     487             :     // SvFileStream can't open a directory
     488        4538 :     if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
     489             :     {
     490           0 :         SetError( ::GetSvError( EISDIR ) );
     491        4538 :         return;
     492             :     }
     493             : 
     494        4538 :     if ( !( nOpenMode & STREAM_WRITE ) )
     495        3947 :         uFlags = osl_File_OpenFlag_Read;
     496         591 :     else if ( !( nOpenMode & STREAM_READ ) )
     497          93 :         uFlags = osl_File_OpenFlag_Write;
     498             :     else
     499         498 :         uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
     500             : 
     501             :     // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
     502             :     // Important for Read-Only-Filesystems (e.g,  CDROM)
     503        4538 :     if ( (!( nOpenMode & STREAM_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
     504         591 :         uFlags |= osl_File_OpenFlag_Create;
     505        4538 :     if ( nOpenMode & STREAM_TRUNC )
     506         141 :         uFlags |= osl_File_OpenFlag_Trunc;
     507             : 
     508        4538 :     uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
     509             : 
     510        4538 :     if ( nOpenMode & STREAM_WRITE)
     511             :     {
     512         591 :         if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
     513             :         {
     514           0 :             if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
     515           0 :                  aStatus.getLinkTargetURL().getLength() > 0 )
     516             :             {
     517             :                 // delete the symbolic link, and replace it with the contents of the link
     518           0 :                 if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
     519             :                 {
     520           0 :                     File::copy( aStatus.getLinkTargetURL(), aFileURL );
     521             : #if OSL_DEBUG_LEVEL > 0
     522             :                     fprintf( stderr,
     523             :                              "Removing link and replacing with file contents (%s) -> (%s).\n",
     524             :                              OUStringToOString( aStatus.getLinkTargetURL(),
     525             :                                                      RTL_TEXTENCODING_UTF8).getStr(),
     526             :                              OUStringToOString( aFileURL,
     527             :                                                      RTL_TEXTENCODING_UTF8).getStr() );
     528             : #endif
     529             :                 }
     530             :             }
     531             :         }
     532             :     }
     533             : 
     534        4538 :     oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     535        4538 :     if ( rc != osl_File_E_None )
     536             :     {
     537        1123 :         if ( uFlags & osl_File_OpenFlag_Write )
     538             :         {
     539             :             // Change to read-only
     540           0 :             uFlags &= ~osl_File_OpenFlag_Write;
     541           0 :             rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     542             :         }
     543             :     }
     544        4538 :     if ( rc == osl_File_E_None )
     545             :     {
     546        3415 :         pInstanceData->rHandle = nHandleTmp;
     547        3415 :         bIsOpen = true;
     548        3415 :         if ( uFlags & osl_File_OpenFlag_Write )
     549         591 :             bIsWritable = true;
     550             : 
     551        3415 :         if ( !LockFile() ) // whole file
     552             :         {
     553           0 :             rc = osl_closeFile( nHandleTmp );
     554           0 :             bIsOpen = false;
     555           0 :             bIsWritable = false;
     556           0 :             pInstanceData->rHandle = 0;
     557             :         }
     558             :     }
     559             :     else
     560        5661 :         SetError( ::GetSvError( rc ) );
     561             : }
     562             : 
     563        8839 : void SvFileStream::Close()
     564             : {
     565        8839 :     UnlockFile();
     566             : 
     567        8839 :     if ( IsOpen() )
     568             :     {
     569             : #ifdef DBG_UTIL
     570             :         OStringBuffer aTraceStr("SvFileStream::Close(): ");
     571             :         aTraceStr.append(OUStringToOString(aFilename,
     572             :             osl_getThreadTextEncoding()));
     573             :         OSL_TRACE("%s", aTraceStr.getStr());
     574             : #endif
     575             : 
     576        2950 :         Flush();
     577        2950 :         osl_closeFile( pInstanceData->rHandle );
     578        2950 :         pInstanceData->rHandle = 0;
     579             :     }
     580             : 
     581        8839 :     bIsOpen     = false;
     582        8839 :     bIsWritable = false;
     583        8839 :     SvStream::ClearBuffer();
     584        8839 :     SvStream::ClearError();
     585        8839 : }
     586             : 
     587             : /// set filepointer to beginning of file
     588          99 : void SvFileStream::ResetError()
     589             : {
     590          99 :     SvStream::ClearError();
     591          99 : }
     592             : 
     593         211 : void SvFileStream::SetSize (sal_uInt64 const nSize)
     594             : {
     595         211 :     if (IsOpen())
     596             :     {
     597         211 :         oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
     598         211 :         if (rc != osl_File_E_None )
     599             :         {
     600           0 :             SetError ( ::GetSvError( rc ));
     601             :         }
     602             :     }
     603         211 : }
     604             : 
     605             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10