[Libreoffice-commits] .: 3 commits - android/qa sal/inc sal/osl sal/Package_inc.mk sal/util tools/source

Tor Lillqvist tml at kemper.freedesktop.org
Wed Jan 18 13:16:22 PST 2012


 android/qa/sc/Makefile          |    8 -
 sal/Package_inc.mk              |    1 
 sal/inc/osl/detail/file.h       |   87 +++++++++++++++
 sal/osl/unx/file.cxx            |   77 +++++++++----
 sal/osl/unx/file_stat.cxx       |   23 ++++
 sal/osl/unx/uunxapi.cxx         |   34 ++++--
 sal/osl/unx/uunxapi.h           |    6 +
 sal/osl/w32/file.cxx            |   16 ++
 sal/util/sal.map                |    8 +
 tools/source/stream/strmunx.cxx |  226 ++++++++++++++++++++--------------------
 10 files changed, 346 insertions(+), 140 deletions(-)

New commits:
commit fa83e46653536821fa70d37d9e4e0ed98538e522
Author: Tor Lillqvist <tlillqvist at suse.com>
Date:   Wed Jan 18 10:48:26 2012 +0200

    No need to unpack the .res files any more

diff --git a/android/qa/sc/Makefile b/android/qa/sc/Makefile
index d023791..67fa567 100644
--- a/android/qa/sc/Makefile
+++ b/android/qa/sc/Makefile
@@ -137,11 +137,11 @@ copy-stuff:
 		sed -e 's!uri="./!uri="$(APP_DATA_PATH)/lib/!g' <$(SRC_ROOT)/testtools/$(INPATH)/lib/$$F.rdb >assets/lib/$$F.rdb; \
 	done
 	cp -R $(OUTDIR)/xml/registry assets/xml
