Update ooo320-m1
[ooovba.git] / tools / source / stream / strmunx.cxx
blobdab24b4c0a526e621d45d8ae5094fafe6cadeb88
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: strmunx.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // no include "precompiled_tools.hxx" because this file is included in strmsys.cxx
33 #include <stdio.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <limits.h>
40 #include <stdlib.h> // fuer getenv()
42 #include <tools/debug.hxx>
43 #include <tools/fsys.hxx>
44 #include <tools/stream.hxx>
46 #include <vos/mutex.hxx>
47 #include <osl/thread.h> // osl_getThreadTextEncoding
49 // class FileBase
50 #include <osl/file.hxx>
51 #include <rtl/instance.hxx>
53 using namespace osl;
55 // -----------------------------------------------------------------------
57 // ----------------
58 // - InternalLock -
59 // ----------------
61 class InternalStreamLock;
62 DECLARE_LIST( InternalStreamLockList, InternalStreamLock* )
63 namespace { struct LockList : public rtl::Static< InternalStreamLockList, LockList > {}; }
65 #ifndef BOOTSTRAP
66 namespace { struct LockMutex : public rtl::Static< NAMESPACE_VOS(OMutex), LockMutex > {}; }
67 #endif
69 class InternalStreamLock
71 sal_Size m_nStartPos;
72 sal_Size m_nEndPos;
73 SvFileStream* m_pStream;
74 struct stat m_aStat;
76 InternalStreamLock( sal_Size, sal_Size, SvFileStream* );
77 ~InternalStreamLock();
78 public:
79 static sal_Bool LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
80 static void UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* );
83 InternalStreamLock::InternalStreamLock(
84 sal_Size nStart,
85 sal_Size nEnd,
86 SvFileStream* pStream ) :
87 m_nStartPos( nStart ),
88 m_nEndPos( nEnd ),
89 m_pStream( pStream )
91 ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding());
92 stat( aFileName.GetBuffer(), &m_aStat );
93 LockList::get().Insert( this, LIST_APPEND );
94 #if OSL_DEBUG_LEVEL > 1
95 fprintf( stderr, "locked %s", aFileName.GetBuffer() );
96 if( m_nStartPos || m_nEndPos )
97 fprintf(stderr, " [ %d ... %d ]", m_nStartPos, m_nEndPos );
98 fprintf( stderr, "\n" );
99 #endif
102 InternalStreamLock::~InternalStreamLock()
104 LockList::get().Remove( this );
105 #if OSL_DEBUG_LEVEL > 1
106 ByteString aFileName(m_pStream->GetFileName(), osl_getThreadTextEncoding());
107 fprintf( stderr, "unlocked %s", aFileName.GetBuffer() );
108 if( m_nStartPos || m_nEndPos )
109 fprintf(stderr, " [ %d ... %d ]", m_nStartPos, m_nEndPos );
110 fprintf( stderr, "\n" );
111 #endif
114 sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
116 #ifndef BOOTSTRAP
117 NAMESPACE_VOS( OGuard ) aGuard( LockMutex::get() );
118 #endif
119 ByteString aFileName(pStream->GetFileName(), osl_getThreadTextEncoding());
120 struct stat aStat;
121 if( stat( aFileName.GetBuffer(), &aStat ) )
122 return sal_False;
124 if( S_ISDIR( aStat.st_mode ) )
125 return sal_True;
127 InternalStreamLock* pLock = NULL;
128 InternalStreamLockList &rLockList = LockList::get();
129 for( ULONG i = 0; i < rLockList.Count(); ++i )
131 pLock = rLockList.GetObject( i );
132 if( aStat.st_ino == pLock->m_aStat.st_ino )
134 sal_Bool bDenyByOptions = sal_False;
135 StreamMode nLockMode = pLock->m_pStream->GetStreamMode();
136 StreamMode nNewMode = pStream->GetStreamMode();
138 if( nLockMode & STREAM_SHARE_DENYALL )
139 bDenyByOptions = sal_True;
140 else if( ( nLockMode & STREAM_SHARE_DENYWRITE ) &&
141 ( nNewMode & STREAM_WRITE ) )
142 bDenyByOptions = sal_True;
143 else if( ( nLockMode & STREAM_SHARE_DENYREAD ) &&
144 ( nNewMode & STREAM_READ ) )
145 bDenyByOptions = sal_True;
147 if( bDenyByOptions )
149 if( pLock->m_nStartPos == 0 && pLock->m_nEndPos == 0 ) // whole file is already locked
150 return sal_False;
151 if( nStart == 0 && nEnd == 0) // cannot lock whole file
152 return sal_False;
154 if( ( nStart < pLock->m_nStartPos && nEnd > pLock->m_nStartPos ) ||
155 ( nStart < pLock->m_nEndPos && nEnd > pLock->m_nEndPos ) )
156 return sal_False;
160 pLock = new InternalStreamLock( nStart, nEnd, pStream );
161 return sal_True;
164 void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStream* pStream )
166 #ifndef BOOTSTRAP
167 NAMESPACE_VOS( OGuard ) aGuard( LockMutex::get() );
168 #endif
169 InternalStreamLock* pLock = NULL;
170 InternalStreamLockList &rLockList = LockList::get();
171 if( nStart == 0 && nEnd == 0 )
173 for( ULONG i = 0; i < rLockList.Count(); ++i )
175 if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream )
177 delete pLock;
178 i--;
181 return;
183 for( ULONG i = 0; i < rLockList.Count(); ++i )
185 if( ( pLock = rLockList.GetObject( i ) )->m_pStream == pStream &&
186 nStart == pLock->m_nStartPos && nEnd == pLock->m_nEndPos )
188 delete pLock;
189 return;
194 // --------------
195 // - StreamData -
196 // --------------
198 class StreamData
200 public:
201 int nHandle;
203 StreamData() { nHandle = 0; }
206 // -----------------------------------------------------------------------
208 static sal_uInt32 GetSvError( int nErrno )
210 static struct { int nErr; sal_uInt32 sv; } errArr[] =
212 { 0, SVSTREAM_OK },
213 { EACCES, SVSTREAM_ACCESS_DENIED },
214 { EBADF, SVSTREAM_INVALID_HANDLE },
215 #if defined( RS6000 ) || defined( ALPHA ) || defined( HP9000 ) || defined( NETBSD ) || defined(FREEBSD) || defined(MACOSX)
216 { EDEADLK, SVSTREAM_LOCKING_VIOLATION },
217 #else
218 { EDEADLOCK, SVSTREAM_LOCKING_VIOLATION },
219 #endif
220 { EINVAL, SVSTREAM_INVALID_PARAMETER },
221 { EMFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
222 { ENFILE, SVSTREAM_TOO_MANY_OPEN_FILES },
223 { ENOENT, SVSTREAM_FILE_NOT_FOUND },
224 { EPERM, SVSTREAM_ACCESS_DENIED },
225 { EROFS, SVSTREAM_ACCESS_DENIED },
226 { EAGAIN, SVSTREAM_LOCKING_VIOLATION },
227 { EISDIR, SVSTREAM_PATH_NOT_FOUND },
228 { ELOOP, SVSTREAM_PATH_NOT_FOUND },
229 #if ! defined( RS6000 ) && ! defined( ALPHA ) && ! defined( NETBSD ) && ! defined (FREEBSD) && ! defined (MACOSX)
230 { EMULTIHOP, SVSTREAM_PATH_NOT_FOUND },
231 { ENOLINK, SVSTREAM_PATH_NOT_FOUND },
232 #endif
233 { ENOTDIR, SVSTREAM_PATH_NOT_FOUND },
234 { ETXTBSY, SVSTREAM_ACCESS_DENIED },
235 { EEXIST, SVSTREAM_CANNOT_MAKE },
236 { ENOSPC, SVSTREAM_DISK_FULL },
237 { (int)0xFFFF, SVSTREAM_GENERALERROR }
240 sal_uInt32 nRetVal = SVSTREAM_GENERALERROR; // Standardfehler
241 int i=0;
244 if ( errArr[i].nErr == nErrno )
246 nRetVal = errArr[i].sv;
247 break;
249 ++i;
251 while( errArr[i].nErr != 0xFFFF );
252 return nRetVal;
255 /*************************************************************************
257 |* SvFileStream::SvFileStream()
259 |* Beschreibung STREAM.SDW
260 |* Ersterstellung OV 08.06.94
261 |* Letzte Aenderung OV 08.06.94
263 *************************************************************************/
265 SvFileStream::SvFileStream( const String& rFileName, StreamMode nOpenMode )
267 bIsOpen = sal_False;
268 nLockCounter = 0;
269 bIsWritable = sal_False;
270 pInstanceData = new StreamData;
272 SetBufferSize( 1024 );
273 // convert URL to SystemPath, if necessary
274 ::rtl::OUString aSystemFileName;
275 if( FileBase::getSystemPathFromFileURL( rFileName , aSystemFileName )
276 != FileBase::E_None )
278 aSystemFileName = rFileName;
280 Open( aSystemFileName, nOpenMode );
283 /*************************************************************************
285 |* SvFileStream::SvFileStream()
287 |* Beschreibung STREAM.SDW
288 |* Ersterstellung OV 22.11.94
289 |* Letzte Aenderung OV 22.11.94
291 *************************************************************************/
293 SvFileStream::SvFileStream()
295 bIsOpen = sal_False;
296 nLockCounter = 0;
297 bIsWritable = sal_False;
298 pInstanceData = new StreamData;
299 SetBufferSize( 1024 );
302 /*************************************************************************
304 |* SvFileStream::~SvFileStream()
306 |* Beschreibung STREAM.SDW
307 |* Ersterstellung OV 22.11.94
308 |* Letzte Aenderung OV 22.11.94
310 *************************************************************************/
312 SvFileStream::~SvFileStream()
314 Close();
316 InternalStreamLock::UnlockFile( 0, 0, this );
318 if (pInstanceData)
319 delete pInstanceData;
322 /*************************************************************************
324 |* SvFileStream::GetFileHandle()
326 |* Beschreibung STREAM.SDW
327 |* Ersterstellung OV 22.11.94
328 |* Letzte Aenderung OV 22.11.94
330 *************************************************************************/
332 sal_uInt32 SvFileStream::GetFileHandle() const
334 return (sal_uInt32)pInstanceData->nHandle;
337 /*************************************************************************
339 |* SvFileStream::IsA()
341 |* Beschreibung STREAM.SDW
342 |* Ersterstellung OV 14.06.94
343 |* Letzte Aenderung OV 14.06.94
345 *************************************************************************/
347 sal_uInt16 SvFileStream::IsA() const
349 return ID_FILESTREAM;
352 /*************************************************************************
354 |* SvFileStream::GetData()
356 |* Beschreibung STREAM.SDW
357 |* Ersterstellung OV 15.06.94
358 |* Letzte Aenderung OV 15.06.94
360 *************************************************************************/
362 sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
364 #ifdef DBG_UTIL
365 ByteString aTraceStr( "SvFileStream::GetData(): " );
366 aTraceStr += ByteString::CreateFromInt64(nSize);
367 aTraceStr += " Bytes from ";
368 aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
369 DBG_TRACE( aTraceStr.GetBuffer() );
370 #endif
372 int nRead = 0;
373 if ( IsOpen() )
375 nRead = read(pInstanceData->nHandle,pData,(unsigned)nSize);
376 if ( nRead == -1 )
377 SetError( ::GetSvError( errno ));
379 return (sal_Size)nRead;
382 /*************************************************************************
384 |* SvFileStream::PutData()
386 |* Beschreibung STREAM.SDW
387 |* Ersterstellung OV 15.06.94
388 |* Letzte Aenderung OV 15.06.94
390 *************************************************************************/
392 sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
394 #ifdef DBG_UTIL
395 ByteString aTraceStr( "SvFileStrean::PutData: " );
396 aTraceStr += ByteString::CreateFromInt64(nSize);
397 aTraceStr += " Bytes to ";
398 aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
399 DBG_TRACE( aTraceStr.GetBuffer() );
400 #endif
402 int nWrite = 0;
403 if ( IsOpen() )
405 nWrite = write(pInstanceData->nHandle,pData,(unsigned)nSize);
406 if ( nWrite == -1 )
407 SetError( ::GetSvError( errno ) );
408 else if( !nWrite )
409 SetError( SVSTREAM_DISK_FULL );
411 return (sal_Size)nWrite;
414 /*************************************************************************
416 |* SvFileStream::SeekPos()
418 |* Beschreibung STREAM.SDW
419 |* Ersterstellung OV 15.06.94
420 |* Letzte Aenderung OV 15.06.94
422 *************************************************************************/
424 sal_Size SvFileStream::SeekPos( sal_Size nPos )
426 if ( IsOpen() )
428 long nNewPos;
429 if ( nPos != STREAM_SEEK_TO_END )
430 nNewPos = lseek( pInstanceData->nHandle, (long)nPos, SEEK_SET );
431 else
432 nNewPos = lseek( pInstanceData->nHandle, 0L, SEEK_END );
434 if ( nNewPos == -1 )
436 SetError( SVSTREAM_SEEK_ERROR );
437 return 0L;
439 // langsam aber sicherer als return nNewPos
440 return lseek(pInstanceData->nHandle,0L,SEEK_CUR);
441 // return nNewPos;
443 SetError( SVSTREAM_GENERALERROR );
444 return 0L;
448 /*************************************************************************
450 |* SvFileStream::FlushData()
452 |* Beschreibung STREAM.SDW
453 |* Ersterstellung OV 15.06.94
454 |* Letzte Aenderung OV 15.06.94
456 *************************************************************************/
458 void SvFileStream::FlushData()
460 // lokal gibt es nicht
463 static char *pFileLockEnvVar = (char*)1;
465 /*************************************************************************
467 |* SvFileStream::LockRange()
469 |* Beschreibung STREAM.SDW
470 |* Ersterstellung OV 15.06.94
471 |* Letzte Aenderung OV 15.06.94
473 *************************************************************************/
475 sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
477 struct flock aflock;
478 aflock.l_start = nByteOffset;
479 aflock.l_whence = SEEK_SET;
480 aflock.l_len = nBytes;
482 int nLockMode = 0;
484 if ( ! IsOpen() )
485 return sal_False;
487 if ( eStreamMode & STREAM_SHARE_DENYALL )
489 if (bIsWritable)
490 nLockMode = F_WRLCK;
491 else
492 nLockMode = F_RDLCK;
495 if ( eStreamMode & STREAM_SHARE_DENYREAD )
497 if (bIsWritable)
498 nLockMode = F_WRLCK;
499 else
501 SetError(SVSTREAM_LOCKING_VIOLATION);
502 return sal_False;
506 if ( eStreamMode & STREAM_SHARE_DENYWRITE )
508 if (bIsWritable)
509 nLockMode = F_WRLCK;
510 else
511 nLockMode = F_RDLCK;
514 if (!nLockMode)
515 return sal_True;
517 if( ! InternalStreamLock::LockFile( nByteOffset, nByteOffset+nBytes, this ) )
519 #if OSL_DEBUG_LEVEL > 1
520 fprintf( stderr, "InternalLock on %s [ %d ... %d ] failed\n",
521 ByteString(aFilename, osl_getThreadTextEncoding()).GetBuffer(), nByteOffset, nByteOffset+nBytes );
522 #endif
523 return sal_False;
526 // HACK: File-Locking nur via Environmentvariable einschalten
527 // um einen Haenger im Zusammenspiel mit einem Linux
528 // NFS-2-Server (kein Lockdaemon) zu verhindern.
529 // File-Locking ?ber NFS ist generell ein Performancekiller.
530 // HR, 22.10.1997 fuer SOLARIS
531 // CP, 30.11.1997 fuer HPUX
532 // ER, 18.12.1997 fuer IRIX
533 // HR, 18.05.1998 Environmentvariable
535 if ( pFileLockEnvVar == (char*)1 )
536 pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
537 if ( ! pFileLockEnvVar )
538 return sal_True;
540 aflock.l_type = nLockMode;
541 if (fcntl(pInstanceData->nHandle, F_GETLK, &aflock) == -1)
543 #if ( defined HPUX && defined BAD_UNION )
544 #ifdef DBG_UTIL
545 fprintf( stderr, "***** FCNTL(lock):errno = %d\n", errno );
546 #endif
547 if ( errno == EINVAL || errno == ENOSYS )
548 return sal_True;
549 #endif
550 #if defined SINIX
551 if (errno == EINVAL)
552 return sal_True;
553 #endif
554 #if defined SOLARIS
555 if (errno == ENOSYS)
556 return sal_True;
557 #endif
558 SetError( ::GetSvError( errno ));
559 return sal_False;
561 if (aflock.l_type != F_UNLCK)
563 SetError(SVSTREAM_LOCKING_VIOLATION);
564 return sal_False;
567 aflock.l_type = nLockMode;
568 if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) == -1)
570 SetError( ::GetSvError( errno ));
571 return sal_False;
573 return sal_True;
576 /*************************************************************************
578 |* SvFileStream::UnlockRange()
580 |* Beschreibung STREAM.SDW
581 |* Ersterstellung OV 15.06.94
582 |* Letzte Aenderung OV 15.06.94
584 *************************************************************************/
586 sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
589 struct flock aflock;
590 aflock.l_type = F_UNLCK;
591 aflock.l_start = nByteOffset;
592 aflock.l_whence = SEEK_SET;
593 aflock.l_len = nBytes;
595 if ( ! IsOpen() )
596 return sal_False;
598 InternalStreamLock::UnlockFile( nByteOffset, nByteOffset+nBytes, this );
600 if ( ! (eStreamMode &
601 (STREAM_SHARE_DENYALL | STREAM_SHARE_DENYREAD | STREAM_SHARE_DENYWRITE)))
602 return sal_True;
604 // wenn File Locking ausgeschaltet, siehe SvFileStream::LockRange
605 if ( ! pFileLockEnvVar )
606 return sal_True;
608 if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) != -1)
609 return sal_True;
611 #if ( defined HPUX && defined BAD_UNION )
612 #ifdef DBG_UTIL
613 fprintf( stderr, "***** FCNTL(unlock):errno = %d\n", errno );
614 #endif
615 if ( errno == EINVAL || errno == ENOSYS )
616 return sal_True;
617 #endif
618 #if ( defined SINIX )
619 if (errno == EINVAL)
620 return sal_True;
621 #endif
623 SetError( ::GetSvError( errno ));
624 return sal_False;
627 /*************************************************************************
629 |* SvFileStream::LockFile()
631 |* Beschreibung STREAM.SDW
632 |* Ersterstellung OV 15.06.94
633 |* Letzte Aenderung OV 15.06.94
635 *************************************************************************/
637 sal_Bool SvFileStream::LockFile()
639 return LockRange( 0UL, 0UL );
642 /*************************************************************************
644 |* SvFileStream::UnlockFile()
646 |* Beschreibung STREAM.SDW
647 |* Ersterstellung OV 15.06.94
648 |* Letzte Aenderung OV 15.06.94
650 *************************************************************************/
652 sal_Bool SvFileStream::UnlockFile()
654 return UnlockRange( 0UL, 0UL );
657 /*************************************************************************
659 |* SvFileStream::Open()
661 |* Beschreibung STREAM.SDW
662 |* Ersterstellung OV 15.06.94
663 |* Letzte Aenderung OV 15.06.94
665 *************************************************************************/
667 void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
669 int nAccess, nAccessRW;
670 int nMode;
671 int nHandleTmp;
672 struct stat buf;
673 sal_Bool bStatValid = sal_False;
675 Close();
676 errno = 0;
677 eStreamMode = nOpenMode;
678 eStreamMode &= ~STREAM_TRUNC; // beim ReOpen nicht cutten
680 // !!! NoOp: Ansonsten ToAbs() verwendern
681 // !!! DirEntry aDirEntry( rFilename );
682 // !!! aFilename = aDirEntry.GetFull();
683 aFilename = rFilename;
684 #ifndef BOOTSTRAP
685 FSysRedirector::DoRedirect( aFilename );
686 #endif
687 ByteString aLocalFilename(aFilename, osl_getThreadTextEncoding());
689 #ifdef DBG_UTIL
690 ByteString aTraceStr( "SvFileStream::Open(): " );
691 aTraceStr += aLocalFilename;
692 DBG_TRACE( aTraceStr.GetBuffer() );
693 #endif
695 if ( lstat( aLocalFilename.GetBuffer(), &buf ) == 0 )
697 bStatValid = sal_True;
698 // SvFileStream soll kein Directory oeffnen
699 if( S_ISDIR( buf.st_mode ) )
701 SetError( ::GetSvError( EISDIR ) );
702 return;
707 if ( !( nOpenMode & STREAM_WRITE ) )
708 nAccessRW = O_RDONLY;
709 else if ( !( nOpenMode & STREAM_READ ) )
710 nAccessRW = O_WRONLY;
711 else
712 nAccessRW = O_RDWR;
714 nAccess = 0;
715 // Fix (MDA, 18.01.95): Bei RD_ONLY nicht mit O_CREAT oeffnen
716 // Wichtig auf Read-Only-Dateisystemen (wie CDROM)
717 if ( (!( nOpenMode & STREAM_NOCREATE )) && ( nAccessRW != O_RDONLY ) )
718 nAccess |= O_CREAT;
719 if ( nOpenMode & STREAM_TRUNC )
720 nAccess |= O_TRUNC;
722 nMode = S_IREAD | S_IROTH | S_IRGRP;
723 if ( nOpenMode & STREAM_WRITE)
725 nMode |= (S_IWRITE | S_IWOTH | S_IWGRP);
727 if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
729 if ( bStatValid && S_ISLNK( buf.st_mode ) < 0 )
731 char *pBuf = new char[ 1024+1 ];
732 if ( readlink( aLocalFilename.GetBuffer(), pBuf, 1024 ) > 0 )
734 if ( unlink(aLocalFilename.GetBuffer()) == 0 )
736 #ifdef DBG_UTIL
737 fprintf( stderr,
738 "Copying file on symbolic link (%s).\n",
739 aLocalFilename.GetBuffer() );
740 #endif
741 String aTmpString( pBuf, osl_getThreadTextEncoding() );
742 const DirEntry aSourceEntry( aTmpString );
743 const DirEntry aTargetEntry( aFilename );
744 FileCopier aFileCopier( aSourceEntry, aTargetEntry );
745 aFileCopier.Execute();
748 delete pBuf;
754 nHandleTmp = open(aLocalFilename.GetBuffer(),nAccessRW|nAccess, nMode );
756 if ( nHandleTmp == -1 )
758 if ( nAccessRW != O_RDONLY )
760 // auf Lesen runterschalten
761 nAccessRW = O_RDONLY;
762 nAccess = 0;
763 nMode = S_IREAD | S_IROTH | S_IRGRP;
764 nHandleTmp =open( aLocalFilename.GetBuffer(),
765 nAccessRW|nAccess,
766 nMode );
769 if ( nHandleTmp != -1 )
771 pInstanceData->nHandle = nHandleTmp;
772 bIsOpen = sal_True;
773 if ( nAccessRW != O_RDONLY )
774 bIsWritable = sal_True;
776 if ( !LockFile() ) // ganze Datei
778 close( nHandleTmp );
779 bIsOpen = sal_False;
780 bIsWritable = sal_False;
781 pInstanceData->nHandle = 0;
784 else
785 SetError( ::GetSvError( errno ) );
788 /*************************************************************************
790 |* SvFileStream::ReOpen()
792 |* Beschreibung STREAM.SDW
793 |* Ersterstellung OV 15.06.94
794 |* Letzte Aenderung OV 15.06.94
796 *************************************************************************/
798 void SvFileStream::ReOpen()
800 if ( !bIsOpen && aFilename.Len() )
801 Open( aFilename, eStreamMode );
804 /*************************************************************************
806 |* SvFileStream::Close()
808 |* Beschreibung STREAM.SDW
809 |* Ersterstellung OV 15.06.94
810 |* Letzte Aenderung OV 15.06.94
812 *************************************************************************/
814 void SvFileStream::Close()
816 InternalStreamLock::UnlockFile( 0, 0, this );
818 if ( IsOpen() )
820 #ifdef DBG_UTIL
821 ByteString aTraceStr( "SvFileStream::Close(): " );
822 aTraceStr += ByteString(aFilename, osl_getThreadTextEncoding());
823 DBG_TRACE( aTraceStr.GetBuffer() );
824 #endif
826 Flush();
827 close( pInstanceData->nHandle );
828 pInstanceData->nHandle = 0;
831 bIsOpen = sal_False;
832 bIsWritable = sal_False;
833 SvStream::ClearBuffer();
834 SvStream::ClearError();
837 /*************************************************************************
839 |* SvFileStream::ResetError()
841 |* Beschreibung STREAM.SDW; Setzt Filepointer auf Dateianfang
842 |* Ersterstellung OV 15.06.94
843 |* Letzte Aenderung OV 15.06.94
845 *************************************************************************/
847 void SvFileStream::ResetError()
849 SvStream::ClearError();
853 /*************************************************************************
855 |* SvFileStream::SetSize()
857 |* Beschreibung STREAM.SDW;
858 |* Ersterstellung OV 15.06.94
859 |* Letzte Aenderung OV 15.06.94
861 *************************************************************************/
863 void SvFileStream::SetSize (sal_Size nSize)
865 if (IsOpen())
867 int fd = pInstanceData->nHandle;
868 if (::ftruncate (fd, (off_t)nSize) < 0)
870 // Save original error.
871 sal_uInt32 nErr = ::GetSvError (errno);
873 // Check against current size. Fail upon 'shrink'.
874 struct stat aStat;
875 if (::fstat (fd, &aStat) < 0)
877 SetError (nErr);
878 return;
880 if ((sal::static_int_cast< sal_sSize >(nSize) <= aStat.st_size))
882 // Failure upon 'shrink'. Return original error.
883 SetError (nErr);
884 return;
887 // Save current position.
888 sal_Size nCurPos = (sal_Size)::lseek (fd, (off_t)0, SEEK_CUR);
889 if (nCurPos == (sal_Size)(-1))
891 SetError (nErr);
892 return;
895 // Try 'expand' via 'lseek()' and 'write()'.
896 if (::lseek (fd, (off_t)(nSize - 1), SEEK_SET) < 0)
898 SetError (nErr);
899 return;
901 if (::write (fd, (char*)"", (size_t)1) < 0)
903 // Failure. Restore saved position.
904 if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0)
906 // Double failure.
909 SetError (nErr);
910 return;
913 // Success. Restore saved position.
914 if (::lseek (fd, (off_t)nCurPos, SEEK_SET) < 0)
916 SetError (nErr);
917 return;