summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sal/osl/unx/file_misc.cxx98
-rw-r--r--sal/osl/unx/makefile.mk8
2 files changed, 62 insertions, 44 deletions
diff --git a/sal/osl/unx/file_misc.cxx b/sal/osl/unx/file_misc.cxx
index 3f3cf02fb010..b9b2b6a23c7d 100644
--- a/sal/osl/unx/file_misc.cxx
+++ b/sal/osl/unx/file_misc.cxx
@@ -29,6 +29,7 @@
#include "osl/diagnose.h"
#include "osl/thread.h"
+#include <osl/signal.h>
#include "rtl/alloc.h"
#include "system.h"
@@ -48,6 +49,8 @@
#include <sys/stat.h>
#include <sys/mman.h>
+#include <algorithm>
+
/************************************************************************
* ToDo
*
@@ -1002,7 +1005,6 @@ static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszD
int SourceFileFD=0;
int DestFileFD=0;
int nRet=0;
- void* pSourceFile=0;
SourceFileFD=open(pszSourceFileName,O_RDONLY);
if ( SourceFileFD < 0 )
@@ -1011,6 +1013,18 @@ static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszD
return nRet;
}
+ // read and lseek are used to check the possibility to access the data
+ // not a nice solution, but it allows to avoid a crash in case it is an opened samba file
+ // generally, reading of one byte should not affect the performance
+ char nCh;
+ if ( 1 != read( SourceFileFD, &nCh, 1 )
+ || -1 == lseek( SourceFileFD, 0, SEEK_SET ) )
+ {
+ nRet = errno;
+ (void) close( SourceFileFD );
+ return nRet;
+ }
+
DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT, mode);
if ( DestFileFD < 0 )
@@ -1029,56 +1043,58 @@ static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszD
return 0;
}
- /* FIXME doCopy: fall back code for systems not having mmap */
- /* mmap file -- open dest file -- write once -- fsync it */
- pSourceFile=mmap(0,nSourceSize,PROT_READ,MAP_PRIVATE,SourceFileFD,0);
+ size_t nWritten = 0;
+ size_t nRemains = nSourceSize;
- if ( pSourceFile == MAP_FAILED )
+ /* mmap file -- open dest file -- write -- fsync it at the end */
+ void* pSourceFile = mmap( 0, nSourceSize, PROT_READ, MAP_SHARED, SourceFileFD, 0 );
+ if ( pSourceFile != MAP_FAILED )
{
- /* it's important to set nRet before the hack
- otherwise errno may be changed by lstat */
- nRet = errno;
- close(SourceFileFD);
- close(DestFileFD);
-
- return nRet;
+ nWritten = write( DestFileFD, pSourceFile, nSourceSize );
+ nRemains -= nWritten;
+ munmap( (char*)pSourceFile, nSourceSize );
}
- nRet = write(DestFileFD,pSourceFile,nSourceSize);
-
- /* #112584# if 'write' could not write the requested number of bytes
- we have to fail of course; because it's not exactly specified if 'write'
- sets errno if less than requested byte could be written we set nRet
- explicitly to ENOSPC */
- if ((nRet < 0) || (nRet != sal::static_int_cast< int >(nSourceSize)))
+ if ( nRemains )
{
- if (nRet < 0)
- nRet = errno;
- else
- nRet = ENOSPC;
+ /* mmap has problems, try the direct streaming */
+ char pBuffer[32000];
+ size_t nRead = 0;
- close(SourceFileFD);
- close(DestFileFD);
- munmap((char*)pSourceFile,nSourceSize);
- return nRet;
+ nRemains = nSourceSize;
+
+ if ( -1 != lseek( SourceFileFD, 0, SEEK_SET )
+ && -1 != lseek( DestFileFD, 0, SEEK_SET ) )
+ {
+ do
+ {
+ nRead = 0;
+ nWritten = 0;
+
+ size_t nToRead = std::min( (size_t)32000, nRemains );
+ nRead = read( SourceFileFD, pBuffer, nToRead );
+ if ( (size_t)-1 != nRead )
+ nWritten = write( DestFileFD, pBuffer, nRead );
+
+ if ( (size_t)-1 != nWritten )
+ nRemains -= nWritten;
+ }
+ while( nRemains && (size_t)-1 != nRead && nRead == nWritten );
+ }
}
- nRet = munmap((char*)pSourceFile,nSourceSize);
- if ( nRet < 0 )
+ if ( nRemains )
{
- nRet=errno;
- close(SourceFileFD);
- close(DestFileFD);
- return nRet;
+ if ( errno )
+ nRet = errno;
+ else
+ nRet = ENOSPC;
}
- close(SourceFileFD);
+ close( SourceFileFD );
+ if ( close( DestFileFD ) == -1 && nRet == 0 )
+ nRet = errno;
- // Removed call to 'fsync' again (#112584#) and instead
- // evaluate the return value of 'close' in order to detect
- // and report ENOSPC and other erronous conditions on close
- if (close(DestFileFD) == -1)
- return errno;
- else
- return 0;
+ return nRet;
}
+
diff --git a/sal/osl/unx/makefile.mk b/sal/osl/unx/makefile.mk
index 0e728c29dbcd..eac4c24cdfa9 100644
--- a/sal/osl/unx/makefile.mk
+++ b/sal/osl/unx/makefile.mk
@@ -55,7 +55,8 @@ CXXFLAGS+= $(LFS_CFLAGS)
# --- Files --------------------------------------------------------
-SLOFILES= $(SLO)$/conditn.obj \
+SLOFILES= \
+ $(SLO)$/conditn.obj \
$(SLO)$/diagnose.obj \
$(SLO)$/semaphor.obj \
$(SLO)$/socket.obj \
@@ -74,7 +75,7 @@ SLOFILES= $(SLO)$/conditn.obj \
$(SLO)$/util.obj \
$(SLO)$/tempfile.obj\
$(SLO)$/file.obj \
- $(SLO)$/file_misc.obj \
+ $(SLO)$/file_misc.obj\
$(SLO)$/file_url.obj\
$(SLO)$/file_error_transl.obj\
$(SLO)$/file_path_helper.obj\
@@ -84,6 +85,7 @@ SLOFILES= $(SLO)$/conditn.obj \
$(SLO)$/process_impl.obj\
$(SLO)$/salinit.obj
+
#.IF "$(UPDATER)"=="YES"
OBJFILES= $(OBJ)$/conditn.obj \
$(OBJ)$/diagnose.obj \
@@ -104,7 +106,7 @@ OBJFILES= $(OBJ)$/conditn.obj \
$(OBJ)$/util.obj \
$(OBJ)$/tempfile.obj\
$(OBJ)$/file.obj \
- $(OBJ)$/file_misc.obj \
+ $(OBJ)$/file_misc.obj\
$(OBJ)$/file_url.obj\
$(OBJ)$/file_error_transl.obj\
$(OBJ)$/file_path_helper.obj\