-# Then assets that are unpacked at run-time into the app's data directory.
-	mkdir -p assets/unpack/bin
+# .res files
 	for F in $(OUTDIR)/bin/*.res; do \
-		cp $$F assets/unpack/bin; \
+		cp $$F assets/bin; \
 	done
+# Then assets that are unpacked at run-time into the app's data directory.
 	mkdir -p assets/unpack/etc/fonts
 	cp fonts.conf assets/unpack/etc/fonts
 #
@@ -164,7 +164,7 @@ uninstall:
 	adb uninstall $(APP_PACKAGE)
 
 run:
-	echo "STAR_RESOURCEPATH=$(APP_DATA_PATH)/bin FONTCONFIG_FILE=$(APP_DATA_PATH)/etc/fonts/fonts.conf $(APP_DATA_PATH)/lib/libtest_sc_ucalc.so --headless --protector libunoexceptionprotector.so unoexceptionprotector '-env:CONFIGURATION_LAYERS=xcsxcu:file:///assets/xml/registry' '-env:UNO_TYPES=file:///assets/bin/udkapi.rdb file:///assets/bin/types.rdb'  '-env:UNO_SERVICES=file:///assets/xml/ure/services.rdb  file:///assets/ComponentTarget/framework/util/fwk.component file:///assets/ComponentTarget/i18npool/util/i18npool.component file:///assets/ComponentTarget/sfx2/util/sfx.component file:///assets/ComponentTarget/unoxml/source/service/unoxml.component file:///assets/ComponentTarget/configmgr/source/configmgr.component file:///assets/ComponentTarget/ucb/source/core/ucb1.component file:///assets/ComponentTarget/ucb/source/ucp/file/ucpfile1.component' -env:URE_INTERNAL_LIB_DIR=file://$(APP_DATA_PATH)/lib -env:LO_LIB_DIR=file://$(APP_DATA_PATH)/lib" >cmdline
+	echo "STAR_RESOURCEPATH=/assets/bin FONTCONFIG_FILE=$(APP_DATA_PATH)/etc/fonts/fonts.conf $(APP_DATA_PATH)/lib/libtest_sc_ucalc.so --headless --protector libunoexceptionprotector.so unoexceptionprotector '-env:CONFIGURATION_LAYERS=xcsxcu:file:///assets/xml/registry' '-env:UNO_TYPES=file:///assets/bin/udkapi.rdb file:///assets/bin/types.rdb'  '-env:UNO_SERVICES=file:///assets/xml/ure/services.rdb  file:///assets/ComponentTarget/framework/util/fwk.component file:///assets/ComponentTarget/i18npool/util/i18npool.component file:///assets/ComponentTarget/sfx2/util/sfx.component file:///assets/ComponentTarget/unoxml/source/service/unoxml.component file:///assets/ComponentTarget/configmgr/source/configmgr.component file:///assets/ComponentTarget/ucb/source/core/ucb1.component file:///assets/ComponentTarget/ucb/source/ucp/file/ucpfile1.component' -env:URE_INTERNAL_LIB_DIR=file://$(APP_DATA_PATH)/lib -env:LO_LIB_DIR=file://$(APP_DATA_PATH)/lib" >cmdline
 	adb push cmdline $(APP_DATA_PATH)/cmdline
 	adb shell am start -n $(APP_PACKAGE)/$(BOOTSTRAP) -e lo-main-library libcppunittester -e lo-main-indirect-cmdline "$(APP_DATA_PATH)/cmdline"
 
commit e541105b45d5da8df296883111194e3a0297a2e7
Author: Tor Lillqvist <tlillqvist at suse.com>
Date:   Tue Jan 17 21:59:22 2012 +0200

    Use osl API to access files in the SvFileStream code
    
    In general it's good to have file opening in just one place. In
    particular, this means SvFileStream can now open files located in the
    app package (.apk Zip archive) on Android, we don't need to unpack
    them into separate files.

diff --git a/tools/source/stream/strmunx.cxx b/tools/source/stream/strmunx.cxx
index ffb75a9..c9d4f07 100644
--- a/tools/source/stream/strmunx.cxx
+++ b/tools/source/stream/strmunx.cxx
@@ -46,6 +46,7 @@
 
 // class FileBase
 #include <osl/file.hxx>
+#include <osl/detail/file.h>
 #include <rtl/instance.hxx>
 #include <rtl/strbuf.hxx>
 
@@ -88,7 +89,7 @@ InternalStreamLock::InternalStreamLock(
 {
     rtl::OString aFileName(rtl::OUStringToOString(m_pStream->GetFileName(),
         osl_getThreadTextEncoding()));
-    stat( aFileName.getStr(), &m_aStat );
+    osl_statFilePath( aFileName.getStr(), &m_aStat );
     LockList::get().push_back( this );
 #if OSL_DEBUG_LEVEL > 1
     fprintf( stderr, "locked %s", aFileName.getStr() );
@@ -127,7 +128,7 @@ sal_Bool InternalStreamLock::LockFile( sal_Size nStart, sal_Size nEnd, SvFileStr
     rtl::OString aFileName(rtl::OUStringToOString(pStream->GetFileName(),
         osl_getThreadTextEncoding()));
     struct stat aStat;
-    if( stat( aFileName.getStr(), &aStat ) )
+    if( osl_statFilePath( aFileName.getStr(), &aStat ) != osl_File_E_None )
         return sal_False;
 
     if( S_ISDIR( aStat.st_mode ) )
@@ -213,9 +214,9 @@ void InternalStreamLock::UnlockFile( sal_Size nStart, sal_Size nEnd, SvFileStrea
 class StreamData
 {
 public:
-    int     nHandle;
+    oslFileHandle rHandle;
 
-            StreamData() { nHandle = 0; }
+            StreamData() { }
 };
 
 // -----------------------------------------------------------------------
@@ -272,6 +273,46 @@ static sal_uInt32 GetSvError( int nErrno )
     return nRetVal;
 }
 
+static sal_uInt32 GetSvError( oslFileError nErrno )
+{
+    static struct { oslFileError nErr; sal_uInt32 sv; } errArr[] =
+    {
+        { osl_File_E_None,        SVSTREAM_OK },
+        { osl_File_E_ACCES,       SVSTREAM_ACCESS_DENIED },
+        { osl_File_E_BADF,        SVSTREAM_INVALID_HANDLE },
+        { osl_File_E_DEADLK,      SVSTREAM_LOCKING_VIOLATION },
+        { osl_File_E_INVAL,       SVSTREAM_INVALID_PARAMETER },
+        { osl_File_E_MFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
+        { osl_File_E_NFILE,       SVSTREAM_TOO_MANY_OPEN_FILES },
+        { osl_File_E_NOENT,       SVSTREAM_FILE_NOT_FOUND },
+        { osl_File_E_PERM,        SVSTREAM_ACCESS_DENIED },
+        { osl_File_E_ROFS,        SVSTREAM_ACCESS_DENIED },
+        { osl_File_E_AGAIN,       SVSTREAM_LOCKING_VIOLATION },
+        { osl_File_E_ISDIR,       SVSTREAM_PATH_NOT_FOUND },
+        { osl_File_E_LOOP,        SVSTREAM_PATH_NOT_FOUND },
+        { osl_File_E_MULTIHOP,    SVSTREAM_PATH_NOT_FOUND },
+        { osl_File_E_NOLINK,      SVSTREAM_PATH_NOT_FOUND },
+        { osl_File_E_NOTDIR,      SVSTREAM_PATH_NOT_FOUND },
+        { osl_File_E_EXIST,       SVSTREAM_CANNOT_MAKE    },
+        { osl_File_E_NOSPC,       SVSTREAM_DISK_FULL      },
+        { (oslFileError)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 != (oslFileError)0xFFFF );
+    return nRetVal;
+}
+
 /*************************************************************************
 |*
 |*    SvFileStream::SvFileStream()
@@ -335,7 +376,11 @@ SvFileStream::~SvFileStream()
 
 sal_uInt32 SvFileStream::GetFileHandle() const
 {
-    return (sal_uInt32)pInstanceData->nHandle;
+    sal_IntPtr handle;
+    if (osl_getFileOSHandle(pInstanceData->rHandle, &handle) == osl_File_E_None)
+        return (sal_uInt32) handle;
+    else
+        return (sal_uInt32) -1;
 }
 
 /*************************************************************************
@@ -367,12 +412,15 @@ sal_Size SvFileStream::GetData( void* pData, sal_Size nSize )
     OSL_TRACE("%s", aTraceStr.getStr());
 #endif
 
-    int nRead = 0;
+    sal_uInt64 nRead = 0;
     if ( IsOpen() )
     {
-        nRead = read(pInstanceData->nHandle,pData,(unsigned)nSize);
-        if ( nRead == -1 )
-            SetError( ::GetSvError( errno ));
+        oslFileError rc = osl_readFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nRead);
+        if ( rc != osl_File_E_None )
+        {
+            SetError( ::GetSvError( rc ));
+            return -1;
+        }
     }
     return (sal_Size)nRead;
 }
@@ -395,14 +443,17 @@ sal_Size SvFileStream::PutData( const void* pData, sal_Size nSize )
     OSL_TRACE("%s", aTraceStr.getStr());
 #endif
 
-    int nWrite = 0;
+    sal_uInt64 nWrite = 0;
     if ( IsOpen() )
     {
-        nWrite = write(pInstanceData->nHandle,pData,(unsigned)nSize);
-        if ( nWrite == -1 )
-        SetError( ::GetSvError( errno ) );
+        oslFileError rc = osl_writeFile(pInstanceData->rHandle,pData,(sal_uInt64)nSize,&nWrite);
+        if ( rc != osl_File_E_None )
+        {
+            SetError( ::GetSvError( rc ) );
+            return -1;
+        }
         else if( !nWrite )
-        SetError( SVSTREAM_DISK_FULL );
+            SetError( SVSTREAM_DISK_FULL );
     }
     return (sal_Size)nWrite;
 }
@@ -417,20 +468,20 @@ sal_Size SvFileStream::SeekPos( sal_Size nPos )
 {
     if ( IsOpen() )
     {
-        long nNewPos;
+        oslFileError rc;
+        sal_uInt64 nNewPos;
         if ( nPos != STREAM_SEEK_TO_END )
-            nNewPos = lseek( pInstanceData->nHandle, (long)nPos, SEEK_SET );
+            rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_Absolut, nPos );
         else
-            nNewPos = lseek( pInstanceData->nHandle, 0L, SEEK_END );
+            rc = osl_setFilePos( pInstanceData->rHandle, osl_Pos_End, 0 );
 
-        if ( nNewPos == -1 )
+        if ( rc != osl_File_E_None )
         {
             SetError( SVSTREAM_SEEK_ERROR );
             return 0L;
         }
-        // langsam aber sicherer als return nNewPos
-        return lseek(pInstanceData->nHandle,0L,SEEK_CUR);
-        // return nNewPos;
+        rc = osl_getFilePos( pInstanceData->rHandle, &nNewPos );
+        return (sal_Size) nNewPos;
     }
     SetError( SVSTREAM_GENERALERROR );
     return 0L;
@@ -520,7 +571,14 @@ sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
         return sal_True;
 
     aflock.l_type = nLockMode;
-    if (fcntl(pInstanceData->nHandle, F_GETLK, &aflock) == -1)
+    sal_IntPtr iFileHandle;
+    oslFileError rc = osl_getFileOSHandle(pInstanceData->rHandle, &iFileHandle);
+    if (rc != osl_File_E_None)
+    {
+        SetError( ::GetSvError( rc ));
+        return sal_False;
+    }
+    if (fcntl((int)iFileHandle, F_GETLK, &aflock) == -1)
     {
     #if defined SOLARIS
         if (errno == ENOSYS)
@@ -536,7 +594,7 @@ sal_Bool SvFileStream::LockRange( sal_Size nByteOffset, sal_Size nBytes )
     }
 
     aflock.l_type = nLockMode;
-    if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) == -1)
+    if (fcntl((int)iFileHandle, F_SETLK, &aflock) == -1)
     {
         SetError( ::GetSvError( errno ));
         return sal_False;
@@ -572,7 +630,14 @@ sal_Bool SvFileStream::UnlockRange( sal_Size nByteOffset, sal_Size nBytes )
     if ( ! pFileLockEnvVar )
         return sal_True;
 
-    if (fcntl(pInstanceData->nHandle, F_SETLK, &aflock) != -1)
+    sal_IntPtr iFileHandle;
+    oslFileError rc = osl_getFileOSHandle(pInstanceData->rHandle, &iFileHandle);
+    if (rc != osl_File_E_None)
+    {
+        SetError( ::GetSvError( rc ));
+        return sal_False;
+    }
+    if (fcntl((int)iFileHandle, F_SETLK, &aflock) != -1)
         return sal_True;
 
     SetError( ::GetSvError( errno ));
@@ -609,9 +674,8 @@ sal_Bool SvFileStream::UnlockFile()
 
 void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
 {
-    int nAccess, nAccessRW;
-    int nMode;
-    int nHandleTmp;
+    sal_uInt32 uFlags;
+    oslFileHandle nHandleTmp;
     struct stat buf;
     sal_Bool bStatValid = sal_False;
 
@@ -636,7 +700,7 @@ void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
     OSL_TRACE( "%s", aTraceStr.getStr() );
 #endif
 
-    if ( lstat( aLocalFilename.getStr(), &buf ) == 0 )
+    if ( osl_lstatFilePath( aLocalFilename.getStr(), &buf ) == osl_File_E_None )
       {
         bStatValid = sal_True;
         // SvFileStream soll kein Directory oeffnen
@@ -647,27 +711,24 @@ void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
           }
       }
 
-
     if ( !( nOpenMode & STREAM_WRITE ) )
-        nAccessRW = O_RDONLY;
+        uFlags = osl_File_OpenFlag_Read;
     else if ( !( nOpenMode & STREAM_READ ) )
-        nAccessRW = O_WRONLY;
+        uFlags = osl_File_OpenFlag_Write;
     else
-        nAccessRW = O_RDWR;
+        uFlags = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
 
-    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_NOCREATE )) && ( uFlags != osl_File_OpenFlag_Read ) )
+        uFlags |= osl_File_OpenFlag_Create;
     if ( nOpenMode & STREAM_TRUNC )
-        nAccess |= O_TRUNC;
+        uFlags |= osl_File_OpenFlag_Trunc;
+
+    uFlags |= osl_File_OpenFlag_NoExcl | osl_File_OpenFlag_NoLock;
 
-    nMode = S_IRUSR | S_IROTH | S_IRGRP;
     if ( nOpenMode & STREAM_WRITE)
     {
-      nMode |= (S_IWUSR | S_IWOTH | S_IWGRP);
-
       if ( nOpenMode & STREAM_COPY_ON_SYMLINK )
           {
           if ( bStatValid  &&  S_ISLNK( buf.st_mode ) < 0 )
@@ -694,39 +755,36 @@ void SvFileStream::Open( const String& rFilename, StreamMode nOpenMode )
         }
     }
 
+    oslFileError rc = osl_openFilePath( aLocalFilename.getStr(),&nHandleTmp, uFlags );
 
-    nHandleTmp = open(aLocalFilename.getStr(),nAccessRW|nAccess, nMode );
-
-    if ( nHandleTmp == -1 )
+    if ( rc != osl_File_E_None )
     {
-        if ( nAccessRW != O_RDONLY )
+        if ( uFlags & osl_File_OpenFlag_Write )
         {
             // auf Lesen runterschalten
-            nAccessRW = O_RDONLY;
-            nAccess = 0;
-            nMode = S_IRUSR | S_IROTH | S_IRGRP;
-            nHandleTmp =open( aLocalFilename.getStr(),
-                              nAccessRW|nAccess,
-                              nMode );
+            uFlags &= ~osl_File_OpenFlag_Write;
+            rc = osl_openFilePath( aLocalFilename.getStr(),
+                                   &nHandleTmp,
+                                   uFlags );
             }
     }
-    if ( nHandleTmp != -1 )
+    if ( rc == osl_File_E_None )
     {
-        pInstanceData->nHandle = nHandleTmp;
+        pInstanceData->rHandle = nHandleTmp;
         bIsOpen = sal_True;
-        if ( nAccessRW != O_RDONLY )
+        if ( uFlags & osl_File_OpenFlag_Write )
             bIsWritable = sal_True;
 
         if ( !LockFile() ) // ganze Datei
         {
-            close( nHandleTmp );
+            rc = osl_closeFile( nHandleTmp );
             bIsOpen = sal_False;
             bIsWritable = sal_False;
-            pInstanceData->nHandle = 0;
+            pInstanceData->rHandle = 0;
         }
     }
     else
-        SetError( ::GetSvError( errno ) );
+        SetError( ::GetSvError( rc ) );
 }
 
 /*************************************************************************
@@ -750,8 +808,8 @@ void SvFileStream::Close()
 #endif
 
         Flush();
-        close( pInstanceData->nHandle );
-        pInstanceData->nHandle = 0;
+        osl_closeFile( pInstanceData->rHandle );
+        pInstanceData->rHandle = 0;
     }
 
     bIsOpen     = sal_False;
@@ -786,58 +844,10 @@ void SvFileStream::SetSize (sal_Size nSize)
 {
     if (IsOpen())
     {
-        int fd = pInstanceData->nHandle;
-        if (::ftruncate (fd, (off_t)nSize) < 0)
+        oslFileError rc = osl_setFileSize( pInstanceData->rHandle, nSize );
+        if (rc != osl_File_E_None )
         {
-            // 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;
-            }
+            SetError ( ::GetSvError( rc ));
         }
     }
 }
commit a64db11b6ca1c0c99937cd99129758dbbe575ac2
Author: Tor Lillqvist <tlillqvist at suse.com>
Date:   Tue Jan 17 12:45:45 2012 +0200

    Add some non-public API to be used by SvFileStream
    
    Having SvFileStream call the file opening etc functions here, instead
    of calling open() directly itself, means we won't have to duplicate
    the Android .apk hooks there, too.

diff --git a/sal/Package_inc.mk b/sal/Package_inc.mk
index e4dd529..7a5a77c 100644
--- a/sal/Package_inc.mk
+++ b/sal/Package_inc.mk
@@ -63,6 +63,7 @@ $(eval $(call gb_Package_add_file,sal_inc,inc/osl/thread.h,osl/thread.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/osl/thread.hxx,osl/thread.hxx))
 $(eval $(call gb_Package_add_file,sal_inc,inc/osl/time.h,osl/time.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/osl/util.h,osl/util.h))
+$(eval $(call gb_Package_add_file,sal_inc,inc/osl/detail/file.h,osl/detail/file.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/allocator.hxx,rtl/allocator.hxx))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/alloc.h,rtl/alloc.h))
 $(eval $(call gb_Package_add_file,sal_inc,inc/rtl/bootstrap.h,rtl/bootstrap.h))
diff --git a/sal/inc/osl/detail/file.h b/sal/inc/osl/detail/file.h
new file mode 100644
index 0000000..19415a2
--- /dev/null
+++ b/sal/inc/osl/detail/file.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2012 Tor Lillqvist <tml at iki.fi> (initial developer)
+ * Copyright (C) 2012 SUSE Linux http://suse.com (initial developer's employer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef INCLUDED_OSL_DETAIL_FILE_H
+#define INCLUDED_OSL_DETAIL_FILE_H
+
+#include <sys/stat.h>
+#include "sal/types.h"
+
+/** @cond INTERNAL */
+
+/* Some additions to the osl file functions for LibreOffice internal
+   use. Needed for details in the Android support.
+ */
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/* More flags needed for semantics that match the open() call that
+   used to be in SvFileStream::Open().
+*/
+#define osl_File_OpenFlag_Trunc     0x00000010L
+#define osl_File_OpenFlag_NoExcl    0x00000020L
+
+/* Variant of osl_openFile that takes the file pathname directly as a
+   char*
+*/
+
+SAL_DLLPUBLIC oslFileError SAL_CALL osl_openFilePath(
+    const char *cpFilePath,
+    oslFileHandle *pHandle,
+    sal_uInt32 uFlags );
+
+/* Wrappers for stat() and lstat() with Android-specific hook
+   for files inside the .apk.
+*/
+
+SAL_DLLPUBLIC oslFileError SAL_CALL osl_statFilePath(
+    const char *cpFilePath,
+    struct stat *statb );
+
+SAL_DLLPUBLIC oslFileError SAL_CALL osl_lstatFilePath(
+    const char *cpFilePath,
+    struct stat *statb );
+
+/*  Get the OS specific "handle" of an open file. */
+
+SAL_DLLPUBLIC oslFileError SAL_CALL osl_getFileOSHandle(
+    oslFileHandle Handle,
+    sal_IntPtr *piFileHandle );
+
+#if defined __cplusplus
+}
+#endif
+
+/** @endcond */
+
+#endif /* INCLUDED_OSL_DETAIL_FILE_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/unx/file.cxx b/sal/osl/unx/file.cxx
index 4bb30cf..64ce977 100644
--- a/sal/osl/unx/file.cxx
+++ b/sal/osl/unx/file.cxx
@@ -28,6 +28,7 @@
 
 
 #include "osl/file.hxx"
