1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sal.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "osl/file.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "osl/diagnose.h" 34*cdf0e10cSrcweir #include "rtl/alloc.h" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "system.h" 37*cdf0e10cSrcweir #include "file_error_transl.h" 38*cdf0e10cSrcweir #include "file_url.h" 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <algorithm> 41*cdf0e10cSrcweir #include <limits> 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir #include <string.h> 44*cdf0e10cSrcweir #include <pthread.h> 45*cdf0e10cSrcweir #include <sys/mman.h> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #if defined(MACOSX) 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include <sys/param.h> 50*cdf0e10cSrcweir #include <sys/mount.h> 51*cdf0e10cSrcweir #define HAVE_O_EXLOCK 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir // add MACOSX Time Value 54*cdf0e10cSrcweir #define TimeValue CFTimeValue 55*cdf0e10cSrcweir #include <CoreFoundation/CoreFoundation.h> 56*cdf0e10cSrcweir #undef TimeValue 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir #endif /* MACOSX */ 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir #ifdef DEBUG_OSL_FILE 61*cdf0e10cSrcweir # define OSL_FILE_TRACE 0 ? (void)(0) : osl_trace 62*cdf0e10cSrcweir # define PERROR( a, b ) perror( a ); fprintf( stderr, b ) 63*cdf0e10cSrcweir #else 64*cdf0e10cSrcweir # define OSL_FILE_TRACE 1 ? (void)(0) : osl_trace 65*cdf0e10cSrcweir # define PERROR( a, b ) 66*cdf0e10cSrcweir #endif 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir /******************************************************************* 69*cdf0e10cSrcweir * 70*cdf0e10cSrcweir * FileHandle_Impl interface 71*cdf0e10cSrcweir * 72*cdf0e10cSrcweir ******************************************************************/ 73*cdf0e10cSrcweir struct FileHandle_Impl 74*cdf0e10cSrcweir { 75*cdf0e10cSrcweir pthread_mutex_t m_mutex; 76*cdf0e10cSrcweir rtl_String * m_strFilePath; /* holds native file path */ 77*cdf0e10cSrcweir int m_fd; 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir /** State 80*cdf0e10cSrcweir */ 81*cdf0e10cSrcweir enum StateBits 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir STATE_SEEKABLE = 1, /* default */ 84*cdf0e10cSrcweir STATE_READABLE = 2, /* default */ 85*cdf0e10cSrcweir STATE_WRITEABLE = 4, /* open() sets, write() requires, else osl_File_E_BADF */ 86*cdf0e10cSrcweir STATE_MODIFIED = 8 /* write() sets, flush() resets */ 87*cdf0e10cSrcweir }; 88*cdf0e10cSrcweir int m_state; 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir sal_uInt64 m_size; /* file size */ 91*cdf0e10cSrcweir off_t m_offset; /* physical offset from begin of file */ 92*cdf0e10cSrcweir off_t m_fileptr; /* logical offset from begin of file */ 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir off_t m_bufptr; /* buffer offset from begin of file */ 95*cdf0e10cSrcweir size_t m_buflen; /* buffer filled [0, m_bufsiz - 1] */ 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir size_t m_bufsiz; 98*cdf0e10cSrcweir sal_uInt8 * m_buffer; 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir explicit FileHandle_Impl (int fd, char const * path = "<anon>"); 101*cdf0e10cSrcweir ~FileHandle_Impl(); 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir static void* operator new (size_t n); 104*cdf0e10cSrcweir static void operator delete (void * p, size_t); 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir static size_t getpagesize(); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir sal_uInt64 getPos() const; 109*cdf0e10cSrcweir oslFileError setPos (sal_uInt64 uPos); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir sal_uInt64 getSize() const; 112*cdf0e10cSrcweir oslFileError setSize (sal_uInt64 uSize); 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir oslFileError readAt ( 115*cdf0e10cSrcweir off_t nOffset, 116*cdf0e10cSrcweir void * pBuffer, 117*cdf0e10cSrcweir size_t nBytesRequested, 118*cdf0e10cSrcweir sal_uInt64 * pBytesRead); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir oslFileError writeAt ( 121*cdf0e10cSrcweir off_t nOffset, 122*cdf0e10cSrcweir void const * pBuffer, 123*cdf0e10cSrcweir size_t nBytesToWrite, 124*cdf0e10cSrcweir sal_uInt64 * pBytesWritten); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir oslFileError readFileAt ( 127*cdf0e10cSrcweir off_t nOffset, 128*cdf0e10cSrcweir void * pBuffer, 129*cdf0e10cSrcweir size_t nBytesRequested, 130*cdf0e10cSrcweir sal_uInt64 * pBytesRead); 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir oslFileError writeFileAt ( 133*cdf0e10cSrcweir off_t nOffset, 134*cdf0e10cSrcweir void const * pBuffer, 135*cdf0e10cSrcweir size_t nBytesToWrite, 136*cdf0e10cSrcweir sal_uInt64 * pBytesWritten); 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir oslFileError readLineAt ( 139*cdf0e10cSrcweir off_t nOffset, 140*cdf0e10cSrcweir sal_Sequence ** ppSequence, 141*cdf0e10cSrcweir sal_uInt64 * pBytesRead); 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir oslFileError writeSequence_Impl ( 144*cdf0e10cSrcweir sal_Sequence ** ppSequence, 145*cdf0e10cSrcweir size_t * pnOffset, 146*cdf0e10cSrcweir const void * pBuffer, 147*cdf0e10cSrcweir size_t nBytes); 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir oslFileError syncFile(); 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir /** Buffer cache / allocator. 152*cdf0e10cSrcweir */ 153*cdf0e10cSrcweir class Allocator 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir rtl_cache_type * m_cache; 156*cdf0e10cSrcweir size_t m_bufsiz; 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir Allocator (Allocator const &); 159*cdf0e10cSrcweir Allocator & operator= (Allocator const &); 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir public: 162*cdf0e10cSrcweir static Allocator & get(); 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir void allocate (sal_uInt8 ** ppBuffer, size_t * pnSize); 165*cdf0e10cSrcweir void deallocate (sal_uInt8 * pBuffer); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir protected: 168*cdf0e10cSrcweir Allocator(); 169*cdf0e10cSrcweir ~Allocator(); 170*cdf0e10cSrcweir }; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir /** Guard. 173*cdf0e10cSrcweir */ 174*cdf0e10cSrcweir class Guard 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir pthread_mutex_t * m_mutex; 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir public: 179*cdf0e10cSrcweir explicit Guard(pthread_mutex_t * pMutex); 180*cdf0e10cSrcweir ~Guard(); 181*cdf0e10cSrcweir }; 182*cdf0e10cSrcweir }; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir /******************************************************************* 185*cdf0e10cSrcweir * 186*cdf0e10cSrcweir * FileHandle_Impl implementation 187*cdf0e10cSrcweir * 188*cdf0e10cSrcweir ******************************************************************/ 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir FileHandle_Impl::Allocator & 191*cdf0e10cSrcweir FileHandle_Impl::Allocator::get() 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir static Allocator g_aBufferAllocator; 194*cdf0e10cSrcweir return g_aBufferAllocator; 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir FileHandle_Impl::Allocator::Allocator() 198*cdf0e10cSrcweir : m_cache (0), 199*cdf0e10cSrcweir m_bufsiz (0) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir size_t const pagesize = FileHandle_Impl::getpagesize(); 202*cdf0e10cSrcweir if (size_t(-1) != pagesize) 203*cdf0e10cSrcweir { 204*cdf0e10cSrcweir m_cache = rtl_cache_create ( 205*cdf0e10cSrcweir "osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0); 206*cdf0e10cSrcweir if (0 != m_cache) 207*cdf0e10cSrcweir m_bufsiz = pagesize; 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir FileHandle_Impl::Allocator::~Allocator() 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir rtl_cache_destroy (m_cache), m_cache = 0; 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, size_t * pnSize) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation"); 218*cdf0e10cSrcweir if ((0 != ppBuffer) && (0 != pnSize)) 219*cdf0e10cSrcweir *ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz; 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir if (0 != pBuffer) 224*cdf0e10cSrcweir rtl_cache_free (m_cache, pBuffer); 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir FileHandle_Impl::Guard::Guard(pthread_mutex_t * pMutex) 228*cdf0e10cSrcweir : m_mutex (pMutex) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::Guard(): null pointer."); 231*cdf0e10cSrcweir (void) pthread_mutex_lock (m_mutex); // ignoring EINVAL ... 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir FileHandle_Impl::Guard::~Guard() 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir OSL_PRECOND (m_mutex != 0, "FileHandle_Impl::Guard::~Guard(): null pointer."); 236*cdf0e10cSrcweir (void) pthread_mutex_unlock (m_mutex); 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir FileHandle_Impl::FileHandle_Impl (int fd, char const * path) 240*cdf0e10cSrcweir : m_strFilePath (0), 241*cdf0e10cSrcweir m_fd (fd), 242*cdf0e10cSrcweir m_state (STATE_SEEKABLE | STATE_READABLE), 243*cdf0e10cSrcweir m_size (0), 244*cdf0e10cSrcweir m_offset (0), 245*cdf0e10cSrcweir m_fileptr (0), 246*cdf0e10cSrcweir m_bufptr (-1), 247*cdf0e10cSrcweir m_buflen (0), 248*cdf0e10cSrcweir m_bufsiz (0), 249*cdf0e10cSrcweir m_buffer (0) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir (void) pthread_mutex_init(&m_mutex, 0); 252*cdf0e10cSrcweir rtl_string_newFromStr (&m_strFilePath, path); 253*cdf0e10cSrcweir Allocator::get().allocate (&m_buffer, &m_bufsiz); 254*cdf0e10cSrcweir if (0 != m_buffer) 255*cdf0e10cSrcweir memset (m_buffer, 0, m_bufsiz); 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir FileHandle_Impl::~FileHandle_Impl() 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir Allocator::get().deallocate (m_buffer), m_buffer = 0; 260*cdf0e10cSrcweir rtl_string_release (m_strFilePath), m_strFilePath = 0; 261*cdf0e10cSrcweir (void) pthread_mutex_destroy(&m_mutex); // ignoring EBUSY ... 262*cdf0e10cSrcweir } 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir void* FileHandle_Impl::operator new (size_t n) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir return rtl_allocateMemory(n); 267*cdf0e10cSrcweir } 268*cdf0e10cSrcweir void FileHandle_Impl::operator delete (void * p, size_t) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir rtl_freeMemory(p); 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir size_t FileHandle_Impl::getpagesize() 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX) 276*cdf0e10cSrcweir return sal::static_int_cast< size_t >(::getpagesize()); 277*cdf0e10cSrcweir #else /* POSIX */ 278*cdf0e10cSrcweir return sal::static_int_cast< size_t >(::sysconf(_SC_PAGESIZE)); 279*cdf0e10cSrcweir #endif /* xBSD || POSIX */ 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir sal_uInt64 FileHandle_Impl::getPos() const 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir return sal::static_int_cast< sal_uInt64 >(m_fileptr); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos) 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir OSL_FILE_TRACE("FileHandle_Impl::setPos(%d, %lld) => %lld", m_fd, getPos(), uPos); 290*cdf0e10cSrcweir m_fileptr = sal::static_int_cast< off_t >(uPos); 291*cdf0e10cSrcweir return osl_File_E_None; 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir sal_uInt64 FileHandle_Impl::getSize() const 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir off_t const bufend = std::max((off_t)(0), m_bufptr) + m_buflen; 297*cdf0e10cSrcweir return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend)); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir off_t const nSize = sal::static_int_cast< off_t >(uSize); 303*cdf0e10cSrcweir if (-1 == ftruncate (m_fd, nSize)) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir /* Failure. Save original result. Try fallback algorithm */ 306*cdf0e10cSrcweir oslFileError result = oslTranslateFileError (OSL_FET_ERROR, errno); 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir /* Check against current size. Fail upon 'shrink' */ 309*cdf0e10cSrcweir if (uSize <= getSize()) 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir /* Failure upon 'shrink'. Return original result */ 312*cdf0e10cSrcweir return (result); 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir /* Save current position */ 316*cdf0e10cSrcweir off_t const nCurPos = (off_t)lseek (m_fd, (off_t)0, SEEK_CUR); 317*cdf0e10cSrcweir if (nCurPos == (off_t)(-1)) 318*cdf0e10cSrcweir return (result); 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir /* Try 'expand' via 'lseek()' and 'write()' */ 321*cdf0e10cSrcweir if (-1 == lseek (m_fd, (off_t)(nSize - 1), SEEK_SET)) 322*cdf0e10cSrcweir return (result); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir if (-1 == write (m_fd, (char*)"", (size_t)1)) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir /* Failure. Restore saved position */ 327*cdf0e10cSrcweir (void) lseek (m_fd, (off_t)(nCurPos), SEEK_SET); 328*cdf0e10cSrcweir return (result); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir 331*cdf0e10cSrcweir /* Success. Restore saved position */ 332*cdf0e10cSrcweir if (-1 == lseek (m_fd, (off_t)nCurPos, SEEK_SET)) 333*cdf0e10cSrcweir return (result); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir OSL_FILE_TRACE("osl_setFileSize(%d, %lld) => %ld", m_fd, getSize(), nSize); 337*cdf0e10cSrcweir m_size = sal::static_int_cast< sal_uInt64 >(nSize); 338*cdf0e10cSrcweir return osl_File_E_None; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir oslFileError FileHandle_Impl::readAt ( 342*cdf0e10cSrcweir off_t nOffset, 343*cdf0e10cSrcweir void * pBuffer, 344*cdf0e10cSrcweir size_t nBytesRequested, 345*cdf0e10cSrcweir sal_uInt64 * pBytesRead) 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::readAt(): not seekable"); 348*cdf0e10cSrcweir if (!(m_state & STATE_SEEKABLE)) 349*cdf0e10cSrcweir return osl_File_E_SPIPE; 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir OSL_PRECOND((m_state & STATE_READABLE), "FileHandle_Impl::readAt(): not readable"); 352*cdf0e10cSrcweir if (!(m_state & STATE_READABLE)) 353*cdf0e10cSrcweir return osl_File_E_BADF; 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir #if defined(LINUX) || defined(SOLARIS) 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir ssize_t nBytes = ::pread (m_fd, pBuffer, nBytesRequested, nOffset); 358*cdf0e10cSrcweir if ((-1 == nBytes) && (EOVERFLOW == errno)) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir /* Some 'pread()'s fail with EOVERFLOW when reading at (or past) 361*cdf0e10cSrcweir * end-of-file, different from 'lseek() + read()' behaviour. 362*cdf0e10cSrcweir * Returning '0 bytes read' and 'osl_File_E_None' instead. 363*cdf0e10cSrcweir */ 364*cdf0e10cSrcweir nBytes = 0; 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir if (-1 == nBytes) 367*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir #else /* !(LINUX || SOLARIS) */ 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir if (nOffset != m_offset) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir if (-1 == ::lseek (m_fd, nOffset, SEEK_SET)) 374*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 375*cdf0e10cSrcweir m_offset = nOffset; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested); 379*cdf0e10cSrcweir if (-1 == nBytes) 380*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 381*cdf0e10cSrcweir m_offset += nBytes; 382*cdf0e10cSrcweir 383*cdf0e10cSrcweir #endif /* !(LINUX || SOLARIS) */ 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir OSL_FILE_TRACE("FileHandle_Impl::readAt(%d, %lld, %ld)", m_fd, nOffset, nBytes); 386*cdf0e10cSrcweir *pBytesRead = nBytes; 387*cdf0e10cSrcweir return osl_File_E_None; 388*cdf0e10cSrcweir } 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir oslFileError FileHandle_Impl::writeAt ( 391*cdf0e10cSrcweir off_t nOffset, 392*cdf0e10cSrcweir void const * pBuffer, 393*cdf0e10cSrcweir size_t nBytesToWrite, 394*cdf0e10cSrcweir sal_uInt64 * pBytesWritten) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::writeAt(): not seekable"); 397*cdf0e10cSrcweir if (!(m_state & STATE_SEEKABLE)) 398*cdf0e10cSrcweir return osl_File_E_SPIPE; 399*cdf0e10cSrcweir 400*cdf0e10cSrcweir OSL_PRECOND((m_state & STATE_WRITEABLE), "FileHandle_Impl::writeAt(): not writeable"); 401*cdf0e10cSrcweir if (!(m_state & STATE_WRITEABLE)) 402*cdf0e10cSrcweir return osl_File_E_BADF; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir #if defined(LINUX) || defined(SOLARIS) 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir ssize_t nBytes = ::pwrite (m_fd, pBuffer, nBytesToWrite, nOffset); 407*cdf0e10cSrcweir if (-1 == nBytes) 408*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir #else /* !(LINUX || SOLARIS) */ 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir if (nOffset != m_offset) 413*cdf0e10cSrcweir { 414*cdf0e10cSrcweir if (-1 == ::lseek (m_fd, nOffset, SEEK_SET)) 415*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 416*cdf0e10cSrcweir m_offset = nOffset; 417*cdf0e10cSrcweir } 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite); 420*cdf0e10cSrcweir if (-1 == nBytes) 421*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 422*cdf0e10cSrcweir m_offset += nBytes; 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir #endif /* !(LINUX || SOLARIS) */ 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir OSL_FILE_TRACE("FileHandle_Impl::writeAt(%d, %lld, %ld)", m_fd, nOffset, nBytes); 427*cdf0e10cSrcweir m_size = std::max (m_size, sal::static_int_cast< sal_uInt64 >(nOffset + nBytes)); 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir *pBytesWritten = nBytes; 430*cdf0e10cSrcweir return osl_File_E_None; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir oslFileError FileHandle_Impl::readFileAt ( 434*cdf0e10cSrcweir off_t nOffset, 435*cdf0e10cSrcweir void * pBuffer, 436*cdf0e10cSrcweir size_t nBytesRequested, 437*cdf0e10cSrcweir sal_uInt64 * pBytesRead) 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir if (0 == (m_state & STATE_SEEKABLE)) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir // not seekable (pipe) 442*cdf0e10cSrcweir ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested); 443*cdf0e10cSrcweir if (-1 == nBytes) 444*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 445*cdf0e10cSrcweir *pBytesRead = nBytes; 446*cdf0e10cSrcweir return osl_File_E_None; 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir else if (0 == m_buffer) 449*cdf0e10cSrcweir { 450*cdf0e10cSrcweir // not buffered 451*cdf0e10cSrcweir return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead); 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir else 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir sal_uInt8 * buffer = static_cast<sal_uInt8*>(pBuffer); 456*cdf0e10cSrcweir for (*pBytesRead = 0; nBytesRequested > 0; ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz; 459*cdf0e10cSrcweir size_t const bufpos = (nOffset % m_bufsiz); 460*cdf0e10cSrcweir 461*cdf0e10cSrcweir if (bufptr != m_bufptr) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir // flush current buffer 464*cdf0e10cSrcweir oslFileError result = syncFile(); 465*cdf0e10cSrcweir if (result != osl_File_E_None) 466*cdf0e10cSrcweir return (result); 467*cdf0e10cSrcweir m_bufptr = -1, m_buflen = 0; 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir if (nBytesRequested >= m_bufsiz) 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir // buffer too small, read through from file 472*cdf0e10cSrcweir sal_uInt64 uDone = 0; 473*cdf0e10cSrcweir result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone); 474*cdf0e10cSrcweir if (result != osl_File_E_None) 475*cdf0e10cSrcweir return (result); 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir nBytesRequested -= uDone, *pBytesRead += uDone; 478*cdf0e10cSrcweir return osl_File_E_None; 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir 481*cdf0e10cSrcweir // update buffer (pointer) 482*cdf0e10cSrcweir sal_uInt64 uDone = 0; 483*cdf0e10cSrcweir result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); 484*cdf0e10cSrcweir if (result != osl_File_E_None) 485*cdf0e10cSrcweir return (result); 486*cdf0e10cSrcweir m_bufptr = bufptr, m_buflen = uDone; 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir if (bufpos >= m_buflen) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir // end of file 491*cdf0e10cSrcweir return osl_File_E_None; 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir size_t const bytes = std::min (m_buflen - bufpos, nBytesRequested); 495*cdf0e10cSrcweir OSL_FILE_TRACE("FileHandle_Impl::readFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes); 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes); 498*cdf0e10cSrcweir nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir return osl_File_E_None; 501*cdf0e10cSrcweir } 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir oslFileError FileHandle_Impl::writeFileAt ( 505*cdf0e10cSrcweir off_t nOffset, 506*cdf0e10cSrcweir void const * pBuffer, 507*cdf0e10cSrcweir size_t nBytesToWrite, 508*cdf0e10cSrcweir sal_uInt64 * pBytesWritten) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir if (0 == (m_state & STATE_SEEKABLE)) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir // not seekable (pipe) 513*cdf0e10cSrcweir ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite); 514*cdf0e10cSrcweir if (-1 == nBytes) 515*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 516*cdf0e10cSrcweir *pBytesWritten = nBytes; 517*cdf0e10cSrcweir return osl_File_E_None; 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir else if (0 == m_buffer) 520*cdf0e10cSrcweir { 521*cdf0e10cSrcweir // not buffered 522*cdf0e10cSrcweir return writeAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten); 523*cdf0e10cSrcweir } 524*cdf0e10cSrcweir else 525*cdf0e10cSrcweir { 526*cdf0e10cSrcweir sal_uInt8 const * buffer = static_cast<sal_uInt8 const *>(pBuffer); 527*cdf0e10cSrcweir for (*pBytesWritten = 0; nBytesToWrite > 0; ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz; 530*cdf0e10cSrcweir size_t const bufpos = (nOffset % m_bufsiz); 531*cdf0e10cSrcweir if (bufptr != m_bufptr) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir // flush current buffer 534*cdf0e10cSrcweir oslFileError result = syncFile(); 535*cdf0e10cSrcweir if (result != osl_File_E_None) 536*cdf0e10cSrcweir return (result); 537*cdf0e10cSrcweir m_bufptr = -1, m_buflen = 0; 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir if (nBytesToWrite >= m_bufsiz) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir // buffer to small, write through to file 542*cdf0e10cSrcweir sal_uInt64 uDone = 0; 543*cdf0e10cSrcweir result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone); 544*cdf0e10cSrcweir if (result != osl_File_E_None) 545*cdf0e10cSrcweir return (result); 546*cdf0e10cSrcweir if (uDone != nBytesToWrite) 547*cdf0e10cSrcweir return osl_File_E_IO; 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir nBytesToWrite -= uDone, *pBytesWritten += uDone; 550*cdf0e10cSrcweir return osl_File_E_None; 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir // update buffer (pointer) 554*cdf0e10cSrcweir sal_uInt64 uDone = 0; 555*cdf0e10cSrcweir result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); 556*cdf0e10cSrcweir if (result != osl_File_E_None) 557*cdf0e10cSrcweir return (result); 558*cdf0e10cSrcweir m_bufptr = bufptr, m_buflen = uDone; 559*cdf0e10cSrcweir } 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir size_t const bytes = std::min (m_bufsiz - bufpos, nBytesToWrite); 562*cdf0e10cSrcweir OSL_FILE_TRACE("FileHandle_Impl::writeFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes); 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes); 565*cdf0e10cSrcweir nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes; 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir m_buflen = std::max(m_buflen, bufpos + bytes); 568*cdf0e10cSrcweir m_state |= STATE_MODIFIED; 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir return osl_File_E_None; 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir oslFileError FileHandle_Impl::readLineAt ( 575*cdf0e10cSrcweir off_t nOffset, 576*cdf0e10cSrcweir sal_Sequence ** ppSequence, 577*cdf0e10cSrcweir sal_uInt64 * pBytesRead) 578*cdf0e10cSrcweir { 579*cdf0e10cSrcweir oslFileError result = osl_File_E_None; 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir off_t bufptr = nOffset / m_bufsiz * m_bufsiz; 582*cdf0e10cSrcweir if (bufptr != m_bufptr) 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir /* flush current buffer */ 585*cdf0e10cSrcweir result = syncFile(); 586*cdf0e10cSrcweir if (result != osl_File_E_None) 587*cdf0e10cSrcweir return (result); 588*cdf0e10cSrcweir 589*cdf0e10cSrcweir /* update buffer (pointer) */ 590*cdf0e10cSrcweir sal_uInt64 uDone = 0; 591*cdf0e10cSrcweir result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); 592*cdf0e10cSrcweir if (result != osl_File_E_None) 593*cdf0e10cSrcweir return (result); 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir m_bufptr = bufptr, m_buflen = uDone; 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir static int const LINE_STATE_BEGIN = 0; 599*cdf0e10cSrcweir static int const LINE_STATE_CR = 1; 600*cdf0e10cSrcweir static int const LINE_STATE_LF = 2; 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir size_t bufpos = nOffset - m_bufptr, curpos = bufpos, dstpos = 0; 603*cdf0e10cSrcweir int state = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN; 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir for ( ; state != LINE_STATE_LF; ) 606*cdf0e10cSrcweir { 607*cdf0e10cSrcweir if (curpos >= m_buflen) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir /* buffer examined */ 610*cdf0e10cSrcweir if (0 < (curpos - bufpos)) 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir /* flush buffer to sequence */ 613*cdf0e10cSrcweir result = writeSequence_Impl ( 614*cdf0e10cSrcweir ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos); 615*cdf0e10cSrcweir if (result != osl_File_E_None) 616*cdf0e10cSrcweir return (result); 617*cdf0e10cSrcweir *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos; 618*cdf0e10cSrcweir } 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir bufptr = nOffset / m_bufsiz * m_bufsiz; 621*cdf0e10cSrcweir if (bufptr != m_bufptr) 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir /* update buffer (pointer) */ 624*cdf0e10cSrcweir sal_uInt64 uDone = 0; 625*cdf0e10cSrcweir result = readAt (bufptr, m_buffer, m_bufsiz, &uDone); 626*cdf0e10cSrcweir if (result != osl_File_E_None) 627*cdf0e10cSrcweir return (result); 628*cdf0e10cSrcweir m_bufptr = bufptr, m_buflen = uDone; 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir 631*cdf0e10cSrcweir bufpos = nOffset - m_bufptr, curpos = bufpos; 632*cdf0e10cSrcweir if (bufpos >= m_buflen) 633*cdf0e10cSrcweir break; 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir switch (state) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir case LINE_STATE_CR: 638*cdf0e10cSrcweir state = LINE_STATE_LF; 639*cdf0e10cSrcweir switch (m_buffer[curpos]) 640*cdf0e10cSrcweir { 641*cdf0e10cSrcweir case 0x0A: /* CRLF */ 642*cdf0e10cSrcweir /* eat current char */ 643*cdf0e10cSrcweir curpos++; 644*cdf0e10cSrcweir break; 645*cdf0e10cSrcweir default: /* single CR */ 646*cdf0e10cSrcweir /* keep current char */ 647*cdf0e10cSrcweir break; 648*cdf0e10cSrcweir } 649*cdf0e10cSrcweir break; 650*cdf0e10cSrcweir default: 651*cdf0e10cSrcweir /* determine next state */ 652*cdf0e10cSrcweir switch (m_buffer[curpos]) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir case 0x0A: /* single LF */ 655*cdf0e10cSrcweir state = LINE_STATE_LF; 656*cdf0e10cSrcweir break; 657*cdf0e10cSrcweir case 0x0D: /* CR */ 658*cdf0e10cSrcweir state = LINE_STATE_CR; 659*cdf0e10cSrcweir break; 660*cdf0e10cSrcweir default: /* advance to next char */ 661*cdf0e10cSrcweir curpos++; 662*cdf0e10cSrcweir break; 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir if (state != LINE_STATE_BEGIN) 665*cdf0e10cSrcweir { 666*cdf0e10cSrcweir /* store (and eat) the newline char */ 667*cdf0e10cSrcweir m_buffer[curpos] = 0x0A, curpos++; 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir /* flush buffer to sequence */ 670*cdf0e10cSrcweir result = writeSequence_Impl ( 671*cdf0e10cSrcweir ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1); 672*cdf0e10cSrcweir if (result != osl_File_E_None) 673*cdf0e10cSrcweir return (result); 674*cdf0e10cSrcweir *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos; 675*cdf0e10cSrcweir } 676*cdf0e10cSrcweir break; 677*cdf0e10cSrcweir } 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir 680*cdf0e10cSrcweir result = writeSequence_Impl (ppSequence, &dstpos, 0, 0); 681*cdf0e10cSrcweir if (result != osl_File_E_None) 682*cdf0e10cSrcweir return (result); 683*cdf0e10cSrcweir if (0 < dstpos) 684*cdf0e10cSrcweir return osl_File_E_None; 685*cdf0e10cSrcweir if (bufpos >= m_buflen) 686*cdf0e10cSrcweir return osl_File_E_AGAIN; 687*cdf0e10cSrcweir return osl_File_E_None; 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir 690*cdf0e10cSrcweir oslFileError FileHandle_Impl::writeSequence_Impl ( 691*cdf0e10cSrcweir sal_Sequence ** ppSequence, 692*cdf0e10cSrcweir size_t * pnOffset, 693*cdf0e10cSrcweir const void * pBuffer, 694*cdf0e10cSrcweir size_t nBytes) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir sal_Int32 nElements = *pnOffset + nBytes; 697*cdf0e10cSrcweir if (!*ppSequence) 698*cdf0e10cSrcweir { 699*cdf0e10cSrcweir /* construct sequence */ 700*cdf0e10cSrcweir rtl_byte_sequence_constructNoDefault(ppSequence, nElements); 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir else if (nElements != (*ppSequence)->nElements) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir /* resize sequence */ 705*cdf0e10cSrcweir rtl_byte_sequence_realloc(ppSequence, nElements); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir if (*ppSequence != 0) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir /* fill sequence */ 710*cdf0e10cSrcweir memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes; 711*cdf0e10cSrcweir } 712*cdf0e10cSrcweir return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM; 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir oslFileError FileHandle_Impl::syncFile() 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir oslFileError result = osl_File_E_None; 718*cdf0e10cSrcweir if (m_state & STATE_MODIFIED) 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir sal_uInt64 uDone = 0; 721*cdf0e10cSrcweir result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone); 722*cdf0e10cSrcweir if (result != osl_File_E_None) 723*cdf0e10cSrcweir return (result); 724*cdf0e10cSrcweir if (uDone != m_buflen) 725*cdf0e10cSrcweir return osl_File_E_IO; 726*cdf0e10cSrcweir m_state &= ~STATE_MODIFIED; 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir return (result); 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir 731*cdf0e10cSrcweir /**************************************************************************** 732*cdf0e10cSrcweir * osl_createFileHandleFromFD 733*cdf0e10cSrcweir ***************************************************************************/ 734*cdf0e10cSrcweir extern "C" oslFileHandle osl_createFileHandleFromFD( int fd ) 735*cdf0e10cSrcweir { 736*cdf0e10cSrcweir if (-1 == fd) 737*cdf0e10cSrcweir return 0; // EINVAL 738*cdf0e10cSrcweir 739*cdf0e10cSrcweir struct stat aFileStat; 740*cdf0e10cSrcweir if (-1 == fstat (fd, &aFileStat)) 741*cdf0e10cSrcweir return 0; // EBADF 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir FileHandle_Impl * pImpl = new FileHandle_Impl (fd); 744*cdf0e10cSrcweir if (0 == pImpl) 745*cdf0e10cSrcweir return 0; // ENOMEM 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir // assume writeable 748*cdf0e10cSrcweir pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE; 749*cdf0e10cSrcweir if (!S_ISREG(aFileStat.st_mode)) 750*cdf0e10cSrcweir { 751*cdf0e10cSrcweir /* not a regular file, mark not seekable */ 752*cdf0e10cSrcweir pImpl->m_state &= ~FileHandle_Impl::STATE_SEEKABLE; 753*cdf0e10cSrcweir } 754*cdf0e10cSrcweir else 755*cdf0e10cSrcweir { 756*cdf0e10cSrcweir /* regular file, init current size */ 757*cdf0e10cSrcweir pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size); 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir OSL_FILE_TRACE("osl_createFileHandleFromFD(%d, writeable) => %s", 761*cdf0e10cSrcweir pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath)); 762*cdf0e10cSrcweir return (oslFileHandle)(pImpl); 763*cdf0e10cSrcweir } 764*cdf0e10cSrcweir 765*cdf0e10cSrcweir /******************************************************************* 766*cdf0e10cSrcweir * osl_file_adjustLockFlags 767*cdf0e10cSrcweir ******************************************************************/ 768*cdf0e10cSrcweir static int osl_file_adjustLockFlags (const char * path, int flags) 769*cdf0e10cSrcweir { 770*cdf0e10cSrcweir #ifdef MACOSX 771*cdf0e10cSrcweir /* 772*cdf0e10cSrcweir * The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way 773*cdf0e10cSrcweir * that makes it impossible for OOo to create a backup copy of the 774*cdf0e10cSrcweir * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by 775*cdf0e10cSrcweir * the OOo file handling, so we need to check the path of the file 776*cdf0e10cSrcweir * for the filesystem name. 777*cdf0e10cSrcweir */ 778*cdf0e10cSrcweir struct statfs s; 779*cdf0e10cSrcweir if( 0 <= statfs( path, &s ) ) 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir if( 0 == strncmp("afpfs", s.f_fstypename, 5) ) 782*cdf0e10cSrcweir { 783*cdf0e10cSrcweir flags &= ~O_EXLOCK; 784*cdf0e10cSrcweir flags |= O_SHLOCK; 785*cdf0e10cSrcweir } 786*cdf0e10cSrcweir else 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir /* Needed flags to allow opening a webdav file */ 789*cdf0e10cSrcweir flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK); 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir #endif /* MACOSX */ 793*cdf0e10cSrcweir 794*cdf0e10cSrcweir (void) path; 795*cdf0e10cSrcweir return flags; 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir /**************************************************************************** 799*cdf0e10cSrcweir * osl_file_queryLocking 800*cdf0e10cSrcweir ***************************************************************************/ 801*cdf0e10cSrcweir struct Locking_Impl 802*cdf0e10cSrcweir { 803*cdf0e10cSrcweir int m_enabled; 804*cdf0e10cSrcweir Locking_Impl() : m_enabled(0) 805*cdf0e10cSrcweir { 806*cdf0e10cSrcweir #ifndef HAVE_O_EXLOCK 807*cdf0e10cSrcweir m_enabled = ((getenv("SAL_ENABLE_FILE_LOCKING") != 0) || (getenv("STAR_ENABLE_FILE_LOCKING") != 0)); 808*cdf0e10cSrcweir #endif /* HAVE_O_EXLOCK */ 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir }; 811*cdf0e10cSrcweir static int osl_file_queryLocking (sal_uInt32 uFlags) 812*cdf0e10cSrcweir { 813*cdf0e10cSrcweir if (!(uFlags & osl_File_OpenFlag_NoLock)) 814*cdf0e10cSrcweir { 815*cdf0e10cSrcweir if ((uFlags & osl_File_OpenFlag_Write) || (uFlags & osl_File_OpenFlag_Create)) 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir static Locking_Impl g_locking; 818*cdf0e10cSrcweir return (g_locking.m_enabled != 0); 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir } 821*cdf0e10cSrcweir return 0; 822*cdf0e10cSrcweir } 823*cdf0e10cSrcweir 824*cdf0e10cSrcweir /**************************************************************************** 825*cdf0e10cSrcweir * osl_openFile 826*cdf0e10cSrcweir ***************************************************************************/ 827*cdf0e10cSrcweir #ifdef HAVE_O_EXLOCK 828*cdf0e10cSrcweir #define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK ) 829*cdf0e10cSrcweir #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK ) 830*cdf0e10cSrcweir #else 831*cdf0e10cSrcweir #define OPEN_WRITE_FLAGS ( O_RDWR ) 832*cdf0e10cSrcweir #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR ) 833*cdf0e10cSrcweir #endif 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir oslFileError 836*cdf0e10cSrcweir SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags ) 837*cdf0e10cSrcweir { 838*cdf0e10cSrcweir oslFileError eRet; 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0)) 841*cdf0e10cSrcweir return osl_File_E_INVAL; 842*cdf0e10cSrcweir 843*cdf0e10cSrcweir /* convert file URL to system path */ 844*cdf0e10cSrcweir char buffer[PATH_MAX]; 845*cdf0e10cSrcweir eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL); 846*cdf0e10cSrcweir if (eRet != osl_File_E_None) 847*cdf0e10cSrcweir return eRet; 848*cdf0e10cSrcweir #ifdef MACOSX 849*cdf0e10cSrcweir if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0) 850*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 851*cdf0e10cSrcweir #endif /* MACOSX */ 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir /* set mode and flags */ 854*cdf0e10cSrcweir int mode = S_IRUSR | S_IRGRP | S_IROTH; 855*cdf0e10cSrcweir int flags = O_RDONLY; 856*cdf0e10cSrcweir if (uFlags & osl_File_OpenFlag_Write) 857*cdf0e10cSrcweir { 858*cdf0e10cSrcweir mode |= S_IWUSR | S_IWGRP | S_IWOTH; 859*cdf0e10cSrcweir flags = OPEN_WRITE_FLAGS; 860*cdf0e10cSrcweir } 861*cdf0e10cSrcweir if (uFlags & osl_File_OpenFlag_Create) 862*cdf0e10cSrcweir { 863*cdf0e10cSrcweir mode |= S_IWUSR | S_IWGRP | S_IWOTH; 864*cdf0e10cSrcweir flags = OPEN_CREATE_FLAGS; 865*cdf0e10cSrcweir } 866*cdf0e10cSrcweir if (uFlags & osl_File_OpenFlag_NoLock) 867*cdf0e10cSrcweir { 868*cdf0e10cSrcweir #ifdef HAVE_O_EXLOCK 869*cdf0e10cSrcweir flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK); 870*cdf0e10cSrcweir #endif /* HAVE_O_EXLOCK */ 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir else 873*cdf0e10cSrcweir { 874*cdf0e10cSrcweir flags = osl_file_adjustLockFlags (buffer, flags); 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir /* open the file */ 878*cdf0e10cSrcweir int fd = open( buffer, flags, mode ); 879*cdf0e10cSrcweir if (-1 == fd) 880*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 881*cdf0e10cSrcweir 882*cdf0e10cSrcweir /* reset O_NONBLOCK flag */ 883*cdf0e10cSrcweir if (flags & O_NONBLOCK) 884*cdf0e10cSrcweir { 885*cdf0e10cSrcweir int f = fcntl (fd, F_GETFL, 0); 886*cdf0e10cSrcweir if (-1 == f) 887*cdf0e10cSrcweir { 888*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, errno); 889*cdf0e10cSrcweir (void) close(fd); 890*cdf0e10cSrcweir return eRet; 891*cdf0e10cSrcweir } 892*cdf0e10cSrcweir if (-1 == fcntl (fd, F_SETFL, (f & ~O_NONBLOCK))) 893*cdf0e10cSrcweir { 894*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, errno); 895*cdf0e10cSrcweir (void) close(fd); 896*cdf0e10cSrcweir return eRet; 897*cdf0e10cSrcweir } 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir 900*cdf0e10cSrcweir /* get file status (mode, size) */ 901*cdf0e10cSrcweir struct stat aFileStat; 902*cdf0e10cSrcweir if (-1 == fstat (fd, &aFileStat)) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, errno); 905*cdf0e10cSrcweir (void) close(fd); 906*cdf0e10cSrcweir return eRet; 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir if (!S_ISREG(aFileStat.st_mode)) 909*cdf0e10cSrcweir { 910*cdf0e10cSrcweir /* we only open regular files here */ 911*cdf0e10cSrcweir (void) close(fd); 912*cdf0e10cSrcweir return osl_File_E_INVAL; 913*cdf0e10cSrcweir } 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir if (osl_file_queryLocking (uFlags)) 916*cdf0e10cSrcweir { 917*cdf0e10cSrcweir #ifdef MACOSX 918*cdf0e10cSrcweir if (-1 == flock (fd, LOCK_EX | LOCK_NB)) 919*cdf0e10cSrcweir { 920*cdf0e10cSrcweir /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */ 921*cdf0e10cSrcweir if ((errno != ENOTSUP) || ((-1 == flock (fd, LOCK_SH | LOCK_NB)) && (errno != ENOTSUP))) 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, errno); 924*cdf0e10cSrcweir (void) close(fd); 925*cdf0e10cSrcweir return eRet; 926*cdf0e10cSrcweir } 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir #else /* F_SETLK */ 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir struct flock aflock; 931*cdf0e10cSrcweir 932*cdf0e10cSrcweir aflock.l_type = F_WRLCK; 933*cdf0e10cSrcweir aflock.l_whence = SEEK_SET; 934*cdf0e10cSrcweir aflock.l_start = 0; 935*cdf0e10cSrcweir aflock.l_len = 0; 936*cdf0e10cSrcweir 937*cdf0e10cSrcweir if (-1 == fcntl (fd, F_SETLK, &aflock)) 938*cdf0e10cSrcweir { 939*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, errno); 940*cdf0e10cSrcweir (void) close(fd); 941*cdf0e10cSrcweir return eRet; 942*cdf0e10cSrcweir } 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir #endif /* F_SETLK */ 945*cdf0e10cSrcweir } 946*cdf0e10cSrcweir 947*cdf0e10cSrcweir /* allocate memory for impl structure */ 948*cdf0e10cSrcweir FileHandle_Impl * pImpl = new FileHandle_Impl (fd, buffer); 949*cdf0e10cSrcweir if (!pImpl) 950*cdf0e10cSrcweir { 951*cdf0e10cSrcweir eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM); 952*cdf0e10cSrcweir (void) close(fd); 953*cdf0e10cSrcweir return eRet; 954*cdf0e10cSrcweir } 955*cdf0e10cSrcweir if (flags & O_RDWR) 956*cdf0e10cSrcweir pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE; 957*cdf0e10cSrcweir pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size); 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir OSL_TRACE("osl_openFile(%d, %s) => %s", pImpl->m_fd, 960*cdf0e10cSrcweir flags & O_RDWR ? "writeable":"readonly", 961*cdf0e10cSrcweir rtl_string_getStr(pImpl->m_strFilePath)); 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir *pHandle = (oslFileHandle)(pImpl); 964*cdf0e10cSrcweir return osl_File_E_None; 965*cdf0e10cSrcweir } 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir /****************************************************************************/ 968*cdf0e10cSrcweir /* osl_closeFile */ 969*cdf0e10cSrcweir /****************************************************************************/ 970*cdf0e10cSrcweir oslFileError 971*cdf0e10cSrcweir SAL_CALL osl_closeFile( oslFileHandle Handle ) 972*cdf0e10cSrcweir { 973*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir if ((pImpl == 0) || (pImpl->m_fd < 0)) 976*cdf0e10cSrcweir return osl_File_E_INVAL; 977*cdf0e10cSrcweir 978*cdf0e10cSrcweir (void) pthread_mutex_lock (&(pImpl->m_mutex)); 979*cdf0e10cSrcweir 980*cdf0e10cSrcweir /* close(2) implicitly (and unconditionally) unlocks */ 981*cdf0e10cSrcweir OSL_TRACE("osl_closeFile(%d) => %s", pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath)); 982*cdf0e10cSrcweir oslFileError result = pImpl->syncFile(); 983*cdf0e10cSrcweir if (result != osl_File_E_None) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir /* close, ignoring double failure */ 986*cdf0e10cSrcweir (void) close (pImpl->m_fd); 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir else if (-1 == close (pImpl->m_fd)) 989*cdf0e10cSrcweir { 990*cdf0e10cSrcweir /* translate error code */ 991*cdf0e10cSrcweir result = oslTranslateFileError (OSL_FET_ERROR, errno); 992*cdf0e10cSrcweir } 993*cdf0e10cSrcweir 994*cdf0e10cSrcweir (void) pthread_mutex_unlock (&(pImpl->m_mutex)); 995*cdf0e10cSrcweir delete pImpl; 996*cdf0e10cSrcweir return (result); 997*cdf0e10cSrcweir } 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir /************************************************ 1000*cdf0e10cSrcweir * osl_syncFile 1001*cdf0e10cSrcweir ***********************************************/ 1002*cdf0e10cSrcweir oslFileError 1003*cdf0e10cSrcweir SAL_CALL osl_syncFile(oslFileHandle Handle) 1004*cdf0e10cSrcweir { 1005*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1006*cdf0e10cSrcweir 1007*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd)) 1008*cdf0e10cSrcweir return osl_File_E_INVAL; 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1011*cdf0e10cSrcweir 1012*cdf0e10cSrcweir OSL_TRACE("osl_syncFile(%d)", pImpl->m_fd); 1013*cdf0e10cSrcweir oslFileError result = pImpl->syncFile(); 1014*cdf0e10cSrcweir if (result != osl_File_E_None) 1015*cdf0e10cSrcweir return (result); 1016*cdf0e10cSrcweir if (-1 == fsync (pImpl->m_fd)) 1017*cdf0e10cSrcweir return oslTranslateFileError (OSL_FET_ERROR, errno); 1018*cdf0e10cSrcweir 1019*cdf0e10cSrcweir return osl_File_E_None; 1020*cdf0e10cSrcweir } 1021*cdf0e10cSrcweir 1022*cdf0e10cSrcweir /******************************************* 1023*cdf0e10cSrcweir osl_mapFile 1024*cdf0e10cSrcweir ********************************************/ 1025*cdf0e10cSrcweir oslFileError 1026*cdf0e10cSrcweir SAL_CALL osl_mapFile ( 1027*cdf0e10cSrcweir oslFileHandle Handle, 1028*cdf0e10cSrcweir void** ppAddr, 1029*cdf0e10cSrcweir sal_uInt64 uLength, 1030*cdf0e10cSrcweir sal_uInt64 uOffset, 1031*cdf0e10cSrcweir sal_uInt32 uFlags 1032*cdf0e10cSrcweir ) 1033*cdf0e10cSrcweir { 1034*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1035*cdf0e10cSrcweir 1036*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppAddr)) 1037*cdf0e10cSrcweir return osl_File_E_INVAL; 1038*cdf0e10cSrcweir *ppAddr = 0; 1039*cdf0e10cSrcweir 1040*cdf0e10cSrcweir static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max(); 1041*cdf0e10cSrcweir if (g_limit_size_t < uLength) 1042*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1043*cdf0e10cSrcweir size_t const nLength = sal::static_int_cast< size_t >(uLength); 1044*cdf0e10cSrcweir 1045*cdf0e10cSrcweir static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); 1046*cdf0e10cSrcweir if (g_limit_off_t < uOffset) 1047*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1048*cdf0e10cSrcweir off_t const nOffset = sal::static_int_cast< off_t >(uOffset); 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pImpl->m_fd, nOffset); 1051*cdf0e10cSrcweir if (MAP_FAILED == p) 1052*cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, errno); 1053*cdf0e10cSrcweir *ppAddr = p; 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir if (uFlags & osl_File_MapFlag_RandomAccess) 1056*cdf0e10cSrcweir { 1057*cdf0e10cSrcweir // Determine memory pagesize. 1058*cdf0e10cSrcweir size_t const nPageSize = FileHandle_Impl::getpagesize(); 1059*cdf0e10cSrcweir if (size_t(-1) != nPageSize) 1060*cdf0e10cSrcweir { 1061*cdf0e10cSrcweir /* 1062*cdf0e10cSrcweir * Pagein, touching first byte of every memory page. 1063*cdf0e10cSrcweir * Note: volatile disables optimizing the loop away. 1064*cdf0e10cSrcweir */ 1065*cdf0e10cSrcweir sal_uInt8 * pData (reinterpret_cast<sal_uInt8*>(*ppAddr)); 1066*cdf0e10cSrcweir size_t nSize (nLength); 1067*cdf0e10cSrcweir 1068*cdf0e10cSrcweir volatile sal_uInt8 c = 0; 1069*cdf0e10cSrcweir while (nSize > nPageSize) 1070*cdf0e10cSrcweir { 1071*cdf0e10cSrcweir c ^= pData[0]; 1072*cdf0e10cSrcweir pData += nPageSize; 1073*cdf0e10cSrcweir nSize -= nPageSize; 1074*cdf0e10cSrcweir } 1075*cdf0e10cSrcweir if (nSize > 0) 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir c^= pData[0]; 1078*cdf0e10cSrcweir pData += nSize; 1079*cdf0e10cSrcweir nSize -= nSize; 1080*cdf0e10cSrcweir } 1081*cdf0e10cSrcweir } 1082*cdf0e10cSrcweir } 1083*cdf0e10cSrcweir if (uFlags & osl_File_MapFlag_WillNeed) 1084*cdf0e10cSrcweir { 1085*cdf0e10cSrcweir // On Linux, madvise(..., MADV_WILLNEED) appears to have the undesirable 1086*cdf0e10cSrcweir // effect of not returning until the data has actually been paged in, so 1087*cdf0e10cSrcweir // that its net effect would typically be to slow down the process 1088*cdf0e10cSrcweir // (which could start processing at the beginning of the data while the 1089*cdf0e10cSrcweir // OS simultaneously pages in the rest); on other platforms, it remains 1090*cdf0e10cSrcweir // to be evaluated whether madvise or equivalent is available and 1091*cdf0e10cSrcweir // actually useful: 1092*cdf0e10cSrcweir #if defined MACOSX 1093*cdf0e10cSrcweir int e = posix_madvise(p, nLength, POSIX_MADV_WILLNEED); 1094*cdf0e10cSrcweir if (e != 0) 1095*cdf0e10cSrcweir { 1096*cdf0e10cSrcweir OSL_TRACE( 1097*cdf0e10cSrcweir "posix_madvise(..., POSIX_MADV_WILLNEED) failed with %d", e); 1098*cdf0e10cSrcweir } 1099*cdf0e10cSrcweir #elif defined SOLARIS 1100*cdf0e10cSrcweir if (madvise(static_cast< caddr_t >(p), nLength, MADV_WILLNEED) != 0) 1101*cdf0e10cSrcweir { 1102*cdf0e10cSrcweir OSL_TRACE("madvise(..., MADV_WILLNEED) failed with %d", errno); 1103*cdf0e10cSrcweir } 1104*cdf0e10cSrcweir #endif 1105*cdf0e10cSrcweir } 1106*cdf0e10cSrcweir return osl_File_E_None; 1107*cdf0e10cSrcweir } 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir /******************************************* 1110*cdf0e10cSrcweir osl_unmapFile 1111*cdf0e10cSrcweir ********************************************/ 1112*cdf0e10cSrcweir oslFileError 1113*cdf0e10cSrcweir SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength) 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir if (0 == pAddr) 1116*cdf0e10cSrcweir return osl_File_E_INVAL; 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max(); 1119*cdf0e10cSrcweir if (g_limit_size_t < uLength) 1120*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1121*cdf0e10cSrcweir size_t const nLength = sal::static_int_cast< size_t >(uLength); 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir if (-1 == munmap(static_cast<char*>(pAddr), nLength)) 1124*cdf0e10cSrcweir return oslTranslateFileError(OSL_FET_ERROR, errno); 1125*cdf0e10cSrcweir 1126*cdf0e10cSrcweir return osl_File_E_None; 1127*cdf0e10cSrcweir } 1128*cdf0e10cSrcweir 1129*cdf0e10cSrcweir /******************************************* 1130*cdf0e10cSrcweir osl_readLine 1131*cdf0e10cSrcweir ********************************************/ 1132*cdf0e10cSrcweir oslFileError 1133*cdf0e10cSrcweir SAL_CALL osl_readLine ( 1134*cdf0e10cSrcweir oslFileHandle Handle, 1135*cdf0e10cSrcweir sal_Sequence ** ppSequence) 1136*cdf0e10cSrcweir { 1137*cdf0e10cSrcweir FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle); 1138*cdf0e10cSrcweir 1139*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppSequence)) 1140*cdf0e10cSrcweir return osl_File_E_INVAL; 1141*cdf0e10cSrcweir sal_uInt64 uBytesRead = 0; 1142*cdf0e10cSrcweir 1143*cdf0e10cSrcweir // read at current fileptr; fileptr += uBytesRead; 1144*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1145*cdf0e10cSrcweir oslFileError result = pImpl->readLineAt ( 1146*cdf0e10cSrcweir pImpl->m_fileptr, ppSequence, &uBytesRead); 1147*cdf0e10cSrcweir if (result == osl_File_E_None) 1148*cdf0e10cSrcweir pImpl->m_fileptr += uBytesRead; 1149*cdf0e10cSrcweir return (result); 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir /******************************************* 1153*cdf0e10cSrcweir osl_readFile 1154*cdf0e10cSrcweir ********************************************/ 1155*cdf0e10cSrcweir oslFileError 1156*cdf0e10cSrcweir SAL_CALL osl_readFile ( 1157*cdf0e10cSrcweir oslFileHandle Handle, 1158*cdf0e10cSrcweir void * pBuffer, 1159*cdf0e10cSrcweir sal_uInt64 uBytesRequested, 1160*cdf0e10cSrcweir sal_uInt64 * pBytesRead) 1161*cdf0e10cSrcweir { 1162*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1163*cdf0e10cSrcweir 1164*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead)) 1165*cdf0e10cSrcweir return osl_File_E_INVAL; 1166*cdf0e10cSrcweir 1167*cdf0e10cSrcweir static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); 1168*cdf0e10cSrcweir if (g_limit_ssize_t < uBytesRequested) 1169*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1170*cdf0e10cSrcweir size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested); 1171*cdf0e10cSrcweir 1172*cdf0e10cSrcweir // read at current fileptr; fileptr += *pBytesRead; 1173*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1174*cdf0e10cSrcweir oslFileError result = pImpl->readFileAt ( 1175*cdf0e10cSrcweir pImpl->m_fileptr, pBuffer, nBytesRequested, pBytesRead); 1176*cdf0e10cSrcweir if (result == osl_File_E_None) 1177*cdf0e10cSrcweir pImpl->m_fileptr += *pBytesRead; 1178*cdf0e10cSrcweir return (result); 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir /******************************************* 1182*cdf0e10cSrcweir osl_writeFile 1183*cdf0e10cSrcweir ********************************************/ 1184*cdf0e10cSrcweir oslFileError 1185*cdf0e10cSrcweir SAL_CALL osl_writeFile ( 1186*cdf0e10cSrcweir oslFileHandle Handle, 1187*cdf0e10cSrcweir const void * pBuffer, 1188*cdf0e10cSrcweir sal_uInt64 uBytesToWrite, 1189*cdf0e10cSrcweir sal_uInt64 * pBytesWritten) 1190*cdf0e10cSrcweir { 1191*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1192*cdf0e10cSrcweir 1193*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten)) 1194*cdf0e10cSrcweir return osl_File_E_INVAL; 1195*cdf0e10cSrcweir if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE)) 1196*cdf0e10cSrcweir return osl_File_E_BADF; 1197*cdf0e10cSrcweir 1198*cdf0e10cSrcweir static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); 1199*cdf0e10cSrcweir if (g_limit_ssize_t < uBytesToWrite) 1200*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1201*cdf0e10cSrcweir size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite); 1202*cdf0e10cSrcweir 1203*cdf0e10cSrcweir // write at current fileptr; fileptr += *pBytesWritten; 1204*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1205*cdf0e10cSrcweir oslFileError result = pImpl->writeFileAt ( 1206*cdf0e10cSrcweir pImpl->m_fileptr, pBuffer, nBytesToWrite, pBytesWritten); 1207*cdf0e10cSrcweir if (result == osl_File_E_None) 1208*cdf0e10cSrcweir pImpl->m_fileptr += *pBytesWritten; 1209*cdf0e10cSrcweir return (result); 1210*cdf0e10cSrcweir } 1211*cdf0e10cSrcweir 1212*cdf0e10cSrcweir /******************************************* 1213*cdf0e10cSrcweir osl_readFileAt 1214*cdf0e10cSrcweir ********************************************/ 1215*cdf0e10cSrcweir oslFileError 1216*cdf0e10cSrcweir SAL_CALL osl_readFileAt ( 1217*cdf0e10cSrcweir oslFileHandle Handle, 1218*cdf0e10cSrcweir sal_uInt64 uOffset, 1219*cdf0e10cSrcweir void* pBuffer, 1220*cdf0e10cSrcweir sal_uInt64 uBytesRequested, 1221*cdf0e10cSrcweir sal_uInt64* pBytesRead) 1222*cdf0e10cSrcweir { 1223*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1224*cdf0e10cSrcweir 1225*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead)) 1226*cdf0e10cSrcweir return osl_File_E_INVAL; 1227*cdf0e10cSrcweir if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE)) 1228*cdf0e10cSrcweir return osl_File_E_SPIPE; 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); 1231*cdf0e10cSrcweir if (g_limit_off_t < uOffset) 1232*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1233*cdf0e10cSrcweir off_t const nOffset = sal::static_int_cast< off_t >(uOffset); 1234*cdf0e10cSrcweir 1235*cdf0e10cSrcweir static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); 1236*cdf0e10cSrcweir if (g_limit_ssize_t < uBytesRequested) 1237*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1238*cdf0e10cSrcweir size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested); 1239*cdf0e10cSrcweir 1240*cdf0e10cSrcweir // read at specified fileptr 1241*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1242*cdf0e10cSrcweir return pImpl->readFileAt (nOffset, pBuffer, nBytesRequested, pBytesRead); 1243*cdf0e10cSrcweir } 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir /******************************************* 1246*cdf0e10cSrcweir osl_writeFileAt 1247*cdf0e10cSrcweir ********************************************/ 1248*cdf0e10cSrcweir oslFileError 1249*cdf0e10cSrcweir SAL_CALL osl_writeFileAt ( 1250*cdf0e10cSrcweir oslFileHandle Handle, 1251*cdf0e10cSrcweir sal_uInt64 uOffset, 1252*cdf0e10cSrcweir const void* pBuffer, 1253*cdf0e10cSrcweir sal_uInt64 uBytesToWrite, 1254*cdf0e10cSrcweir sal_uInt64* pBytesWritten) 1255*cdf0e10cSrcweir { 1256*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1257*cdf0e10cSrcweir 1258*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten)) 1259*cdf0e10cSrcweir return osl_File_E_INVAL; 1260*cdf0e10cSrcweir if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE)) 1261*cdf0e10cSrcweir return osl_File_E_SPIPE; 1262*cdf0e10cSrcweir if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE)) 1263*cdf0e10cSrcweir return osl_File_E_BADF; 1264*cdf0e10cSrcweir 1265*cdf0e10cSrcweir static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); 1266*cdf0e10cSrcweir if (g_limit_off_t < uOffset) 1267*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1268*cdf0e10cSrcweir off_t const nOffset = sal::static_int_cast< off_t >(uOffset); 1269*cdf0e10cSrcweir 1270*cdf0e10cSrcweir static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max(); 1271*cdf0e10cSrcweir if (g_limit_ssize_t < uBytesToWrite) 1272*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1273*cdf0e10cSrcweir size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite); 1274*cdf0e10cSrcweir 1275*cdf0e10cSrcweir // write at specified fileptr 1276*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1277*cdf0e10cSrcweir return pImpl->writeFileAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten); 1278*cdf0e10cSrcweir } 1279*cdf0e10cSrcweir 1280*cdf0e10cSrcweir /****************************************************************************/ 1281*cdf0e10cSrcweir /* osl_isEndOfFile */ 1282*cdf0e10cSrcweir /****************************************************************************/ 1283*cdf0e10cSrcweir oslFileError 1284*cdf0e10cSrcweir SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF ) 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1287*cdf0e10cSrcweir 1288*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pIsEOF)) 1289*cdf0e10cSrcweir return osl_File_E_INVAL; 1290*cdf0e10cSrcweir 1291*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1292*cdf0e10cSrcweir *pIsEOF = (pImpl->getPos() == pImpl->getSize()); 1293*cdf0e10cSrcweir return osl_File_E_None; 1294*cdf0e10cSrcweir } 1295*cdf0e10cSrcweir 1296*cdf0e10cSrcweir /************************************************ 1297*cdf0e10cSrcweir * osl_getFilePos 1298*cdf0e10cSrcweir ***********************************************/ 1299*cdf0e10cSrcweir oslFileError 1300*cdf0e10cSrcweir SAL_CALL osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos ) 1301*cdf0e10cSrcweir { 1302*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pPos)) 1305*cdf0e10cSrcweir return osl_File_E_INVAL; 1306*cdf0e10cSrcweir 1307*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1308*cdf0e10cSrcweir *pPos = pImpl->getPos(); 1309*cdf0e10cSrcweir return osl_File_E_None; 1310*cdf0e10cSrcweir } 1311*cdf0e10cSrcweir 1312*cdf0e10cSrcweir /******************************************* 1313*cdf0e10cSrcweir osl_setFilePos 1314*cdf0e10cSrcweir ********************************************/ 1315*cdf0e10cSrcweir oslFileError 1316*cdf0e10cSrcweir SAL_CALL osl_setFilePos (oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset) 1317*cdf0e10cSrcweir { 1318*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1319*cdf0e10cSrcweir 1320*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd)) 1321*cdf0e10cSrcweir return osl_File_E_INVAL; 1322*cdf0e10cSrcweir 1323*cdf0e10cSrcweir static sal_Int64 const g_limit_off_t = std::numeric_limits< off_t >::max(); 1324*cdf0e10cSrcweir if (g_limit_off_t < uOffset) 1325*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1326*cdf0e10cSrcweir off_t nPos = 0, nOffset = sal::static_int_cast< off_t >(uOffset); 1327*cdf0e10cSrcweir 1328*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1329*cdf0e10cSrcweir switch(uHow) 1330*cdf0e10cSrcweir { 1331*cdf0e10cSrcweir case osl_Pos_Absolut: 1332*cdf0e10cSrcweir if (0 > nOffset) 1333*cdf0e10cSrcweir return osl_File_E_INVAL; 1334*cdf0e10cSrcweir break; 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir case osl_Pos_Current: 1337*cdf0e10cSrcweir nPos = sal::static_int_cast< off_t >(pImpl->getPos()); 1338*cdf0e10cSrcweir if ((0 > nOffset) && (-1*nOffset > nPos)) 1339*cdf0e10cSrcweir return osl_File_E_INVAL; 1340*cdf0e10cSrcweir if (g_limit_off_t < nPos + nOffset) 1341*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1342*cdf0e10cSrcweir break; 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir case osl_Pos_End: 1345*cdf0e10cSrcweir nPos = sal::static_int_cast< off_t >(pImpl->getSize()); 1346*cdf0e10cSrcweir if ((0 > nOffset) && (-1*nOffset > nPos)) 1347*cdf0e10cSrcweir return osl_File_E_INVAL; 1348*cdf0e10cSrcweir if (g_limit_off_t < nPos + nOffset) 1349*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1350*cdf0e10cSrcweir break; 1351*cdf0e10cSrcweir 1352*cdf0e10cSrcweir default: 1353*cdf0e10cSrcweir return osl_File_E_INVAL; 1354*cdf0e10cSrcweir } 1355*cdf0e10cSrcweir 1356*cdf0e10cSrcweir return pImpl->setPos (nPos + nOffset); 1357*cdf0e10cSrcweir } 1358*cdf0e10cSrcweir 1359*cdf0e10cSrcweir /**************************************************************************** 1360*cdf0e10cSrcweir * osl_getFileSize 1361*cdf0e10cSrcweir ****************************************************************************/ 1362*cdf0e10cSrcweir oslFileError 1363*cdf0e10cSrcweir SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize ) 1364*cdf0e10cSrcweir { 1365*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1366*cdf0e10cSrcweir 1367*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pSize)) 1368*cdf0e10cSrcweir return osl_File_E_INVAL; 1369*cdf0e10cSrcweir 1370*cdf0e10cSrcweir FileHandle_Impl::Guard lock (&(pImpl->m_mutex)); 1371*cdf0e10cSrcweir *pSize = pImpl->getSize(); 1372*cdf0e10cSrcweir return osl_File_E_None; 1373*cdf0e10cSrcweir } 1374*cdf0e10cSrcweir 1375*cdf0e10cSrcweir /************************************************ 1376*cdf0e10cSrcweir * osl_setFileSize 1377*cdf0e10cSrcweir ***********************************************/ 1378*cdf0e10cSrcweir oslFileError 1379*cdf0e10cSrcweir SAL_CALL osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize ) 1380*cdf0e10cSrcweir { 1381*cdf0e10cSrcweir FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle); 1382*cdf0e10cSrcweir 1383*cdf0e10cSrcweir if ((0 == pImpl) || (-1 == pImpl->m_fd)) 1384*cdf0e10cSrcweir return osl_File_E_INVAL; 1385*cdf0e10cSrcweir if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE)) 1386*cdf0e10cSrcweir return osl_File_E_BADF; 1387*cdf0e10cSrcweir 1388*cdf0e10cSrcweir static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max(); 1389*cdf0e10cSrcweir if (g_limit_off_t < uSize) 1390*cdf0e10cSrcweir return osl_File_E_OVERFLOW; 1391*cdf0e10cSrcweir 1392*cdf0e10cSrcweir oslFileError result = pImpl->syncFile(); 1393*cdf0e10cSrcweir if (result != osl_File_E_None) 1394*cdf0e10cSrcweir return (result); 1395*cdf0e10cSrcweir pImpl->m_bufptr = -1, pImpl->m_buflen = 0; 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir return pImpl->setSize (uSize); 1398*cdf0e10cSrcweir } 1399