LCOV - code coverage report
Current view: top level - libreoffice/tools/source/stream - strmunx.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 147 239 61.5 %
Date: 2012-12-27 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/fsys.hxx>
      30             : #include <tools/stream.hxx>
      31             : #include <vector>
      32             : 
      33             : #include <osl/mutex.hxx>
      34             : #include <osl/thread.h> // osl_getThreadTextEncoding
      35             : 
      36             : // class FileBase
      37             : #include <osl/file.hxx>
      38             : #include <osl/detail/file.h>
      39             : #include <rtl/instance.hxx>
      40             : #include <rtl/strbuf.hxx>
      41             : 
      42             : using namespace osl;
      43             : 
      44             : // InternalLock ----------------------------------------------------------------
      45             : 
      46             : namespace { struct LockMutex : public rtl::Static< osl::Mutex, LockMutex > {}; }
      47             : 
      48             : class InternalStreamLock
      49             : {
      50             :     sal_Size           m_nStartPos;
      51             :     sal_Size           m_nEndPos;
      52             :     SvFileStream*      m_pStream;
      53             :     osl::DirectoryItem m_aItem;
      54             : 
      55             :     InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
      56             :     ~InternalStreamLock();
      57             : public:
      58             :     static sal_Bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      59             :     static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
      60             : };
      61             : 
      62             : typedef ::std::vector< InternalStreamLock* > InternalStreamLockList;
      63             : 
      64             : namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
      65             : 
      66           0 : InternalStreamLock::InternalStreamLock(
      67             :     sal_Size nStart,
      68             :     sal_Size nEnd,
      69             :     SvFileStream* pStream ) :
      70             :         m_nStartPos( nStart ),
      71             :         m_nEndPos( nEnd ),
      72           0 :         m_pStream( pStream )
      73             : {
      74           0 :     osl::DirectoryItem::get( m_pStream->GetFileName(), m_aItem );
      75           0 :     LockList::get().push_back( this );
      76             : #if OSL_DEBUG_LEVEL > 1
      77             :     rtl::OString aFileName(rtl::OUStringToOString(m_pStream->GetFileName(),
      78             :                                                   osl_getThreadTextEncoding()));
      79             :     fprintf( stderr, "locked %s", aFileName.getStr() );
      80             :     if( m_nStartPos || m_nEndPos )
      81             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
      82             :     fprintf( stderr, "\n" );
      83             : #endif
      84           0 : }
      85             : 
      86           0 : InternalStreamLock::~InternalStreamLock()
      87             : {
      88           0 :     for ( InternalStreamLockList::iterator it = LockList::get().begin();
      89           0 :           it != LockList::get().end();
      90             :           ++it
      91             :     ) {
      92           0 :         if ( this == *it ) {
      93           0 :             LockList::get().erase( it );
      94           0 :             break;
      95             :         }
      96             :     }
      97             : #if OSL_DEBUG_LEVEL > 1
      98             :     rtl::OString aFileName(rtl::OUStringToOString(m_pStream->GetFileName(),
      99             :                                                   osl_getThreadTextEncoding()));
     100             :     fprintf( stderr, "unlocked %s", aFileName.getStr() );
     101             :     if( m_nStartPos || m_nEndPos )
     102             :         fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos );
     103             :     fprintf( stderr, "\n" );
     104             : #endif
     105           0 : }
     106             : 
     107         684 : sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     108             : {
     109         684 :     osl::MutexGuard aGuard( LockMutex::get() );
     110         684 :     osl::DirectoryItem aItem;
     111         684 :     if (osl::DirectoryItem::get( pStream->GetFileName(), aItem) != osl::FileBase::E_None )
     112             :     {
     113             :         SAL_INFO("tools.stream", "Failed to lookup stream for locking");
     114         684 :         return sal_True;
     115             :     }
     116             : 
     117           0 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type );
     118           0 :     if ( aItem.getFileStatus( aStatus ) != osl::FileBase::E_None )
     119             :     {
     120             :         SAL_INFO("tools.stream", "Failed to stat stream for locking");
     121           0 :         return sal_True;
     122             :     }
     123           0 :     if( aStatus.getFileType() == osl::FileStatus::Directory )
     124           0 :         return sal_True;
     125             : 
     126           0 :     InternalStreamLock* pLock = NULL;
     127           0 :     InternalStreamLockList &rLockList = LockList::get();
     128           0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     129             :     {
     130           0 :         pLock = rLockList[ i ];
     131           0 :         if( aItem.isIdenticalTo( pLock->m_aItem ) )
     132             :         {
     133           0 :             sal_Bool bDenyByOptions = sal_False;
     134           0 :             StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
     135           0 :             StreamMode nNewMode = pStream->GetStreamMode();
     136             : 
     137           0 :             if( nLockMode & STREAM_SHARE_DENYALL )
     138           0 :                 bDenyByOptions = sal_True;
     139           0 :             else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
     140             :                      ( nNewMode & STREAM_WRITE ) )
     141           0 :                 bDenyByOptions = sal_True;
     142           0 :             else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
     143             :                      ( nNewMode & STREAM_READ ) )
     144           0 :                 bDenyByOptions = sal_True;
     145             : 
     146           0 :             if( bDenyByOptions )
     147             :             {
     148           0 :                 if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
     149           0 :                     return sal_False;
     150           0 :                 if( nStart == 0 && nEnd == 0) // cannot lock whole file
     151           0 :                     return sal_False;
     152             : 
     153           0 :                 if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
     154             :                     ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
     155           0 :                     return sal_False;
     156             :             }
     157             :         }
     158             :     }
     159             :     // hint: new InternalStreamLock() adds the entry to the global list
     160           0 :     pLock  = new InternalStreamLock( nStart, nEnd, pStream );
     161           0 :     return sal_True;
     162             : }
     163             : 
     164        4040 : void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
     165             : {
     166        4040 :     osl::MutexGuard aGuard( LockMutex::get() );
     167        4040 :     InternalStreamLock* pLock = NULL;
     168        4040 :     InternalStreamLockList &rLockList = LockList::get();
     169        4040 :     if( nStart == 0 && nEnd == 0 )
     170             :     {
     171             :         // nStart & nEnd = 0, so delete all locks
     172        4040 :         for( size_t i = 0; i < rLockList.size(); ++i )
     173             :         {
     174           0 :             if( ( pLock = rLockList[ i ] )->m_pStream == pStream )
     175             :             {
     176             :                 // hint: delete will remove pLock from the global list
     177           0 :                 delete pLock;
     178           0 :                 i--;
     179             :             }
     180             :         }
     181             :         return;
     182             :     }
     183           0 :     for( size_t i = 0; i < rLockList.size(); ++i )
     184             :     {
     185           0 :         if (  ( pLock = rLockList[ i ] )->m_pStream == pStream
     186             :            && nStart == pLock->m_nStartPos
     187             :            && nEnd == pLock->m_nEndPos
     188             :         ) {
     189             :             // hint: delete will remove pLock from the global list
     190           0 :             delete pLock;
     191             :             return;
     192             :         }
     193        4040 :     }
     194             : }
     195             : 
     196             : // StreamData ------------------------------------------------------------------
     197             : 
     198             : class StreamData
     199             : {
     200             : public:
     201             :     oslFileHandle rHandle;
     202             : 
     203        2261 :     StreamData() : rHandle( 0 ) { }
     204             : };
     205             : 
     206           0 : static sal_uInt32 GetSvError( int nErrno )
     207             : {
     208             :     static struct { int nErr; sal_uInt32 sv; } errArr[] =
     209             :     {
     210             :         { 0,            SVSTREAM_OK },
     211             :         { EACCES,       SVSTREAM_ACCESS_DENIED },
     212             :         { EBADF,        SVSTREAM_INVALID_HANDLE },
     213             : #if defined(RS6000) || defined(NETBSD) || \
     214             :     defined(FREEBSD) || defined(MACOSX) || defined(OPENBSD) || \
     215             :     defined(__FreeBSD_kernel__) || defined (AIX) || defined(DRAGONFLY) || \
     216             :     defined(IOS)
     217             :         { EDEADLK,      SVSTREAM_LOCKING_VIOLATION },
     218             : #else
     219             :         { EDEADLOCK,    SVSTREAM_LOCKING_VIOLATION },
     220             : #endif
     221             :         { EINVAL,       SVSTREAM_INVALID_PARAMETER },
     222             :         { EMFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     223             :         { ENFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     224             :         { ENOENT,       SVSTREAM_FILE_NOT_FOUND },
     225             :         { EPERM,        SVSTREAM_ACCESS_DENIED },
     226             :         { EROFS,        SVSTREAM_ACCESS_DENIED },
     227             :         { EAGAIN,       SVSTREAM_LOCKING_VIOLATION },
     228             :         { EISDIR,       SVSTREAM_PATH_NOT_FOUND },
     229             :         { ELOOP,        SVSTREAM_PATH_NOT_FOUND },
     230             : #if !defined(RS6000) && !defined(NETBSD) && !defined (FREEBSD) && \
     231             :     !defined(MACOSX) && !defined(OPENBSD) && !defined(__FreeBSD_kernel__) && \
     232             :     !defined(DRAGONFLY)
     233             :         { EMULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     234             :         { ENOLINK,      SVSTREAM_PATH_NOT_FOUND },
     235             : #endif
     236             :         { ENOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     237             :         { ETXTBSY,      SVSTREAM_ACCESS_DENIED  },
     238             :         { EEXIST,       SVSTREAM_CANNOT_MAKE    },
     239             :         { ENOSPC,       SVSTREAM_DISK_FULL      },
     240             :         { (int)0xFFFF,  SVSTREAM_GENERALERROR }
     241             :     };
     242             : 
     243           0 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     244           0 :     int i=0;
     245           0 :     do
     246             :     {
     247           0 :         if ( errArr[i].nErr == nErrno )
     248             :         {
     249           0 :             nRetVal = errArr[i].sv;
     250           0 :             break;
     251             :         }
     252           0 :         ++i;
     253             :     }
     254             :     while( errArr[i].nErr != 0xFFFF );
     255           0 :     return nRetVal;
     256             : }
     257             : 
     258          51 : static sal_uInt32 GetSvError( oslFileError nErrno )
     259             : {
     260             :     static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
     261             :     {
     262             :         { osl_File_E_None,        SVSTREAM_OK },
     263             :         { osl_File_E_ACCES,       SVSTREAM_ACCESS_DENIED },
     264             :         { osl_File_E_BADF,        SVSTREAM_INVALID_HANDLE },
     265             :         { osl_File_E_DEADLK,      SVSTREAM_LOCKING_VIOLATION },
     266             :         { osl_File_E_INVAL,       SVSTREAM_INVALID_PARAMETER },
     267             :         { osl_File_E_MFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     268             :         { osl_File_E_NFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
     269             :         { osl_File_E_NOENT,       SVSTREAM_FILE_NOT_FOUND },
     270             :         { osl_File_E_PERM,        SVSTREAM_ACCESS_DENIED },
     271             :         { osl_File_E_ROFS,        SVSTREAM_ACCESS_DENIED },
     272             :         { osl_File_E_AGAIN,       SVSTREAM_LOCKING_VIOLATION },
     273             :         { osl_File_E_ISDIR,       SVSTREAM_PATH_NOT_FOUND },
     274             :         { osl_File_E_LOOP,        SVSTREAM_PATH_NOT_FOUND },
     275             :         { osl_File_E_MULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
     276             :         { osl_File_E_NOLINK,      SVSTREAM_PATH_NOT_FOUND },
     277             :         { osl_File_E_NOTDIR,      SVSTREAM_PATH_NOT_FOUND },
     278             :         { osl_File_E_EXIST,       SVSTREAM_CANNOT_MAKE    },
     279             :         { osl_File_E_NOSPC,       SVSTREAM_DISK_FULL      },
     280             :         { (oslFileError)0xFFFF,   SVSTREAM_GENERALERROR }
     281             :     };
     282             : 
     283          51 :     sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // default error
     284          51 :     int i=0;
     285         357 :     do
     286             :     {
     287         408 :         if ( errArr[i].nErr == nErrno )
     288             :         {
     289          51 :             nRetVal = errArr[i].sv;
     290          51 :             break;
     291             :         }
     292         357 :         ++i;
     293             :     }
     294             :     while( errArr[i].nErr != (oslFileError)0xFFFF );
     295          51 :     return nRetVal;
     296             : }
     297             : 
     298        2167 : SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
     299             : {
     300        2167 :     bIsOpen             = sal_False;
     301        2167 :     nLockCounter        = 0;
     302        2167 :     bIsWritable         = sal_False;
     303        2167 :     pInstanceData       = new StreamData;
     304             : 
     305        2167 :     SetBufferSize( 1024 );
     306             :     // convert URL to SystemPath, if necessary
     307        2167 :     ::rtl::OUString aSystemFileName;
     308        2167 :     if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
     309             :         != FileBase::E_None )
     310             :     {
     311         587 :         aSystemFileName = rFileName;
     312             :     }
     313        2167 :     Open( aSystemFileName, nOpenMode );
     314        2167 : }
     315             : 
     316          94 : SvFileStream::SvFileStream()
     317             : {
     318          94 :     bIsOpen             = sal_False;
     319          94 :     nLockCounter        = 0;
     320          94 :     bIsWritable         = sal_False;
     321          94 :     pInstanceData       = new StreamData;
     322          94 :     SetBufferSize( 1024 );
     323          94 : }
     324             : 
     325        4573 : SvFileStream::~SvFileStream()
     326             : {
     327        2092 :     Close();
     328             : 
     329        2092 :     InternalStreamLock::UnlockFile( 0, 0, this );
     330             : 
     331        2092 :     if (pInstanceData)
     332        2092 :         delete pInstanceData;
     333        2481 : }
     334             : 
     335        1260 : sal_uInt32 SvFileStream::GetFileHandle() const
     336             : {
     337             :     sal_IntPtr handle;
     338        1260 :     if (osl_getFileOSHandle(pInstanceData->rHandle, &handle) == osl_File_E_None)
     339        1260 :         return (sal_uInt32) handle;
     340             :     else
     341           0 :         return (sal_uInt32) -1;
     342             : }
     343             : 
     344           0 : sal_uInt16 SvFileStream::IsA() const
     345             : {
     346           0 :     return ID_FILESTREAM;
     347             : }
     348             : 
     349      102706 : sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
     350             : {
     351             : #ifdef DBG_UTIL
     352             :     rtl::OStringBuffer aTraceStr(
     353             :         RTL_CONSTASCII_STRINGPARAM("SvFileStream::GetData(): "));
     354             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     355             :     aTraceStr.append(RTL_CONSTASCII_STRINGPARAM(" Bytes from "));
     356             :     aTraceStr.append(rtl::OUStringToOString(aFilename,
     357             :         osl_getThreadTextEncoding()));
     358             :     OSL_TRACE("%s", aTraceStr.getStr());
     359             : #endif
     360             : 
     361      102706 :     sal_uInt64 nRead = 0;
     362      102706 :     if ( IsOpen() )
     363             :     {
     364      102706 :         oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
     365      102706 :         if ( rc != osl_File_E_None )
     366             :         {
     367           0 :             SetError( ::GetSvError( rc ));
     368           0 :             return -1;
     369             :         }
     370             :     }
     371      102706 :     return (sal_Size)nRead;
     372             : }
     373             : 
     374       16828 : sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
     375             : {
     376             : #ifdef DBG_UTIL
     377             :     rtl::OStringBuffer aTraceStr(
     378             :         RTL_CONSTASCII_STRINGPARAM("SvFileStream::PutData(): "));
     379             :     aTraceStr.append(static_cast<sal_Int64>(nSize));
     380             :     aTraceStr.append(RTL_CONSTASCII_STRINGPARAM(" Bytes to "));
     381             :     aTraceStr.append(rtl::OUStringToOString(aFilename,
     382             :         osl_getThreadTextEncoding()));
     383             :     OSL_TRACE("%s", aTraceStr.getStr());
     384             : #endif
     385             : 
     386       16828 :     sal_uInt64 nWrite = 0;
     387       16828 :     if ( IsOpen() )
     388             :     {
     389       16828 :         oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
     390       16828 :         if ( rc != osl_File_E_None )
     391             :         {
     392           0 :             SetError( ::GetSvError( rc ) );
     393           0 :             return -1;
     394             :         }
     395       16828 :         else if( !nWrite )
     396           0 :             SetError( SVSTREAM_DISK_FULL );
     397             :     }
     398       16828 :     return (sal_Size)nWrite;
     399             : }
     400             : 
     401      133700 : sal_Size SvFileStream::SeekPos( sal_Size nPos )
     402             : {
     403      133700 :     if ( IsOpen() )
     404             :     {
     405             :         oslFileError rc;
     406             :         sal_uInt64 nNewPos;
     407      133700 :         if ( nPos != STREAM_SEEK_TO_END )
     408      133293 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
     409             :         else
     410         407 :             rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
     411             : 
     412      133700 :         if ( rc != osl_File_E_None )
     413             :         {
     414           0 :             SetError( SVSTREAM_SEEK_ERROR );
     415           0 :             return 0L;
     416             :         }
     417      133700 :         rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
     418      133700 :         return (sal_Size) nNewPos;
     419             :     }
     420           0 :     SetError( SVSTREAM_GENERALERROR );
     421           0 :     return 0L;
     422             : }
     423             : 
     424         925 : void SvFileStream::FlushData()
     425             : {
     426             :     // does not exist locally
     427         925 : }
     428             : 
     429        2117 : sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     430             : {
     431        2117 :     int nLockMode = 0;
     432             : 
     433        2117 :     if ( ! IsOpen() )
     434           0 :         return sal_False;
     435             : 
     436        2117 :     if ( eStreamMode & STREAM_SHARE_DENYALL )
     437             :         {
     438          54 :         if (bIsWritable)
     439          54 :             nLockMode = F_WRLCK;
     440             :         else
     441           0 :             nLockMode = F_RDLCK;
     442             :         }
     443             : 
     444        2117 :     if ( eStreamMode & STREAM_SHARE_DENYREAD )
     445             :         {
     446           0 :         if (bIsWritable)
     447           0 :             nLockMode = F_WRLCK;
     448             :         else
     449             :         {
     450           0 :             SetError(SVSTREAM_LOCKING_VIOLATION);
     451           0 :             return sal_False;
     452             :         }
     453             :         }
     454             : 
     455        2117 :     if ( eStreamMode & STREAM_SHARE_DENYWRITE )
     456             :         {
     457         880 :         if (bIsWritable)
     458         630 :             nLockMode = F_WRLCK;
     459             :         else
     460         250 :             nLockMode = F_RDLCK;
     461             :         }
     462             : 
     463        2117 :     if (!nLockMode)
     464        1433 :         return sal_True;
     465             : 
     466         684 :     if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
     467             :     {
     468             : #if OSL_DEBUG_LEVEL > 1
     469             :         fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n",
     470             :                  rtl::OUStringToOString(aFilename, osl_getThreadTextEncoding()).getStr(), nByteOffset, nByteOffset+nBytes );
     471             : #endif
     472           0 :         return sal_False;
     473             :     }
     474             : 
     475         684 :     return sal_True;
     476             : }
     477             : 
     478        4890 : sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     479             : {
     480        4890 :     if ( ! IsOpen() )
     481        2942 :         return sal_False;
     482             : 
     483        1948 :     InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
     484             : 
     485        1948 :     return sal_True;
     486             : }
     487             : 
     488        2117 : sal_Bool SvFileStream::LockFile()
     489             : {
     490        2117 :   return LockRange( 0UL, 0UL );
     491             : }
     492             : 
     493        4890 : sal_Bool SvFileStream::UnlockFile()
     494             : {
     495        4890 :     return UnlockRange( 0UL, 0UL );
     496             : }
     497             : 
     498        2168 : void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
     499             : {
     500             :     sal_uInt32 uFlags;
     501             :     oslFileHandle nHandleTmp;
     502             : 
     503        2168 :     Close();
     504        2168 :     errno = 0;
     505        2168 :     eStreamMode = nOpenMode;
     506        2168 :     eStreamMode &= ~STREAM_TRUNC; // don't truncat on reopen
     507             : 
     508             : //    !!! NoOp: use ToAbs()
     509             : //    !!! DirEntry aDirEntry( rFilename );
     510             : //    !!! aFilename = aDirEntry.GetFull();
     511        2168 :     aFilename = rFilename;
     512        2168 :     rtl::OString aLocalFilename(rtl::OUStringToOString(aFilename, osl_getThreadTextEncoding()));
     513             : 
     514             : #ifdef DBG_UTIL
     515             :     rtl::OStringBuffer aTraceStr(RTL_CONSTASCII_STRINGPARAM(
     516             :         "SvFileStream::Open(): "));
     517             :     aTraceStr.append(aLocalFilename);
     518             :     OSL_TRACE( "%s", aTraceStr.getStr() );
     519             : #endif
     520             : 
     521        2168 :     rtl::OUString aFileURL;
     522        2168 :     osl::DirectoryItem aItem;
     523        2168 :     osl::FileStatus aStatus( osl_FileStatus_Mask_Type | osl_FileStatus_Mask_LinkTargetURL );
     524             : 
     525             :     // FIXME: we really need to switch to a pure URL model ...
     526        2168 :     if ( osl::File::getFileURLFromSystemPath( aFilename, aFileURL ) != osl::FileBase::E_None )
     527           0 :         aFileURL = aFilename;
     528        2168 :     bool bStatValid = ( osl::DirectoryItem::get( aFileURL, aItem) == osl::FileBase::E_None &&
     529        2168 :                         aItem.getFileStatus( aStatus ) == osl::FileBase::E_None );
     530             : 
     531             :     // SvFileStream can't open a directory
     532        2168 :     if( bStatValid && aStatus.getFileType() == osl::FileStatus::Directory )
     533             :     {
     534           0 :         SetError( ::GetSvError( EISDIR ) );
     535        2168 :         return;
     536             :     }
     537             : 
     538        2168 :     if ( !( nOpenMode & STREAM_WRITE ) )
     539        1373 :         uFlags = osl_File_OpenFlag_Read;
     540         795 :     else if ( !( nOpenMode & STREAM_READ ) )
     541         693 :         uFlags = osl_File_OpenFlag_Write;
     542             :     else
     543         102 :         uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
     544             : 
     545             :     // Fix (MDA, 18.01.95): Don't open with O_CREAT upon RD_ONLY
     546             :     // Important for Read-Only-Filesystems (e.g,  CDROM)
     547        2168 :     if ( (!( nOpenMode & STREAM_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
     548         795 :         uFlags |= osl_File_OpenFlag_Create;
     549        2168 :     if ( nOpenMode & STREAM_TRUNC )
     550         741 :         uFlags |= osl_File_OpenFlag_Trunc;
     551             : 
     552        2168 :     uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
     553             : 
     554        2168 :     if ( nOpenMode & STREAM_WRITE)
     555             :     {
     556         795 :         if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
     557             :         {
     558           0 :             if ( bStatValid && aStatus.getFileType() == osl::FileStatus::Link &&
     559           0 :                  aStatus.getLinkTargetURL().getLength() > 0 )
     560             :             {
     561             :                 // delete the symbolic link, and replace it with the contents of the link
     562           0 :                 if (osl::File::remove( aFileURL ) == osl::FileBase::E_None )
     563             :                 {
     564           0 :                     File::copy( aStatus.getLinkTargetURL(), aFileURL );
     565             : #if OSL_DEBUG_LEVEL > 0
     566             :                     fprintf( stderr,
     567             :                              "Removing link and replacing with file contents (%s) -> (%s).\n",
     568             :                              rtl::OUStringToOString( aStatus.getLinkTargetURL(),
     569             :                                                      RTL_TEXTENCODING_UTF8).getStr(),
     570             :                              rtl::OUStringToOString( aFileURL,
     571             :                                                      RTL_TEXTENCODING_UTF8).getStr() );
     572             : #endif
     573             :                 }
     574             :             }
     575             :         }
     576             :     }
     577             : 
     578        2168 :     oslFileError rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     579        2168 :     if ( rc != osl_File_E_None )
     580             :     {
     581          51 :         if ( uFlags & osl_File_OpenFlag_Write )
     582             :         {
     583             :             // Change to read-only
     584           0 :             uFlags &= ~osl_File_OpenFlag_Write;
     585           0 :             rc = osl_openFile( aFileURL.pData, &nHandleTmp, uFlags );
     586             :         }
     587             :     }
     588        2168 :     if ( rc == osl_File_E_None )
     589             :     {
     590        2117 :         pInstanceData->rHandle = nHandleTmp;
     591        2117 :         bIsOpen = sal_True;
     592        2117 :         if ( uFlags & osl_File_OpenFlag_Write )
     593         795 :             bIsWritable = sal_True;
     594             : 
     595        2117 :         if ( !LockFile() ) // whole file
     596             :         {
     597           0 :             rc = osl_closeFile( nHandleTmp );
     598           0 :             bIsOpen = sal_False;
     599           0 :             bIsWritable = sal_False;
     600           0 :             pInstanceData->rHandle = 0;
     601             :         }
     602             :     }
     603             :     else
     604          51 :         SetError( ::GetSvError( rc ) );
     605             : }
     606             : 
     607        4890 : void SvFileStream::Close()
     608             : {
     609        4890 :     UnlockFile();
     610             : 
     611        4890 :     if ( IsOpen() )
     612             :     {
     613             : #ifdef DBG_UTIL
     614             :         rtl::OStringBuffer aTraceStr(
     615             :             RTL_CONSTASCII_STRINGPARAM("SvFileStream::Close(): "));
     616             :         aTraceStr.append(rtl::OUStringToOString(aFilename,
     617             :             osl_getThreadTextEncoding()));
     618             :         OSL_TRACE("%s", aTraceStr.getStr());
     619             : #endif
     620             : 
     621        1948 :         Flush();
     622        1948 :         osl_closeFile( pInstanceData->rHandle );
     623        1948 :         pInstanceData->rHandle = 0;
     624             :     }
     625             : 
     626        4890 :     bIsOpen     = sal_False;
     627        4890 :     bIsWritable = sal_False;
     628        4890 :     SvStream::ClearBuffer();
     629        4890 :     SvStream::ClearError();
     630        4890 : }
     631             : 
     632             : /// set filepointer to beginning of file
     633          32 : void SvFileStream::ResetError()
     634             : {
     635          32 :     SvStream::ClearError();
     636          32 : }
     637             : 
     638           0 : void SvFileStream::SetSize (sal_Size nSize)
     639             : {
     640           0 :     if (IsOpen())
     641             :     {
     642           0 :         oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
     643           0 :         if (rc != osl_File_E_None )
     644             :         {
     645           0 :             SetError ( ::GetSvError( rc ));
     646             :         }
     647             :     }
     648           0 : }
     649             : 
     650             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10