+#include "osl/detail/file.h"
 
 #include "osl/diagnose.h"
 #include "rtl/alloc.h"
@@ -885,40 +886,27 @@ SAL_CALL osl_openMemoryAsFile( void *address, size_t size, oslFileHandle *pHandl
  ***************************************************************************/
 #ifdef HAVE_O_EXLOCK
 #define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK )
-#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK )
+#define OPEN_CREATE_FLAGS ( O_CREAT | O_RDWR | O_EXLOCK | O_NONBLOCK )
 #else
 #define OPEN_WRITE_FLAGS ( O_RDWR )
-#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
+#define OPEN_CREATE_FLAGS ( O_CREAT | O_RDWR )
 #endif
 
 oslFileError
-SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
+SAL_CALL osl_openFilePath( const char *cpFilePath, oslFileHandle* pHandle, sal_uInt32 uFlags )
 {
     oslFileError eRet;
 
-    if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0))
-        return osl_File_E_INVAL;
-
-    /* convert file URL to system path */
-    char buffer[PATH_MAX];
-    eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL);
-    if (eRet != osl_File_E_None)
-        return eRet;
-#ifdef MACOSX
-    if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0)
-        return oslTranslateFileError (OSL_FET_ERROR, errno);
-#endif /* MACOSX */
-
 #ifdef ANDROID
     /* Opening a file from /assets read-only means
      * we should mmap it from the .apk file
      */
     if (!(uFlags & osl_File_OpenFlag_Write) &&
-        strncmp (buffer, "/assets/", sizeof ("/assets/") - 1) == 0)
+        strncmp (cpFilePath, "/assets/", sizeof ("/assets/") - 1) == 0)
     {
         void *address;
         size_t size;
-        address = lo_apkentry(buffer, &size);
+        address = lo_apkentry(cpFilePath, &size);
         return osl_openMemoryAsFile(address, size, pHandle);
     }
 #endif
