/**************************************************************
 *
 * 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_uIntPtr 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;
			}
		}
    }
}
