| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // no include "precompiled_tools.hxx" because this file is included in strmsys.cxx |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <unistd.h> |
| #include <limits.h> |
| #include <stdlib.h> // fuer getenv() |
| |
| #include <tools/debug.hxx> |
| #include <tools/fsys.hxx> |
| #include <tools/stream.hxx> |
| |
| #include <vos/mutex.hxx> |
| #include <osl/thread.h> // osl_getThreadTextEncoding |
| |
| // class FileBase |
| #include <osl/file.hxx> |
| #include <rtl/instance.hxx> |
| |
| using namespace osl; |
| |
| // ----------------------------------------------------------------------- |
| |
| // ---------------- |
| // - InternalLock - |
| // ---------------- |
| |
| class InternalStreamLock; |
| DECLARE_LIST( InternalStreamLockList, InternalStreamLock* ) |
| namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; } |
| |
| #ifndef BOOTSTRAP |
| namespace { struct LockMutex : public rtl::Static< vos::OMutex, LockMutex > {}; } |
| #endif |
| |
| class InternalStreamLock |
| { |
| sal_Size m_nStartPos; |
| sal_Size m_nEndPos; |
| SvFileStream* m_pStream; |
| struct stat m_aStat; |
| |
| InternalStreamLock( sal_Size, sal_Size, SvFileStream* ); |
| ~InternalStreamLock(); |
| public: |
| static sal_Bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* ); |
| static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* ); |
| }; |
| |
| InternalStreamLock::InternalStreamLock( |
| sal_Size nStart, |
| sal_Size nEnd, |
| SvFileStream* pStream ) : |
| m_nStartPos( nStart ), |
| m_nEndPos( nEnd ), |
| m_pStream( pStream ) |
| { |
| ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding()); |
| stat( aFileName.GetBuffer(), &m_aStat ); |
| LockList::get().Insert( this, LIST_APPEND ); |
| #if OSL_DEBUG_LEVEL > 1 |
| fprintf( stderr, "locked %s", aFileName.GetBuffer() ); |
| if( m_nStartPos || m_nEndPos ) |
| fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos ); |
| fprintf( stderr, "\n" ); |
| #endif |
| } |
| |
| InternalStreamLock::~InternalStreamLock() |
| { |
| LockList::get().Remove( this ); |
| #if OSL_DEBUG_LEVEL > 1 |
| ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding()); |
| fprintf( stderr, "unlocked %s", aFileName.GetBuffer() ); |
| if( m_nStartPos || m_nEndPos ) |
| fprintf(stderr, " [ %ld ... %ld ]", m_nStartPos, m_nEndPos ); |
| fprintf( stderr, "\n" ); |
| #endif |
| } |
| |
| sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream ) |
| { |
| #ifndef BOOTSTRAP |
| vos:: OGuard aGuard( LockMutex::get() ); |
| #endif |
| ByteString aFileName(pStream->GetFileName(), osl_getThreadTextEncoding()); |
| struct stat aStat; |
| if( stat( aFileName.GetBuffer(), &aStat ) ) |
| return sal_False; |
| |
| if( S_ISDIR( aStat.st_mode ) ) |
| return sal_True; |
| |
| InternalStreamLock* pLock = NULL; |
| InternalStreamLockList &rLockList = LockList::get(); |
| for( sal_uIntPtr i = 0; i < rLockList.Count(); ++i ) |
| { |
| pLock = rLockList.GetObject( i ); |
| if( aStat.st_ino == pLock->m_aStat.st_ino ) |
| { |
| sal_Bool bDenyByOptions = sal_False; |
| StreamMode nLockMode = pLock->m_pStream->GetStreamMode(); |
| StreamMode nNewMode = pStream->GetStreamMode(); |
| |
| if( nLockMode & STREAM_SHARE_DENYALL ) |
| bDenyByOptions = sal_True; |
| else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) && |
| ( nNewMode & STREAM_WRITE ) ) |
| bDenyByOptions = sal_True; |
| else if( ( nLockMode & STREAM_SHARE_DENYREAD ) && |
| ( nNewMode & STREAM_READ ) ) |
| bDenyByOptions = sal_True; |
| |
| if( bDenyByOptions ) |
| { |
| if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked |
| return sal_False; |
| if( nStart == 0 && nEnd == 0) // cannot lock whole file |
| return sal_False; |
| |
| if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) || |
| ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) ) |
| return sal_False; |
| } |
| } |
| } |
| pLock = new InternalStreamLock( nStart, nEnd, pStream ); |
| return sal_True; |
| } |
| |
| void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream ) |
| { |
| #ifndef BOOTSTRAP |
| vos:: OGuard aGuard( LockMutex::get() ); |
| #endif |
| InternalStreamLock* pLock = NULL; |
| InternalStreamLockList &rLockList = LockList::get(); |
| if( nStart == 0 && nEnd == 0 ) |
| { |
| for( sal_uIntPtr i = 0; i < rLockList.Count(); ++i ) |
| { |
| if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream ) |
| { |
| delete pLock; |
| i--; |
| } |
| } |
| return; |
| } |
| for( sal_uIntPtr i = 0; i < rLockList.Count(); ++i ) |
| { |
| if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream && |
| nStart == pLock->m_nStartPos && nEnd == pLock->m_nEndPos ) |
| { |
| delete pLock; |
| return; |
| } |
| } |
| } |
| |
| // -------------- |
| // - StreamData - |
| // -------------- |
| |
| class StreamData |
| { |
| public: |
| int nHandle; |
| |
| StreamData() { nHandle = 0; } |
| }; |
| |
| // ----------------------------------------------------------------------- |
| |
| static sal_uInt32 GetSvError( int nErrno ) |
| { |
| static struct { int nErr; sal_uInt32 sv; } errArr[] = |
| { |
| { 0, SVSTREAM_OK }, |
| { EACCES, SVSTREAM_ACCESS_DENIED }, |
| { EBADF, SVSTREAM_INVALID_HANDLE }, |
| #if defined( RS6000 ) || defined( ALPHA ) || defined( HP9000 ) || defined( NETBSD ) || defined(FREEBSD) || defined(MACOSX) || defined(__FreeBSD_kernel__) |
| { EDEADLK, SVSTREAM_LOCKING_VIOLATION }, |
| #else |
| { EDEADLOCK, SVSTREAM_LOCKING_VIOLATION }, |
| #endif |
| { EINVAL, SVSTREAM_INVALID_PARAMETER }, |
| { EMFILE, SVSTREAM_TOO_MANY_OPEN_FILES }, |
| { ENFILE, SVSTREAM_TOO_MANY_OPEN_FILES }, |
| { ENOENT, SVSTREAM_FILE_NOT_FOUND }, |
| { EPERM, SVSTREAM_ACCESS_DENIED }, |
| { EROFS, SVSTREAM_ACCESS_DENIED }, |
| { EAGAIN, SVSTREAM_LOCKING_VIOLATION }, |
| { EISDIR, SVSTREAM_PATH_NOT_FOUND }, |
| { ELOOP, SVSTREAM_PATH_NOT_FOUND }, |
| #if ! defined( RS6000 ) && ! defined( ALPHA ) && ! defined( NETBSD ) && ! defined (FREEBSD) && ! defined (MACOSX) && ! defined(__FreeBSD_kernel__) |
| { EMULTIHOP, SVSTREAM_PATH_NOT_FOUND }, |
| { ENOLINK, SVSTREAM_PATH_NOT_FOUND }, |
| #endif |
| { ENOTDIR, SVSTREAM_PATH_NOT_FOUND }, |
| { ETXTBSY, SVSTREAM_ACCESS_DENIED }, |
| { EEXIST, SVSTREAM_CANNOT_MAKE }, |
| { ENOSPC, SVSTREAM_DISK_FULL }, |
| { (int)0xFFFF, SVSTREAM_GENERALERROR } |
| }; |
| |
| sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // Standardfehler |
| int i=0; |
| do |
| { |
| if ( errArr[i].nErr == nErrno ) |
| { |
| nRetVal = errArr[i].sv; |
| break; |
| } |
| ++i; |
| } |
| while( errArr[i].nErr != 0xFFFF ); |
| return nRetVal; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::SvFileStream() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 08.06.94 |
| |* Letzte Aenderung OV 08.06.94 |
| |* |
| *************************************************************************/ |
| |
| SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode ) |
| { |
| bIsOpen = sal_False; |
| nLockCounter = 0; |
| bIsWritable = sal_False; |
| pInstanceData = new StreamData; |
| |
| SetBufferSize( 1024 ); |
| // convert URL to SystemPath, if necessary |
| ::rtl::OUString aSystemFileName; |
| if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName ) |
| != FileBase::E_None ) |
| { |
| aSystemFileName = rFileName; |
| } |
| Open( aSystemFileName, nOpenMode ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::SvFileStream() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 22.11.94 |
| |* Letzte Aenderung OV 22.11.94 |
| |* |
| *************************************************************************/ |
| |
| SvFileStream::SvFileStream() |
| { |
| bIsOpen = sal_False; |
| nLockCounter = 0; |
| bIsWritable = sal_False; |
| pInstanceData = new StreamData; |
| SetBufferSize( 1024 ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::~SvFileStream() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 22.11.94 |
| |* Letzte Aenderung OV 22.11.94 |
| |* |
| *************************************************************************/ |
| |
| SvFileStream::~SvFileStream() |
| { |
| Close(); |
| |
| InternalStreamLock::UnlockFile( 0, 0, this ); |
| |
| if (pInstanceData) |
| delete pInstanceData; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::GetFileHandle() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 22.11.94 |
| |* Letzte Aenderung OV 22.11.94 |
| |* |
| *************************************************************************/ |
| |
| sal_uInt32 SvFileStream::GetFileHandle() const |
| { |
| return (sal_uInt32)pInstanceData->nHandle; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::IsA() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 14.06.94 |
| |* Letzte Aenderung OV 14.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_uInt16 SvFileStream::IsA() const |
| { |
| return ID_FILESTREAM; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::GetData() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Size SvFileStream::GetData( void* pData, sal_Size nSize ) |
| { |
| #ifdef DBG_UTIL |
| ByteString aTraceStr( "SvFileStream::GetData(): " ); |
| aTraceStr += ByteString::CreateFromInt64(nSize); |
| aTraceStr += " Bytes from "; |
| aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding()); |
| DBG_TRACE( aTraceStr.GetBuffer() ); |
| #endif |
| |
| int nRead = 0; |
| if ( IsOpen() ) |
| { |
| nRead = read(pInstanceData->nHandle,pData,(unsigned)nSize); |
| if ( nRead == -1 ) |
| SetError( ::GetSvError( errno )); |
| } |
| return (sal_Size)nRead; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::PutData() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize ) |
| { |
| #ifdef DBG_UTIL |
| ByteString aTraceStr( "SvFileStrean::PutData: " ); |
| aTraceStr += ByteString::CreateFromInt64(nSize); |
| aTraceStr += " Bytes to "; |
| aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding()); |
| DBG_TRACE( aTraceStr.GetBuffer() ); |
| #endif |
| |
| int nWrite = 0; |
| if ( IsOpen() ) |
| { |
| nWrite = write(pInstanceData->nHandle,pData,(unsigned)nSize); |
| if ( nWrite == -1 ) |
| SetError( ::GetSvError( errno ) ); |
| else if( !nWrite ) |
| SetError( SVSTREAM_DISK_FULL ); |
| } |
| return (sal_Size)nWrite; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::SeekPos() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Size SvFileStream::SeekPos( sal_Size nPos ) |
| { |
| if ( IsOpen() ) |
| { |
| long nNewPos; |
| if ( nPos != STREAM_SEEK_TO_END ) |
| nNewPos = lseek( pInstanceData->nHandle, (long)nPos, SEEK_SET ); |
| else |
| nNewPos = lseek( pInstanceData->nHandle, 0L, SEEK_END ); |
| |
| if ( nNewPos == -1 ) |
| { |
| SetError( SVSTREAM_SEEK_ERROR ); |
| return 0L; |
| } |
| // langsam aber sicherer als return nNewPos |
| return lseek(pInstanceData->nHandle,0L,SEEK_CUR); |
| // return nNewPos; |
| } |
| SetError( SVSTREAM_GENERALERROR ); |
| return 0L; |
| } |
| |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::FlushData() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::FlushData() |
| { |
| // lokal gibt es nicht |
| } |
| |
| static char *pFileLockEnvVar = (char*)1; |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::LockRange() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes ) |
| { |
| struct flock aflock; |
| aflock.l_start = nByteOffset; |
| aflock.l_whence = SEEK_SET; |
| aflock.l_len = nBytes; |
| |
| int nLockMode = 0; |
| |
| if ( ! IsOpen() ) |
| return sal_False; |
| |
| if ( eStreamMode & STREAM_SHARE_DENYALL ) |
| { |
| if (bIsWritable) |
| nLockMode = F_WRLCK; |
| else |
| nLockMode = F_RDLCK; |
| } |
| |
| if ( eStreamMode & STREAM_SHARE_DENYREAD ) |
| { |
| if (bIsWritable) |
| nLockMode = F_WRLCK; |
| else |
| { |
| SetError(SVSTREAM_LOCKING_VIOLATION); |
| return sal_False; |
| } |
| } |
| |
| if ( eStreamMode & STREAM_SHARE_DENYWRITE ) |
| { |
| if (bIsWritable) |
| nLockMode = F_WRLCK; |
| else |
| nLockMode = F_RDLCK; |
| } |
| |
| if (!nLockMode) |
| return sal_True; |
| |
| if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) ) |
| { |
| #if OSL_DEBUG_LEVEL > 1 |
| fprintf( stderr, "InternalLock on %s [ %ld ... %ld ] failed\n", |
| ByteString(aFilename, osl_getThreadTextEncoding()).GetBuffer(), nByteOffset, nByteOffset+nBytes ); |
| #endif |
| return sal_False; |
| } |
| |
| // HACK: File-Locking nur via Environmentvariable einschalten |
| // um einen Haenger im Zusammenspiel mit einem Linux |
| // NFS-2-Server (kein Lockdaemon) zu verhindern. |
| // File-Locking ?ber NFS ist generell ein Performancekiller. |
| // HR, 22.10.1997 fuer SOLARIS |
| // CP, 30.11.1997 fuer HPUX |
| // ER, 18.12.1997 fuer IRIX |
| // HR, 18.05.1998 Environmentvariable |
| |
| if ( pFileLockEnvVar == (char*)1 ) |
| pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING"); |
| if ( ! pFileLockEnvVar ) |
| return sal_True; |
| |
| aflock.l_type = nLockMode; |
| if (fcntl(pInstanceData->nHandle, F_GETLK, &aflock) == -1) |
| { |
| #if ( defined HPUX && defined BAD_UNION ) |
| #ifdef DBG_UTIL |
| fprintf( stderr, "***** FCNTL(lock):errno = %d\n", errno ); |
| #endif |
| if ( errno == EINVAL || errno == ENOSYS ) |
| return sal_True; |
| #endif |
| #if defined SINIX |
| if (errno == EINVAL) |
| return sal_True; |
| #endif |
| #if defined SOLARIS |
| if (errno == ENOSYS) |
| return sal_True; |
| #endif |
| SetError( ::GetSvError( errno )); |
| return sal_False; |
| } |
| if (aflock.l_type != F_UNLCK) |
| { |
| SetError(SVSTREAM_LOCKING_VIOLATION); |
| return sal_False; |
| } |
| |
| aflock.l_type = nLockMode; |
| if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) == -1) |
| { |
| SetError( ::GetSvError( errno )); |
| return sal_False; |
| } |
| return sal_True; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::UnlockRange() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes ) |
| { |
| |
| struct flock aflock; |
| aflock.l_type = F_UNLCK; |
| aflock.l_start = nByteOffset; |
| aflock.l_whence = SEEK_SET; |
| aflock.l_len = nBytes; |
| |
| if ( ! IsOpen() ) |
| return sal_False; |
| |
| InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this ); |
| |
| if ( ! (eStreamMode & |
| (STREAM_SHARE_DENYALL | STREAM_SHARE_DENYREAD | STREAM_SHARE_DENYWRITE))) |
| return sal_True; |
| |
| // wenn File Locking ausgeschaltet, siehe SvFileStream::LockRange |
| if ( ! pFileLockEnvVar ) |
| return sal_True; |
| |
| if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) != -1) |
| return sal_True; |
| |
| #if ( defined HPUX && defined BAD_UNION ) |
| #ifdef DBG_UTIL |
| fprintf( stderr, "***** FCNTL(unlock):errno = %d\n", errno ); |
| #endif |
| if ( errno == EINVAL || errno == ENOSYS ) |
| return sal_True; |
| #endif |
| #if ( defined SINIX ) |
| if (errno == EINVAL) |
| return sal_True; |
| #endif |
| |
| SetError( ::GetSvError( errno )); |
| return sal_False; |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::LockFile() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool SvFileStream::LockFile() |
| { |
| return LockRange( 0UL, 0UL ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::UnlockFile() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| sal_Bool SvFileStream::UnlockFile() |
| { |
| return UnlockRange( 0UL, 0UL ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::Open() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode ) |
| { |
| int nAccess, nAccessRW; |
| int nMode; |
| int nHandleTmp; |
| struct stat buf; |
| sal_Bool bStatValid = sal_False; |
| |
| Close(); |
| errno = 0; |
| eStreamMode = nOpenMode; |
| eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten |
| |
| // !!! NoOp: Ansonsten ToAbs() verwendern |
| // !!! DirEntry aDirEntry( rFilename ); |
| // !!! aFilename = aDirEntry.GetFull(); |
| aFilename = rFilename; |
| #ifndef BOOTSTRAP |
| FSysRedirector::DoRedirect( aFilename ); |
| #endif |
| ByteString aLocalFilename(aFilename, osl_getThreadTextEncoding()); |
| |
| #ifdef DBG_UTIL |
| ByteString aTraceStr( "SvFileStream::Open(): " ); |
| aTraceStr += aLocalFilename; |
| DBG_TRACE( aTraceStr.GetBuffer() ); |
| #endif |
| |
| if ( lstat( aLocalFilename.GetBuffer(), &buf ) == 0 ) |
| { |
| bStatValid = sal_True; |
| // SvFileStream soll kein Directory oeffnen |
| if( S_ISDIR( buf.st_mode ) ) |
| { |
| SetError( ::GetSvError( EISDIR ) ); |
| return; |
| } |
| } |
| |
| |
| if ( !( nOpenMode & STREAM_WRITE ) ) |
| nAccessRW = O_RDONLY; |
| else if ( !( nOpenMode & STREAM_READ ) ) |
| nAccessRW = O_WRONLY; |
| else |
| nAccessRW = O_RDWR; |
| |
| nAccess = 0; |
| // Fix (MDA, 18.01.95): Bei RD_ONLY nicht mit O_CREAT oeffnen |
| // Wichtig auf Read-Only-Dateisystemen (wie CDROM) |
| if ( (!( nOpenMode & STREAM_NOCREATE )) && ( nAccessRW != O_RDONLY ) ) |
| nAccess |= O_CREAT; |
| if ( nOpenMode & STREAM_TRUNC ) |
| nAccess |= O_TRUNC; |
| |
| nMode = S_IREAD | S_IROTH | S_IRGRP; |
| if ( nOpenMode & STREAM_WRITE) |
| { |
| nMode |= (S_IWRITE | S_IWOTH | S_IWGRP); |
| |
| if ( nOpenMode & STREAM_COPY_ON_SYMLINK ) |
| { |
| if ( bStatValid && S_ISLNK( buf.st_mode ) < 0 ) |
| { |
| char *pBuf = new char[ 1024+1 ]; |
| if ( readlink( aLocalFilename.GetBuffer(), pBuf, 1024 ) > 0 ) |
| { |
| if ( unlink(aLocalFilename.GetBuffer()) == 0 ) |
| { |
| #ifdef DBG_UTIL |
| fprintf( stderr, |
| "Copying file on symbolic link (%s).\n", |
| aLocalFilename.GetBuffer() ); |
| #endif |
| String aTmpString( pBuf, osl_getThreadTextEncoding() ); |
| const DirEntry aSourceEntry( aTmpString ); |
| const DirEntry aTargetEntry( aFilename ); |
| FileCopier aFileCopier( aSourceEntry, aTargetEntry ); |
| aFileCopier.Execute(); |
| } |
| } |
| delete [] pBuf; |
| } |
| } |
| } |
| |
| |
| nHandleTmp = open(aLocalFilename.GetBuffer(),nAccessRW|nAccess, nMode ); |
| |
| if ( nHandleTmp == -1 ) |
| { |
| if ( nAccessRW != O_RDONLY ) |
| { |
| // auf Lesen runterschalten |
| nAccessRW = O_RDONLY; |
| nAccess = 0; |
| nMode = S_IREAD | S_IROTH | S_IRGRP; |
| nHandleTmp =open( aLocalFilename.GetBuffer(), |
| nAccessRW|nAccess, |
| nMode ); |
| } |
| } |
| if ( nHandleTmp != -1 ) |
| { |
| pInstanceData->nHandle = nHandleTmp; |
| bIsOpen = sal_True; |
| if ( nAccessRW != O_RDONLY ) |
| bIsWritable = sal_True; |
| |
| if ( !LockFile() ) // ganze Datei |
| { |
| close( nHandleTmp ); |
| bIsOpen = sal_False; |
| bIsWritable = sal_False; |
| pInstanceData->nHandle = 0; |
| } |
| } |
| else |
| SetError( ::GetSvError( errno ) ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::ReOpen() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::ReOpen() |
| { |
| if ( !bIsOpen && aFilename.Len() ) |
| Open( aFilename, eStreamMode ); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::Close() |
| |* |
| |* Beschreibung STREAM.SDW |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::Close() |
| { |
| InternalStreamLock::UnlockFile( 0, 0, this ); |
| |
| if ( IsOpen() ) |
| { |
| #ifdef DBG_UTIL |
| ByteString aTraceStr( "SvFileStream::Close(): " ); |
| aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding()); |
| DBG_TRACE( aTraceStr.GetBuffer() ); |
| #endif |
| |
| Flush(); |
| close( pInstanceData->nHandle ); |
| pInstanceData->nHandle = 0; |
| } |
| |
| bIsOpen = sal_False; |
| bIsWritable = sal_False; |
| SvStream::ClearBuffer(); |
| SvStream::ClearError(); |
| } |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::ResetError() |
| |* |
| |* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::ResetError() |
| { |
| SvStream::ClearError(); |
| } |
| |
| |
| /************************************************************************* |
| |* |
| |* SvFileStream::SetSize() |
| |* |
| |* Beschreibung STREAM.SDW; |
| |* Ersterstellung OV 15.06.94 |
| |* Letzte Aenderung OV 15.06.94 |
| |* |
| *************************************************************************/ |
| |
| void SvFileStream::SetSize (sal_Size nSize) |
| { |
| if (IsOpen()) |
| { |
| int fd = pInstanceData->nHandle; |
| if (::ftruncate (fd, (off_t)nSize) < 0) |
| { |
| // Save original error. |
| sal_uInt32 nErr = ::GetSvError (errno); |
| |
| // Check against current size. Fail upon 'shrink'. |
| struct stat aStat; |
| if (::fstat (fd, &aStat) < 0) |
| { |
| SetError (nErr); |
| return; |
| } |
| if ((sal::static_int_cast< sal_sSize >(nSize) <= aStat.st_size)) |
| { |
| // Failure upon 'shrink'. Return original error. |
| SetError (nErr); |
| return; |
| } |
| |
| // Save current position. |
| sal_Size nCurPos = (sal_Size)::lseek (fd, (off_t)0, SEEK_CUR); |
| if (nCurPos == (sal_Size)(-1)) |
| { |
| SetError (nErr); |
| return; |
| } |
| |
| // Try 'expand' via 'lseek()' and 'write()'. |
| if (::lseek (fd, (off_t)(nSize - 1), SEEK_SET) < 0) |
| { |
| SetError (nErr); |
| return; |
| } |
| if (::write (fd, (char*)"", (size_t)1) < 0) |
| { |
| // Failure. Restore saved position. |
| if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0) |
| { |
| // Double failure. |
| } |
| |
| SetError (nErr); |
| return; |
| } |
| |
| // Success. Restore saved position. |
| if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0) |
| { |
| SetError (nErr); |
| return; |
| } |
| } |
| } |
| } |
| |
| |