@@ -936,6 +924,13 @@ SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uIn
         mode |= S_IWUSR | S_IWGRP | S_IWOTH;
         flags = OPEN_CREATE_FLAGS;
     }
+
+    /* Check for flags passed in from SvFileStream::Open() */
+    if (uFlags & osl_File_OpenFlag_Trunc)
+        flags |= O_TRUNC;
+    if (!(uFlags & osl_File_OpenFlag_NoExcl))
+        flags |= O_EXCL;
+
     if (uFlags & osl_File_OpenFlag_NoLock)
     {
 #ifdef HAVE_O_EXLOCK
@@ -944,11 +939,11 @@ SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uIn
     }
     else
     {
-        flags = osl_file_adjustLockFlags (buffer, flags);
+        flags = osl_file_adjustLockFlags (cpFilePath, flags);
     }
 
     /* open the file */
-    int fd = open( buffer, flags, mode );
+    int fd = open( cpFilePath, flags, mode );
     if (-1 == fd)
         return oslTranslateFileError (OSL_FET_ERROR, errno);
 
@@ -1018,7 +1013,7 @@ SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uIn
     }
 
     /* allocate memory for impl structure */
-    FileHandle_Impl * pImpl = new FileHandle_Impl (fd, FileHandle_Impl::KIND_FD, buffer);
+    FileHandle_Impl * pImpl = new FileHandle_Impl (fd, FileHandle_Impl::KIND_FD, cpFilePath);
     if (!pImpl)
     {
         eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM);
@@ -1037,6 +1032,28 @@ SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uIn
     return osl_File_E_None;
 }
 
+oslFileError
+SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
+{
+    oslFileError eRet;
+
+    if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0))
+        return osl_File_E_INVAL;
+
+    /* convert file URL to system path */
+    char buffer[PATH_MAX];
+    eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL);
+    if (eRet != osl_File_E_None)
+        return eRet;
+
+#ifdef MACOSX
+    if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0)
+        return oslTranslateFileError (OSL_FET_ERROR, errno);
+#endif /* MACOSX */
+
+    return osl_openFilePath (buffer, pHandle, uFlags);
+}
+
 /****************************************************************************/
 /*  osl_closeFile */
 /****************************************************************************/
@@ -1104,6 +1121,24 @@ SAL_CALL osl_syncFile(oslFileHandle Handle)
     return osl_File_E_None;
 }
 
+/************************************************
+ * osl_fileGetOSHandle
+ ***********************************************/
+oslFileError
+SAL_CALL osl_getFileOSHandle(
+    oslFileHandle Handle,
+    sal_IntPtr *piFileHandle )
+{
+    FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
+
+    if (0 == pImpl || pImpl->m_kind != FileHandle_Impl::KIND_FD || -1 == pImpl->m_fd)
+        return osl_File_E_INVAL;
+
+    *piFileHandle = pImpl->m_fd;
+
+    return osl_File_E_None;
+}
+
 /*******************************************
     osl_mapFile
 ********************************************/
diff --git a/sal/osl/unx/file_stat.cxx b/sal/osl/unx/file_stat.cxx
index ffeb885..9cbb39a 100644
--- a/sal/osl/unx/file_stat.cxx
+++ b/sal/osl/unx/file_stat.cxx
@@ -28,6 +28,7 @@
 
 
 #include "osl/file.h"
+#include "osl/detail/file.h"
 
 #include "system.h"
 #include <sys/types.h>
@@ -447,4 +448,26 @@ oslFileError SAL_CALL osl_setFileTime (
     return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
 }
 
+oslFileError
+SAL_CALL osl_statFilePath( const char *cpFilePath, struct stat *statb )
+{
+    int rc = stat_c( cpFilePath, statb );
+
+    if (rc == -1)
+        return oslTranslateFileError(OSL_FET_ERROR, errno);
+    else
+        return osl_File_E_None;
+}
+
+oslFileError
+SAL_CALL osl_lstatFilePath( const char *cpFilePath, struct stat *statb )
+{
+    int rc = lstat_c( cpFilePath, statb );
+
+    if (rc == -1)
+        return oslTranslateFileError(OSL_FET_ERROR, errno);
+    else
+        return osl_File_E_None;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/unx/uunxapi.cxx b/sal/osl/unx/uunxapi.cxx
index 86e86e2..8abe57f 100644
--- a/sal/osl/unx/uunxapi.cxx
+++ b/sal/osl/unx/uunxapi.cxx
@@ -145,18 +145,38 @@
  }
 
  //#########################
+ //stat_c
+  int stat_c(const char* cpPath, struct stat* buf)
+ {
+#ifdef ANDROID
+    if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
+        (cpPath[sizeof("/assets")-1] == '\0' ||
+         cpPath[sizeof("/assets")-1] == '/'))
+        return lo_apk_lstat(cpPath, buf);
+#endif
+    return stat(cpPath, buf);
+ }
+
+ //#########################
+ //lstat_c
+  int lstat_c(const char* cpPath, struct stat* buf)
+ {
+#ifdef ANDROID
+    if (strncmp(cpPath, "/assets", sizeof("/assets")-1) == 0 &&
+        (cpPath[sizeof("/assets")-1] == '\0' ||
+         cpPath[sizeof("/assets")-1] == '/'))
+        return lo_apk_lstat(cpPath, buf);
+#endif
+    return lstat(cpPath, buf);
+ }
+
+ //#########################
  //lstat_u
   int lstat_u(const rtl_uString* pustrPath, struct stat* buf)
  {
 #ifndef MACOSX  // not MACOSX
     rtl::OString fn = OUStringToOString(pustrPath);
-#ifdef ANDROID
-    if (strncmp(fn.getStr(), "/assets", sizeof("/assets")-1) == 0 &&
-        (fn.getStr()[sizeof("/assets")-1] == '\0' ||
-         fn.getStr()[sizeof("/assets")-1] == '/'))
-        return lo_apk_lstat(fn.getStr(), buf);
-#endif
-    return lstat(fn.getStr(), buf);
+    return lstat_c(fn.getStr(), buf);
 #else
     return lstat(macxp_resolveAliasAndConvert(pustrPath).getStr(), buf);
 #endif
diff --git a/sal/osl/unx/uunxapi.h b/sal/osl/unx/uunxapi.h
index 9ac7ddd..3696ab4 100644
--- a/sal/osl/unx/uunxapi.h
+++ b/sal/osl/unx/uunxapi.h
@@ -72,6 +72,12 @@
      const rtl_uString* pustrFileName,
     rtl_uString** ppustrResolvedName);
 
+ /* @see stat */
+ int stat_c(const char *cpPath, struct stat* buf);
+
+ /* @see lstat */
+ int lstat_c(const char *cpPath, struct stat* buf);
+
  /* @see lstat */
  int lstat_u(const rtl_uString* pustrPath, struct stat* buf);
 
diff --git a/sal/osl/w32/file.cxx b/sal/osl/w32/file.cxx
index 5e73dbf..e581a11 100644
--- a/sal/osl/w32/file.cxx
+++ b/sal/osl/w32/file.cxx
@@ -767,6 +767,22 @@ SAL_CALL osl_syncFile(oslFileHandle Handle)
 
 //#############################################
 oslFileError
+SAL_CALL osl_getFileOSHandle(
+    oslFileHandle  Handle,
+    sal_IntPtr    *piFileHandle )
+{
+    FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
+
+    if (0 == pImpl || !IsValidHandle(pImpl->m_hFile))
+        return osl_File_E_INVAL;
+
+    *piFileHandle = (sal_IntPtr) pImpl->m_hFile;
+
+    return osl_File_E_None;
+}
+
+//#############################################
+oslFileError
 SAL_CALL osl_closeFile(oslFileHandle Handle)
 {
     FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
diff --git a/sal/util/sal.map b/sal/util/sal.map
index a22661c..879d252 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -645,6 +645,14 @@ PRIVATE_textenc.1 { # LibreOffice 3.6
         _ZN3sal6detail7textenc37handleBadInputUnicodeToTextConversion*;
 };
 
+PRIVATE_file.1 { # LibreOffice 3.6
+    global:
+        osl_openFilePath;
+        osl_statFilePath;
+        osl_lstatFilePath;
+        osl_getFileOSHandle;
+};
+
 # Unique libstdc++ symbols:
 GLIBCXX_3.4 {
     global:


More information about the Libreoffice-commits mailing list