file.cxx (87d2adbc) file.cxx (dcc6e752)
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 55 unchanged lines hidden (view full) ---

64#ifndef _CTYPE_H_
65#include <ctype.h>
66#endif
67
68#ifndef _WCHAR_H_
69#include <wchar.h>
70#endif
71
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 55 unchanged lines hidden (view full) ---

64#ifndef _CTYPE_H_
65#include <ctype.h>
66#endif
67
68#ifndef _WCHAR_H_
69#include <wchar.h>
70#endif
71
72#include <algorithm>
73
74#include <limits>
75#include <sys/mman.h>
76
72#if OSL_DEBUG_LEVEL > 1
73 extern void debug_ustring(rtl_uString*);
74#endif
75
76
77#ifdef DEBUG_OSL_FILE
78# define PERROR( a, b ) perror( a ); fprintf( stderr, b )
79#else

--- 61 unchanged lines hidden (view full) ---

141 for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
142 {
143 if (dwError == errtable[i].oscode)
144 return static_cast<oslFileError>(errtable[i].errnocode);
145 }
146 return osl_File_E_INVAL;
147 }
148
77#if OSL_DEBUG_LEVEL > 1
78 extern void debug_ustring(rtl_uString*);
79#endif
80
81
82#ifdef DEBUG_OSL_FILE
83# define PERROR( a, b ) perror( a ); fprintf( stderr, b )
84#else

--- 61 unchanged lines hidden (view full) ---

146 for (int i = 0; i < ELEMENTS_OF_ARRAY(errtable); ++i )
147 {
148 if (dwError == errtable[i].oscode)
149 return static_cast<oslFileError>(errtable[i].errnocode);
150 }
151 return osl_File_E_INVAL;
152 }
153
154#ifdef DEBUG_OSL_FILE
155# define OSL_FILE_TRACE 0 ? (void)(0) : osl_trace
156# define PERROR( a, b ) perror( a ); fprintf( stderr, b )
157#else
158# define OSL_FILE_TRACE 1 ? (void)(0) : osl_trace
159# define PERROR( a, b )
160#endif
161
162//##################################################################
163// File handle implementation
164//##################################################################
165struct FileHandle_Impl
166{
167 rtl_String * m_strFilePath; /* holds native file path */
168 int m_fd;
169
170 /** State
171 */
172 enum StateBits
173 {
174 STATE_SEEKABLE = 1, /* default */
175 STATE_READABLE = 2, /* default */
176 STATE_WRITEABLE = 4, /* open() sets, write() requires, else osl_File_E_BADF */
177 STATE_MODIFIED = 8 /* write() sets, flush() resets */
178 };
179 int m_state;
180
181 sal_uInt64 m_size; /* file size */
182 off_t m_offset; /* physical offset from begin of file */
183 //off_t m_filepos; /* logical offset from begin of file */
184 off_t m_fileptr; /* logical offset from begin of file */
185
186 off_t m_bufptr; /* buffer offset from begin of file */
187 size_t m_buflen; /* buffer filled [0, m_bufsiz - 1] */
188
189 size_t m_bufsiz;
190 sal_uInt8 * m_buffer;
191
192 explicit FileHandle_Impl (int fd, char const * path = "<anon>");
193 ~FileHandle_Impl();
194
195 static void* operator new(size_t n);
196 static void operator delete(void * p, size_t);
197 static size_t getpagesize();
198
199 sal_uInt64 getPos() const;
200 oslFileError setPos (sal_uInt64 uPos);
201
202 sal_uInt64 getSize() const;
203 oslFileError setSize (sal_uInt64 uPos);
204
205 oslFileError readAt (
206 off_t nOffset,
207 void * pBuffer,
208 size_t nBytesRequested,
209 sal_uInt64 * pBytesRead);
210
211 oslFileError writeAt (
212 off_t nOffset,
213 void const * pBuffer,
214 size_t nBytesToWrite,
215 sal_uInt64 * pBytesWritten);
216
217 oslFileError readFileAt (
218 off_t nOffset,
219 void * pBuffer,
220 size_t nBytesRequested,
221 sal_uInt64 * pBytesRead);
222
223 oslFileError writeFileAt (
224 off_t nOffset,
225 void const * pBuffer,
226 size_t nBytesToWrite,
227 sal_uInt64 * pBytesWritten);
228
229 oslFileError readLineAt (
230 LONGLONG nOffset,
231 sal_Sequence ** ppSequence,
232 sal_uInt64 * pBytesRead);
233
234 oslFileError writeSequence_Impl (
235 sal_Sequence ** ppSequence,
236 size_t * pnOffset,
237 const void * pBuffer,
238 size_t nBytes);
239
240 oslFileError syncFile();
241
242 /** Buffer cache / allocator.
243 */
244 class Allocator
245 {
246 rtl_cache_type * m_cache;
247 size_t m_bufsiz;
248
249 Allocator (Allocator const &);
250 Allocator & operator= (Allocator const &);
251
252 public:
253 static Allocator & get();
254
255 void allocate (sal_uInt8 ** ppBuffer, size_t * pnSize);
256 void deallocate (sal_uInt8 * pBuffer);
257
258 protected:
259 Allocator();
260 ~Allocator();
261 };
262};
263
264FileHandle_Impl::Allocator &
265FileHandle_Impl::Allocator::get()
266{
267 static Allocator g_aBufferAllocator;
268 return g_aBufferAllocator;
269}
270
271FileHandle_Impl::Allocator::Allocator()
272 : m_cache (0),
273 m_bufsiz (0)
274{
275 size_t const pagesize = FileHandle_Impl::getpagesize();
276 m_cache = rtl_cache_create (
277 "osl_file_buffer_cache", pagesize, 0, 0, 0, 0, 0, 0, 0);
278 if (0 != m_cache)
279 m_bufsiz = pagesize;
280}
281
282FileHandle_Impl::Allocator::~Allocator()
283{
284 rtl_cache_destroy(m_cache), m_cache = 0;
285}
286
287void FileHandle_Impl::Allocator::allocate (sal_uInt8 ** ppBuffer, size_t * pnSize)
288{
289 OSL_PRECOND((0 != ppBuffer) && (0 != pnSize), "FileHandle_Impl::Allocator::allocate(): contract violation");
290 *ppBuffer = static_cast< sal_uInt8* >(rtl_cache_alloc(m_cache)), *pnSize = m_bufsiz;
291}
292
293void FileHandle_Impl::Allocator::deallocate (sal_uInt8 * pBuffer)
294{
295 if (0 != pBuffer)
296 rtl_cache_free (m_cache, pBuffer);
297}
298
299FileHandle_Impl::FileHandle_Impl (int fd, char const * path)
300 : m_strFilePath (0),
301 m_fd (fd),
302 m_state (STATE_SEEKABLE | STATE_READABLE),
303 m_size (0),
304 m_offset (0),
305 m_fileptr (0),
306 m_bufptr (-1),
307 m_buflen (0),
308 m_bufsiz (0),
309 m_buffer (0)
310{
311 rtl_string_newFromStr (&m_strFilePath, path);
312 Allocator::get().allocate (&m_buffer, &m_bufsiz);
313 if (m_buffer != 0)
314 memset (m_buffer, 0, m_bufsiz);
315}
316
317FileHandle_Impl::~FileHandle_Impl()
318{
319 Allocator::get().deallocate (m_buffer), m_buffer = 0;
320 rtl_string_release (m_strFilePath), m_strFilePath = 0;
321}
322
323void * FileHandle_Impl::operator new(size_t n)
324{
325 return rtl_allocateMemory(n);
326}
327
328void FileHandle_Impl::operator delete(void * p, size_t)
329{
330 rtl_freeMemory(p);
331}
332
333size_t FileHandle_Impl::getpagesize()
334{
335 ULONG ulPageSize;
336 DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
337 return sal::static_int_cast< size_t >(ulPageSize);
338}
339
340sal_uInt64 FileHandle_Impl::getPos() const
341{
342 return sal::static_int_cast< sal_uInt64 >(m_fileptr);
343}
344
345oslFileError FileHandle_Impl::setPos (sal_uInt64 uPos)
346{
347 m_fileptr = sal::static_int_cast< LONGLONG >(uPos);
348 return osl_File_E_None;
349}
350
351sal_uInt64 FileHandle_Impl::getSize() const
352{
353 LONGLONG bufend = std::max((LONGLONG)(0), m_bufptr) + m_buflen;
354 return std::max(m_size, sal::static_int_cast< sal_uInt64 >(bufend));
355}
356
357oslFileError FileHandle_Impl::setSize (sal_uInt64 uSize)
358{
359 off_t const nSize = sal::static_int_cast< off_t >(uSize);
360 if (-1 == ftruncate (m_fd, nSize))
361 {
362 /* Failure. Save original result. Try fallback algorithm */
363 oslFileError result = oslTranslateFileError (OSL_FET_ERROR, errno);
364
365 /* Check against current size. Fail upon 'shrink' */
366 if (uSize <= getSize())
367 {
368 /* Failure upon 'shrink'. Return original result */
369 return (result);
370 }
371
372 /* Save current position */
373 off_t const nCurPos = (off_t)lseek (m_fd, (off_t)0, SEEK_CUR);
374 if (nCurPos == (off_t)(-1))
375 return (result);
376
377 /* Try 'expand' via 'lseek()' and 'write()' */
378 if (-1 == lseek (m_fd, (off_t)(nSize - 1), SEEK_SET))
379 return (result);
380
381 if (-1 == write (m_fd, (char*)"", (size_t)1))
382 {
383 /* Failure. Restore saved position */
384 (void) lseek (m_fd, (off_t)(nCurPos), SEEK_SET);
385 return (result);
386 }
387
388 /* Success. Restore saved position */
389 if (-1 == lseek (m_fd, (off_t)nCurPos, SEEK_SET))
390 return (result);
391 }
392
393 OSL_FILE_TRACE("osl_setFileSize(%d, %lld) => %ld", m_fd, getSize(), nSize);
394 m_size = sal::static_int_cast< sal_uInt64 >(nSize);
395 return osl_File_E_None;
396}
397
398oslFileError FileHandle_Impl::readAt (
399 off_t nOffset,
400 void * pBuffer,
401 size_t nBytesRequested,
402 sal_uInt64 * pBytesRead)
403{
404 OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::readAt(): not seekable");
405 if (!(m_state & STATE_SEEKABLE))
406 return osl_File_E_SPIPE;
407
408 OSL_PRECOND((m_state & STATE_READABLE), "FileHandle_Impl::readAt(): not readable");
409 if (!(m_state & STATE_READABLE))
410 return osl_File_E_BADF;
411
412 if (nOffset != m_offset)
413 {
414 if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
415 return oslTranslateFileError (OSL_FET_ERROR, errno);
416 m_offset = nOffset;
417 }
418
419 ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
420 if (-1 == nBytes)
421 return oslTranslateFileError (OSL_FET_ERROR, errno);
422 m_offset += nBytes;
423
424 OSL_FILE_TRACE("FileHandle_Impl::readAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
425 *pBytesRead = nBytes;
426 return osl_File_E_None;
427}
428
429oslFileError FileHandle_Impl::writeAt (
430 off_t nOffset,
431 void const * pBuffer,
432 size_t nBytesToWrite,
433 sal_uInt64 * pBytesWritten)
434{
435 OSL_PRECOND((m_state & STATE_SEEKABLE), "FileHandle_Impl::writeAt(): not seekable");
436 if (!(m_state & STATE_SEEKABLE))
437 return osl_File_E_SPIPE;
438
439 OSL_PRECOND((m_state & STATE_WRITEABLE), "FileHandle_Impl::writeAt(): not writeable");
440 if (!(m_state & STATE_WRITEABLE))
441 return osl_File_E_BADF;
442
443 if (nOffset != m_offset)
444 {
445 if (-1 == ::lseek (m_fd, nOffset, SEEK_SET))
446 return oslTranslateFileError (OSL_FET_ERROR, errno);
447 m_offset = nOffset;
448 }
449
450 ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
451 if (-1 == nBytes)
452 return oslTranslateFileError (OSL_FET_ERROR, errno);
453 m_offset += nBytes;
454
455 OSL_FILE_TRACE("FileHandle_Impl::writeAt(%d, %lld, %ld)", m_fd, nOffset, nBytes);
456 m_size = std::max (m_size, sal::static_int_cast< sal_uInt64 >(nOffset + nBytes));
457
458 *pBytesWritten = nBytes;
459 return osl_File_E_None;
460}
461
462oslFileError FileHandle_Impl::readFileAt (
463 off_t nOffset,
464 void * pBuffer,
465 size_t nBytesRequested,
466 sal_uInt64 * pBytesRead)
467{
468 if (0 == (m_state & STATE_SEEKABLE))
469 {
470 // not seekable (pipe)
471 ssize_t nBytes = ::read (m_fd, pBuffer, nBytesRequested);
472 if (-1 == nBytes)
473 return oslTranslateFileError (OSL_FET_ERROR, errno);
474 *pBytesRead = nBytes;
475 return osl_File_E_None;
476 }
477 else if (0 == m_buffer)
478 {
479 // not buffered
480 return readAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
481 }
482 else
483 {
484 sal_uInt8 * buffer = static_cast<sal_uInt8*>(pBuffer);
485 for (*pBytesRead = 0; nBytesRequested > 0; )
486 {
487 off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
488 size_t const bufpos = (nOffset % m_bufsiz);
489
490 if (bufptr != m_bufptr)
491 {
492 // flush current buffer
493 oslFileError result = syncFile();
494 if (result != osl_File_E_None)
495 return (result);
496
497 if (nBytesRequested >= m_bufsiz)
498 {
499 // buffer too small, read through from file
500 sal_uInt64 uDone = 0;
501 result = readAt (nOffset, &(buffer[*pBytesRead]), nBytesRequested, &uDone);
502 if (result != osl_File_E_None)
503 return (result);
504
505 nBytesRequested -= uDone, *pBytesRead += uDone;
506 return osl_File_E_None;
507 }
508
509 // update buffer (pointer)
510 sal_uInt64 uDone = 0;
511 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
512 if (result != osl_File_E_None)
513 return (result);
514 m_bufptr = bufptr, m_buflen = uDone;
515 }
516 if (bufpos >= m_buflen)
517 {
518 // end of file
519 return osl_File_E_None;
520 }
521
522 size_t const bytes = std::min (m_buflen - bufpos, nBytesRequested);
523 OSL_FILE_TRACE("FileHandle_Impl::readFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
524
525 memcpy (&(buffer[*pBytesRead]), &(m_buffer[bufpos]), bytes);
526 nBytesRequested -= bytes, *pBytesRead += bytes, nOffset += bytes;
527 }
528 return osl_File_E_None;
529 }
530}
531
532oslFileError FileHandle_Impl::writeFileAt (
533 off_t nOffset,
534 void const * pBuffer,
535 size_t nBytesToWrite,
536 sal_uInt64 * pBytesWritten)
537{
538 if (0 == (m_state & STATE_SEEKABLE))
539 {
540 // not seekable (pipe)
541 ssize_t nBytes = ::write (m_fd, pBuffer, nBytesToWrite);
542 if (-1 == nBytes)
543 return oslTranslateFileError (OSL_FET_ERROR, errno);
544 *pBytesWritten = nBytes;
545 return osl_File_E_None;
546 }
547 else if (0 == m_buffer)
548 {
549 // not buffered
550 return writeAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
551 }
552 else
553 {
554 sal_uInt8 const * buffer = static_cast<sal_uInt8 const *>(pBuffer);
555 for (*pBytesWritten = 0; nBytesToWrite > 0; )
556 {
557 off_t const bufptr = (nOffset / m_bufsiz) * m_bufsiz;
558 size_t const bufpos = (nOffset % m_bufsiz);
559 if (bufptr != m_bufptr)
560 {
561 // flush current buffer
562 oslFileError result = syncFile();
563 if (result != osl_File_E_None)
564 return (result);
565
566 if (nBytesToWrite >= m_bufsiz)
567 {
568 // buffer to small, write through to file
569 sal_uInt64 uDone = 0;
570 result = writeAt (nOffset, &(buffer[*pBytesWritten]), nBytesToWrite, &uDone);
571 if (result != osl_File_E_None)
572 return (result);
573 if (uDone != nBytesToWrite)
574 return osl_File_E_IO;
575
576 nBytesToWrite -= uDone, *pBytesWritten += uDone;
577 return osl_File_E_None;
578 }
579
580 // update buffer (pointer)
581 sal_uInt64 uDone = 0;
582 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
583 if (result != osl_File_E_None)
584 return (result);
585 m_bufptr = bufptr, m_buflen = uDone;
586 }
587
588 size_t const bytes = std::min (m_bufsiz - bufpos, nBytesToWrite);
589 OSL_FILE_TRACE("FileHandle_Impl::writeFileAt(%d, %lld, %ld)", m_fd, nOffset, bytes);
590
591 memcpy (&(m_buffer[bufpos]), &(buffer[*pBytesWritten]), bytes);
592 nBytesToWrite -= bytes, *pBytesWritten += bytes, nOffset += bytes;
593
594 m_buflen = std::max(m_buflen, bufpos + bytes);
595 m_state |= STATE_MODIFIED;
596 }
597 return osl_File_E_None;
598 }
599}
600
601oslFileError FileHandle_Impl::readLineAt (
602 LONGLONG nOffset,
603 sal_Sequence ** ppSequence,
604 sal_uInt64 * pBytesRead)
605{
606 oslFileError result = osl_File_E_None;
607
608 LONGLONG bufptr = (nOffset / m_bufsiz) * m_bufsiz;
609 if (bufptr != m_bufptr)
610 {
611 /* flush current buffer */
612 result = syncFile();
613 if (result != osl_File_E_None)
614 return (result);
615
616 /* update buffer (pointer) */
617 sal_uInt64 uDone = 0;
618 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
619 if (result != osl_File_E_None)
620 return (result);
621
622 m_bufptr = bufptr, m_buflen = sal::static_int_cast< size_t >(uDone);
623 }
624
625 static int const LINE_STATE_BEGIN = 0;
626 static int const LINE_STATE_CR = 1;
627 static int const LINE_STATE_LF = 2;
628
629 size_t bufpos = sal::static_int_cast< size_t >(nOffset - m_bufptr), curpos = bufpos, dstpos = 0;
630 int state = (bufpos >= m_buflen) ? LINE_STATE_LF : LINE_STATE_BEGIN;
631
632 for ( ; state != LINE_STATE_LF; )
633 {
634 if (curpos >= m_buflen)
635 {
636 /* buffer examined */
637 if (0 < (curpos - bufpos))
638 {
639 /* flush buffer to sequence */
640 result = writeSequence_Impl (
641 ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos);
642 if (result != osl_File_E_None)
643 return (result);
644 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
645 }
646
647 bufptr = nOffset / m_bufsiz * m_bufsiz;
648 if (bufptr != m_bufptr)
649 {
650 /* update buffer (pointer) */
651 sal_uInt64 uDone = 0;
652 result = readAt (bufptr, m_buffer, m_bufsiz, &uDone);
653 if (result != osl_File_E_None)
654 return (result);
655 m_bufptr = bufptr, m_buflen = sal::static_int_cast< size_t >(uDone);
656 }
657
658 bufpos = sal::static_int_cast< size_t >(nOffset - m_bufptr), curpos = bufpos;
659 if (bufpos >= m_buflen)
660 break;
661 }
662 switch (state)
663 {
664 case LINE_STATE_CR:
665 state = LINE_STATE_LF;
666 switch (m_buffer[curpos])
667 {
668 case 0x0A: /* CRLF */
669 /* eat current char */
670 curpos++;
671 break;
672 default: /* single CR */
673 /* keep current char */
674 break;
675 }
676 break;
677 default:
678 /* determine next state */
679 switch (m_buffer[curpos])
680 {
681 case 0x0A: /* single LF */
682 state = LINE_STATE_LF;
683 break;
684 case 0x0D: /* CR */
685 state = LINE_STATE_CR;
686 break;
687 default: /* advance to next char */
688 curpos++;
689 break;
690 }
691 if (state != LINE_STATE_BEGIN)
692 {
693 /* store (and eat) the newline char */
694 m_buffer[curpos] = 0x0A, curpos++;
695
696 /* flush buffer to sequence */
697 result = writeSequence_Impl (
698 ppSequence, &dstpos, &(m_buffer[bufpos]), curpos - bufpos - 1);
699 if (result != osl_File_E_None)
700 return (result);
701 *pBytesRead += curpos - bufpos, nOffset += curpos - bufpos;
702 }
703 break;
704 }
705 }
706
707 result = writeSequence_Impl (ppSequence, &dstpos, 0, 0);
708 if (result != osl_File_E_None)
709 return (result);
710 if (0 < dstpos)
711 return osl_File_E_None;
712 if (bufpos >= m_buflen)
713 return osl_File_E_AGAIN;
714 return osl_File_E_None;
715}
716
717oslFileError FileHandle_Impl::writeSequence_Impl (
718 sal_Sequence ** ppSequence,
719 size_t * pnOffset,
720 const void * pBuffer,
721 size_t nBytes)
722{
723 sal_Int32 nElements = *pnOffset + nBytes;
724 if (!*ppSequence)
725 {
726 /* construct sequence */
727 rtl_byte_sequence_constructNoDefault(ppSequence, nElements);
728 }
729 else if (nElements != (*ppSequence)->nElements)
730 {
731 /* resize sequence */
732 rtl_byte_sequence_realloc(ppSequence, nElements);
733 }
734 if (*ppSequence != 0)
735 {
736 /* fill sequence */
737 memcpy(&((*ppSequence)->elements[*pnOffset]), pBuffer, nBytes), *pnOffset += nBytes;
738 }
739 return (*ppSequence != 0) ? osl_File_E_None : osl_File_E_NOMEM;
740}
741
742oslFileError FileHandle_Impl::syncFile()
743{
744 oslFileError result = osl_File_E_None;
745 if (m_state & STATE_MODIFIED)
746 {
747 sal_uInt64 uDone = 0;
748 result = writeAt (m_bufptr, m_buffer, m_buflen, &uDone);
749 if (result != osl_File_E_None)
750 return (result);
751 if (uDone != m_buflen)
752 return osl_File_E_IO;
753 m_state &= ~STATE_MODIFIED;
754 }
755 return (result);
756}
757
758
149/******************************************************************************
150 *
151 * static members
152 *
153 *****************************************************************************/
154
155static const char * pFileLockEnvVar = (char *) -1;
156

--- 495 unchanged lines hidden (view full) ---

652 rtl_freeMemory( pItemImpl );
653 }
654 return osl_File_E_None;
655}
656
657/****************************************************************************
658 * osl_createFileHandleFromFD
659 ***************************************************************************/
759/******************************************************************************
760 *
761 * static members
762 *
763 *****************************************************************************/
764
765static const char * pFileLockEnvVar = (char *) -1;
766

--- 495 unchanged lines hidden (view full) ---

1262 rtl_freeMemory( pItemImpl );
1263 }
1264 return osl_File_E_None;
1265}
1266
1267/****************************************************************************
1268 * osl_createFileHandleFromFD
1269 ***************************************************************************/
660
661oslFileHandle osl_createFileHandleFromFD( int fd )
1270extern "C" oslFileHandle osl_createFileHandleFromFD( int fd )
662{
1271{
663 oslFileHandleImpl* pHandleImpl = NULL;
1272 if (-1 == fd)
1273 return 0; // EINVAL
664
1274
665 if ( fd >= 0 )
666 {
667 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
1275 struct stat aFileStat;
1276 if (-1 == fstat (fd, &aFileStat))
1277 return 0; // EBADF
668
1278
669 if( pHandleImpl )
670 {
671 pHandleImpl->ustrFilePath = NULL;
672 rtl_uString_new( &pHandleImpl->ustrFilePath );
673 pHandleImpl->fd = fd;
1279 FileHandle_Impl * pImpl = new FileHandle_Impl (fd);
1280 if (0 == pImpl)
1281 return 0; // ENOMEM
674
1282
675 /* FIXME: should detect whether the file has been locked */
676 pHandleImpl->bLocked = sal_True;
1283 // assume writeable
1284 pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
1285 if (!S_ISREG(aFileStat.st_mode))
1286 {
1287 /* not a regular file, mark not seekable */
1288 pImpl->m_state &= ~FileHandle_Impl::STATE_SEEKABLE;
1289 }
1290 else
1291 {
1292 /* regular file, init current size */
1293 pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
1294 }
1295
1296 OSL_FILE_TRACE("osl_createFileHandleFromFD(%d, writeable) => %s",
1297 pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
1298 return (oslFileHandle)(pImpl);
1299}
1300
1301/*******************************************************************
1302 * osl_file_adjustLockFlags
1303 ******************************************************************/
1304static int osl_file_adjustLockFlags (const char * path, int flags)
1305{
1306#ifdef MACOSX
1307 /*
1308 * The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
1309 * that makes it impossible for OOo to create a backup copy of the
1310 * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by
1311 * the OOo file handling, so we need to check the path of the file
1312 * for the filesystem name.
1313 */
1314 struct statfs s;
1315 if( 0 <= statfs( path, &s ) )
1316 {
1317 if( 0 == strncmp("afpfs", s.f_fstypename, 5) )
1318 {
1319 flags &= ~O_EXLOCK;
1320 flags |= O_SHLOCK;
1321 }
1322 else
1323 {
1324 /* Needed flags to allow opening a webdav file */
1325 flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
677 }
1326 }
678 }
1327 }
1328#endif /* MACOSX */
679
1329
680 return (oslFileHandle)pHandleImpl;
1330 (void) path;
1331 return flags;
681}
682
683/****************************************************************************
1332}
1333
1334/****************************************************************************
1335 * osl_file_queryLocking
1336 ***************************************************************************/
1337struct Locking_Impl
1338{
1339 int m_enabled;
1340 Locking_Impl() : m_enabled(0)
1341 {
1342#ifndef HAVE_O_EXLOCK
1343 m_enabled = ((getenv("SAL_ENABLE_FILE_LOCKING") != 0) || (getenv("STAR_ENABLE_FILE_LOCKING") != 0));
1344#endif /* HAVE_O_EXLOCK */
1345 }
1346};
1347static int osl_file_queryLocking (sal_uInt32 uFlags)
1348{
1349 if (!(uFlags & osl_File_OpenFlag_NoLock))
1350 {
1351 if ((uFlags & osl_File_OpenFlag_Write) || (uFlags & osl_File_OpenFlag_Create))
1352 {
1353 static Locking_Impl g_locking;
1354 return (g_locking.m_enabled != 0);
1355 }
1356 }
1357 return 0;
1358}
1359
1360/****************************************************************************
684 * osl_openFile
685 ***************************************************************************/
1361 * osl_openFile
1362 ***************************************************************************/
1363#ifdef HAVE_O_EXLOCK
1364#define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK )
1365#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK )
1366#else
1367#define OPEN_WRITE_FLAGS ( O_RDWR )
1368#define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
1369#endif
686
1370
687oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
1371oslFileError
1372SAL_CALL osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
688{
1373{
689 oslFileHandleImpl* pHandleImpl = NULL;
690 oslFileError eRet;
1374 oslFileError eRet;
691 rtl_uString* ustrFilePath = NULL;
692
1375
693 char buffer[PATH_MAX];
694 int fd;
695 int mode = S_IRUSR | S_IRGRP | S_IROTH;
696 int flags = O_RDONLY;
697
698 struct flock aflock;
699
700 /* locking the complete file */
701 aflock.l_type = 0;
702 aflock.l_whence = SEEK_SET;
703 aflock.l_start = 0;
704 aflock.l_len = 0;
705
706 OSL_ASSERT( ustrFileURL );
707 OSL_ASSERT( pHandle );
708
709 if( ( 0 == ustrFileURL->length ) )
1376 if ((ustrFileURL == 0) || (ustrFileURL->length == 0) || (pHandle == 0))
710 return osl_File_E_INVAL;
711
712 /* convert file URL to system path */
1377 return osl_File_E_INVAL;
1378
1379 /* convert file URL to system path */
713 eRet = osl_getSystemPathFromFileURL( ustrFileURL, &ustrFilePath );
714
715 if( osl_File_E_None != eRet )
1380 char buffer[PATH_MAX];
1381 eRet = FileURLToPath (buffer, sizeof(buffer), ustrFileURL);
1382 if (eRet != osl_File_E_None)
716 return eRet;
1383 return eRet;
1384#ifdef MACOSX
1385 if (macxp_resolveAlias (buffer, sizeof(buffer)) != 0)
1386 return oslTranslateFileError (OSL_FET_ERROR, errno);
1387#endif /* MACOSX */
717
1388
718 osl_systemPathRemoveSeparator(ustrFilePath);
1389 /* set mode and flags */
1390 int mode = S_IRUSR | S_IRGRP | S_IROTH;
1391 int flags = O_RDONLY;
1392 if (uFlags & osl_File_OpenFlag_Write)
1393 {
1394 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1395 flags = OPEN_WRITE_FLAGS;
1396 }
1397 if (uFlags & osl_File_OpenFlag_Create)
1398 {
1399 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
1400 flags = OPEN_CREATE_FLAGS;
1401 }
1402 if (uFlags & osl_File_OpenFlag_NoLock)
1403 {
1404#ifdef HAVE_O_EXLOCK
1405 flags &= ~(O_EXLOCK | O_SHLOCK | O_NONBLOCK);
1406#endif /* HAVE_O_EXLOCK */
1407 }
1408 else
1409 {
1410 flags = osl_file_adjustLockFlags (buffer, flags);
1411 }
719
1412
720 /* convert unicode path to text */
721 if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length ) )
1413 /* open the file */
1414 int fd = open( buffer, flags | O_BINARY, mode );
1415 if (-1 == fd)
1416 return oslTranslateFileError (OSL_FET_ERROR, errno);
1417
1418 /* reset O_NONBLOCK flag */
1419 if (flags & O_NONBLOCK)
722 {
1420 {
723 /* we do not open devices or such here */
724 if( !( uFlags & osl_File_OpenFlag_Create ) )
1421 int f = fcntl (fd, F_GETFL, 0);
1422 if (-1 == f)
725 {
1423 {
726 struct stat aFileStat;
1424 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1425 (void) close(fd);
1426 return eRet;
1427 }
1428 if (-1 == fcntl (fd, F_SETFL, (f & ~O_NONBLOCK)))
1429 {
1430 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1431 (void) close(fd);
1432 return eRet;
1433 }
1434 }
727
1435
728 if( 0 > stat( buffer, &aFileStat ) )
729 {
730 PERROR( "osl_openFile", buffer );
731 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
732 }
1436 /* get file status (mode, size) */
1437 struct stat aFileStat;
1438 if (-1 == fstat (fd, &aFileStat))
1439 {
1440 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1441 (void) close(fd);
1442 return eRet;
1443 }
1444 if (!S_ISREG(aFileStat.st_mode))
1445 {
1446 /* we only open regular files here */
1447 (void) close(fd);
1448 return osl_File_E_INVAL;
1449 }
733
1450
734 else if( !S_ISREG( aFileStat.st_mode ) )
1451 if (osl_file_queryLocking (uFlags))
1452 {
1453#ifdef MACOSX
1454 if (-1 == flock (fd, LOCK_EX | LOCK_NB))
1455 {
1456 /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */
1457 if ((errno != ENOTSUP) || ((-1 == flock (fd, LOCK_SH | LOCK_NB)) && (errno != ENOTSUP)))
735 {
1458 {
736 eRet = osl_File_E_INVAL;
1459 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1460 (void) close(fd);
1461 return eRet;
737 }
738 }
1462 }
1463 }
739
740 if( osl_File_E_None == eRet )
1464#else /* F_SETLK */
741 {
1465 {
742 /*
743 * set flags and mode
744 */
1466 struct flock aflock;
745
1467
746 if ( uFlags & osl_File_OpenFlag_Write )
747 {
748 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
749 flags = O_RDWR;
750 aflock.l_type = F_WRLCK;
751 }
1468 aflock.l_type = F_WRLCK;
1469 aflock.l_whence = SEEK_SET;
1470 aflock.l_start = 0;
1471 aflock.l_len = 0;
752
1472
753 if ( uFlags & osl_File_OpenFlag_Create )
1473 if (-1 == fcntl (fd, F_SETLK, &aflock))
754 {
1474 {
755 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
756 flags = O_CREAT | O_EXCL | O_RDWR;
1475 eRet = oslTranslateFileError (OSL_FET_ERROR, errno);
1476 (void) close(fd);
1477 return eRet;
757 }
1478 }
1479 }
1480#endif /* F_SETLK */
1481 }
758
1482
759 /* open the file */
760 fd = open( buffer, flags | O_BINARY, mode);
761 if ( fd >= 0 )
762 {
763 sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
764 sal_Bool bLocked = sal_False;
765 if( bNeedsLock )
766 {
767 /* check if file lock is enabled and clear l_type member of flock otherwise */
768 if( (char *) -1 == pFileLockEnvVar )
769 {
770 /* FIXME: this is not MT safe */
771 pFileLockEnvVar = getenv("SAL_ENABLE_FILE_LOCKING");
1483 /* allocate memory for impl structure */
1484 FileHandle_Impl * pImpl = new FileHandle_Impl (fd, buffer);
1485 if (!pImpl)
1486 {
1487 eRet = oslTranslateFileError (OSL_FET_ERROR, ENOMEM);
1488 (void) close(fd);
1489 return eRet;
1490 }
1491 if (flags & O_RDWR)
1492 pImpl->m_state |= FileHandle_Impl::STATE_WRITEABLE;
1493 pImpl->m_size = sal::static_int_cast< sal_uInt64 >(aFileStat.st_size);
772
1494
773 if( NULL == pFileLockEnvVar)
774 pFileLockEnvVar = getenv("STAR_ENABLE_FILE_LOCKING");
775 }
1495 OSL_TRACE("osl_openFile(%d, %s) => %s", pImpl->m_fd,
1496 flags & O_RDWR ? "writeable":"readonly",
1497 rtl_string_getStr(pImpl->m_strFilePath));
776
1498
777 if( NULL == pFileLockEnvVar )
778 aflock.l_type = 0;
1499 *pHandle = (oslFileHandle)(pImpl);
1500 return osl_File_E_None;
1501}
779
1502
780 /* lock the file if flock.l_type is set */
781 bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
782 }
1503/****************************************************************************/
1504/* osl_closeFile */
1505/****************************************************************************/
1506oslFileError
1507SAL_CALL osl_closeFile( oslFileHandle Handle )
1508{
1509 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
783
1510
784 if ( !bNeedsLock || bLocked )
785 {
786 /* allocate memory for impl structure */
787 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
788 if( pHandleImpl )
789 {
790 pHandleImpl->ustrFilePath = ustrFilePath;
791 pHandleImpl->fd = fd;
792 pHandleImpl->bLocked = bLocked;
1511 if ((pImpl == 0) || (pImpl->m_fd < 0))
1512 return osl_File_E_INVAL;
793
1513
794 *pHandle = (oslFileHandle) pHandleImpl;
1514 /* close(2) implicitly (and unconditionally) unlocks */
1515 OSL_TRACE("osl_closeFile(%d) => %s", pImpl->m_fd, rtl_string_getStr(pImpl->m_strFilePath));
1516 oslFileError result = pImpl->syncFile();
1517 if (result != osl_File_E_None)
1518 {
1519 /* close, ignoring double failure */
1520 (void) close (pImpl->m_fd);
1521 }
1522 else if (-1 == close (pImpl->m_fd))
1523 {
1524 /* translate error code */
1525 result = oslTranslateFileError (OSL_FET_ERROR, errno);
1526 }
795
1527
796 return osl_File_E_None;
797 }
798 else
799 {
800 errno = ENOMEM;
801 }
802 }
1528 delete pImpl;
1529 return (result);
1530}
803
1531
804 close( fd );
805 }
1532/************************************************
1533 * osl_syncFile
1534 ***********************************************/
1535oslFileError
1536SAL_CALL osl_syncFile(oslFileHandle Handle)
1537{
1538 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1539
1540 if ((0 == pImpl) || (-1 == pImpl->m_fd))
1541 return osl_File_E_INVAL;
806
1542
807 PERROR( "osl_openFile", buffer );
808 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
809 }
810 }
811 else
812 eRet = osl_File_E_INVAL;
1543 OSL_FILE_TRACE("osl_syncFile(%d)", pImpl->m_fd);
1544 oslFileError result = pImpl->syncFile();
1545 if (result != osl_File_E_None)
1546 return (result);
1547 if (-1 == fsync (pImpl->m_fd))
1548 return oslTranslateFileError (OSL_FET_ERROR, errno);
1549
1550 return osl_File_E_None;
1551}
813
1552
814 rtl_uString_release( ustrFilePath );
815 return eRet;
1553/*******************************************
1554 osl_mapFile
1555********************************************/
1556oslFileError
1557SAL_CALL osl_mapFile (
1558 oslFileHandle Handle,
1559 void** ppAddr,
1560 sal_uInt64 uLength,
1561 sal_uInt64 uOffset,
1562 sal_uInt32 uFlags
1563)
1564{
1565 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1566
1567 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppAddr))
1568 return osl_File_E_INVAL;
1569 *ppAddr = 0;
1570
1571 static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max();
1572 if (g_limit_size_t < uLength)
1573 return osl_File_E_OVERFLOW;
1574 size_t const nLength = sal::static_int_cast< size_t >(uLength);
1575
1576 static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1577 if (g_limit_off_t < uOffset)
1578 return osl_File_E_OVERFLOW;
1579 off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1580
1581#ifdef SAL_OS2 // YD mmap does not support shared
1582 void* p = mmap(NULL, nLength, PROT_READ, MAP_PRIVATE, pImpl->m_fd, nOffset);
1583#else
1584 void* p = mmap(NULL, nLength, PROT_READ, MAP_SHARED, pImpl->m_fd, nOffset);
1585#endif
1586 if (MAP_FAILED == p)
1587 return oslTranslateFileError(OSL_FET_ERROR, errno);
1588 *ppAddr = p;
1589
1590 if (uFlags & osl_File_MapFlag_RandomAccess)
1591 {
1592 // Determine memory pagesize.
1593 size_t const nPageSize = FileHandle_Impl::getpagesize();
1594 if (size_t(-1) != nPageSize)
1595 {
1596 /*
1597 * Pagein, touching first byte of every memory page.
1598 * Note: volatile disables optimizing the loop away.
1599 */
1600 sal_uInt8 * pData (reinterpret_cast<sal_uInt8*>(*ppAddr));
1601 size_t nSize (nLength);
1602
1603 volatile sal_uInt8 c = 0;
1604 while (nSize > nPageSize)
1605 {
1606 c ^= pData[0];
1607 pData += nPageSize;
1608 nSize -= nPageSize;
1609 }
1610 if (nSize > 0)
1611 {
1612 c^= pData[0];
1613 pData += nSize;
1614 nSize -= nSize;
1615 }
1616 }
1617 }
1618 return osl_File_E_None;
816}
817
1619}
1620
818/****************************************************************************/
819/* osl_closeFile */
820/****************************************************************************/
1621/*******************************************
1622 osl_unmapFile
1623********************************************/
1624oslFileError
1625SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength)
1626{
1627 if (0 == pAddr)
1628 return osl_File_E_INVAL;
821
1629
822oslFileError osl_closeFile( oslFileHandle Handle )
1630 static sal_uInt64 const g_limit_size_t = std::numeric_limits< size_t >::max();
1631 if (g_limit_size_t < uLength)
1632 return osl_File_E_OVERFLOW;
1633 size_t const nLength = sal::static_int_cast< size_t >(uLength);
1634
1635 if (-1 == munmap(static_cast<char*>(pAddr), nLength))
1636 return oslTranslateFileError(OSL_FET_ERROR, errno);
1637
1638 return osl_File_E_None;
1639}
1640
1641/*******************************************
1642 osl_readLine
1643********************************************/
1644oslFileError
1645SAL_CALL osl_readLine (
1646 oslFileHandle Handle,
1647 sal_Sequence ** ppSequence)
823{
1648{
824 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
825 oslFileError eRet = osl_File_E_INVAL;
1649 FileHandle_Impl * pImpl = static_cast<FileHandle_Impl*>(Handle);
826
1650
827 OSL_ASSERT( Handle );
1651 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == ppSequence))
1652 return osl_File_E_INVAL;
1653 sal_uInt64 uBytesRead = 0;
828
1654
829 if( pHandleImpl )
830 {
831 rtl_uString_release( pHandleImpl->ustrFilePath );
1655 // read at current fileptr; fileptr += uBytesRead;
1656 oslFileError result = pImpl->readLineAt (
1657 pImpl->m_fileptr, ppSequence, &uBytesRead);
1658 if (result == osl_File_E_None)
1659 pImpl->m_fileptr += uBytesRead;
1660 return (result);
1661}
832
1662
833 /* release file lock if locking is enabled */
834 if( pFileLockEnvVar )
835 {
836 struct flock aflock;
1663/*******************************************
1664 osl_readFile
1665********************************************/
1666oslFileError
1667SAL_CALL osl_readFile (
1668 oslFileHandle Handle,
1669 void * pBuffer,
1670 sal_uInt64 uBytesRequested,
1671 sal_uInt64 * pBytesRead)
1672{
1673 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
837
1674
838 aflock.l_type = F_UNLCK;
839 aflock.l_whence = SEEK_SET;
840 aflock.l_start = 0;
841 aflock.l_len = 0;
1675 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
1676 return osl_File_E_INVAL;
1677
1678 static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1679 if (g_limit_ssize_t < uBytesRequested)
1680 return osl_File_E_OVERFLOW;
1681 size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
842
1682
843 if ( pHandleImpl->bLocked )
844 {
845 /* FIXME: check if file is really locked ? */
1683 // read at current fileptr; fileptr += *pBytesRead;
1684 oslFileError result = pImpl->readFileAt (
1685 pImpl->m_fileptr, pBuffer, nBytesRequested, pBytesRead);
1686 if (result == osl_File_E_None)
1687 pImpl->m_fileptr += *pBytesRead;
1688 return (result);
1689}
846
1690
847 /* release the file share lock on this file */
848 if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
849 PERROR( "osl_closeFile", "unlock failed" );
850 }
851 }
1691/*******************************************
1692 osl_writeFile
1693********************************************/
1694oslFileError
1695SAL_CALL osl_writeFile (
1696 oslFileHandle Handle,
1697 const void * pBuffer,
1698 sal_uInt64 uBytesToWrite,
1699 sal_uInt64 * pBytesWritten)
1700{
1701 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
852
1702
853 if( 0 > close( pHandleImpl->fd ) )
854 {
855 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
856 }
857 else
858 eRet = osl_File_E_None;
1703 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
1704 return osl_File_E_INVAL;
1705 if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1706 return osl_File_E_BADF;
859
1707
860 rtl_freeMemory( pHandleImpl );
861 }
1708 static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1709 if (g_limit_ssize_t < uBytesToWrite)
1710 return osl_File_E_OVERFLOW;
1711 size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
862
1712
863 return eRet;
1713 // write at current fileptr; fileptr += *pBytesWritten;
1714 oslFileError result = pImpl->writeFileAt (
1715 pImpl->m_fileptr, pBuffer, nBytesToWrite, pBytesWritten);
1716 if (result == osl_File_E_None)
1717 pImpl->m_fileptr += *pBytesWritten;
1718 return (result);
864}
865
1719}
1720
1721/*******************************************
1722 osl_readFileAt
1723********************************************/
1724oslFileError
1725SAL_CALL osl_readFileAt (
1726 oslFileHandle Handle,
1727 sal_uInt64 uOffset,
1728 void* pBuffer,
1729 sal_uInt64 uBytesRequested,
1730 sal_uInt64* pBytesRead)
1731{
1732 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1733
1734 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesRead))
1735 return osl_File_E_INVAL;
1736 if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
1737 return osl_File_E_SPIPE;
1738
1739 static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1740 if (g_limit_off_t < uOffset)
1741 return osl_File_E_OVERFLOW;
1742 off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1743
1744 static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1745 if (g_limit_ssize_t < uBytesRequested)
1746 return osl_File_E_OVERFLOW;
1747 size_t const nBytesRequested = sal::static_int_cast< size_t >(uBytesRequested);
1748
1749 // read at specified fileptr
1750 return pImpl->readFileAt (nOffset, pBuffer, nBytesRequested, pBytesRead);
1751}
1752
1753/*******************************************
1754 osl_writeFileAt
1755********************************************/
1756oslFileError
1757SAL_CALL osl_writeFileAt (
1758 oslFileHandle Handle,
1759 sal_uInt64 uOffset,
1760 const void* pBuffer,
1761 sal_uInt64 uBytesToWrite,
1762 sal_uInt64* pBytesWritten)
1763{
1764 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1765
1766 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pBuffer) || (0 == pBytesWritten))
1767 return osl_File_E_INVAL;
1768 if (0 == (pImpl->m_state & FileHandle_Impl::STATE_SEEKABLE))
1769 return osl_File_E_SPIPE;
1770 if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1771 return osl_File_E_BADF;
1772
1773 static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1774 if (g_limit_off_t < uOffset)
1775 return osl_File_E_OVERFLOW;
1776 off_t const nOffset = sal::static_int_cast< off_t >(uOffset);
1777
1778 static sal_uInt64 const g_limit_ssize_t = std::numeric_limits< ssize_t >::max();
1779 if (g_limit_ssize_t < uBytesToWrite)
1780 return osl_File_E_OVERFLOW;
1781 size_t const nBytesToWrite = sal::static_int_cast< size_t >(uBytesToWrite);
1782
1783 // write at specified fileptr
1784 return pImpl->writeFileAt (nOffset, pBuffer, nBytesToWrite, pBytesWritten);
1785}
1786
866/****************************************************************************/
867/* osl_isEndOfFile */
868/****************************************************************************/
1787/****************************************************************************/
1788/* osl_isEndOfFile */
1789/****************************************************************************/
1790oslFileError
1791SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
1792{
1793 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
869
1794
870oslFileError SAL_CALL osl_isEndOfFile( oslFileHandle Handle, sal_Bool *pIsEOF )
1795 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pIsEOF))
1796 return osl_File_E_INVAL;
1797
1798 *pIsEOF = (pImpl->getPos() == pImpl->getSize());
1799 return osl_File_E_None;
1800}
1801
1802/************************************************
1803 * osl_getFilePos
1804 ***********************************************/
1805oslFileError
1806SAL_CALL osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
871{
1807{
872 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
873 oslFileError eRet = osl_File_E_INVAL;
1808 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
874
1809
875 if ( pHandleImpl)
876 {
877 long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
1810 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pPos))
1811 return osl_File_E_INVAL;
878
1812
879 if ( curPos >= 0 )
880 {
881 long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
1813 *pPos = pImpl->getPos();
1814 return osl_File_E_None;
1815}
882
1816
883 if ( endPos >= 0 )
884 {
885 *pIsEOF = ( curPos == endPos );
886 curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
1817/*******************************************
1818 osl_setFilePos
1819********************************************/
1820oslFileError
1821SAL_CALL osl_setFilePos (oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uOffset)
1822{
1823 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
887
1824
888 if ( curPos >= 0 )
889 eRet = osl_File_E_None;
890 else
891 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
892 }
893 else
894 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
895 }
896 else
897 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
898 }
1825 if ((0 == pImpl) || (-1 == pImpl->m_fd))
1826 return osl_File_E_INVAL;
899
1827
900 return eRet;
1828 static sal_Int64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1829 if (g_limit_off_t < uOffset)
1830 return osl_File_E_OVERFLOW;
1831 off_t nPos = 0, nOffset = sal::static_int_cast< off_t >(uOffset);
1832
1833 switch(uHow)
1834 {
1835 case osl_Pos_Absolut:
1836 if (0 > nOffset)
1837 return osl_File_E_INVAL;
1838 break;
1839
1840 case osl_Pos_Current:
1841 nPos = sal::static_int_cast< off_t >(pImpl->getPos());
1842 if ((0 > nOffset) && (-1*nOffset > nPos))
1843 return osl_File_E_INVAL;
1844 if (g_limit_off_t < nPos + nOffset)
1845 return osl_File_E_OVERFLOW;
1846 break;
1847
1848 case osl_Pos_End:
1849 nPos = sal::static_int_cast< off_t >(pImpl->getSize());
1850 if ((0 > nOffset) && (-1*nOffset > nPos))
1851 return osl_File_E_INVAL;
1852 if (g_limit_off_t < nPos + nOffset)
1853 return osl_File_E_OVERFLOW;
1854 break;
1855
1856 default:
1857 return osl_File_E_INVAL;
1858 }
1859
1860 return pImpl->setPos (nPos + nOffset);
901}
902
1861}
1862
1863/****************************************************************************
1864 * osl_getFileSize
1865 ****************************************************************************/
1866oslFileError
1867SAL_CALL osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
1868{
1869 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
903
1870
1871 if ((0 == pImpl) || (-1 == pImpl->m_fd) || (0 == pSize))
1872 return osl_File_E_INVAL;
1873
1874 *pSize = pImpl->getSize();
1875 return osl_File_E_None;
1876}
1877
1878/************************************************
1879 * osl_setFileSize
1880 ***********************************************/
1881oslFileError
1882SAL_CALL osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
1883{
1884 FileHandle_Impl* pImpl = static_cast<FileHandle_Impl*>(Handle);
1885
1886 if ((0 == pImpl) || (-1 == pImpl->m_fd))
1887 return osl_File_E_INVAL;
1888 if (0 == (pImpl->m_state & FileHandle_Impl::STATE_WRITEABLE))
1889 return osl_File_E_BADF;
1890
1891 static sal_uInt64 const g_limit_off_t = std::numeric_limits< off_t >::max();
1892 if (g_limit_off_t < uSize)
1893 return osl_File_E_OVERFLOW;
1894
1895 oslFileError result = pImpl->syncFile();
1896 if (result != osl_File_E_None)
1897 return (result);
1898 pImpl->m_bufptr = -1, pImpl->m_buflen = 0;
1899
1900 return pImpl->setSize (uSize);
1901}
1902
904/****************************************************************************/
905/* osl_moveFile */
906/****************************************************************************/
907
908oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
909{
910 char srcPath[PATH_MAX];
911 char destPath[PATH_MAX];

--- 1118 unchanged lines hidden (view full) ---

2030/******************************************************************************
2031 *
2032 * Exported Module Functions
2033 * (independent of C or Unicode Strings)
2034 *
2035 *****************************************************************************/
2036
2037
1903/****************************************************************************/
1904/* osl_moveFile */
1905/****************************************************************************/
1906
1907oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
1908{
1909 char srcPath[PATH_MAX];
1910 char destPath[PATH_MAX];

--- 1118 unchanged lines hidden (view full) ---

3029/******************************************************************************
3030 *
3031 * Exported Module Functions
3032 * (independent of C or Unicode Strings)
3033 *
3034 *****************************************************************************/
3035
3036
2038/*******************************************
2039 osl_readFile
2040********************************************/
2041
3037
2042oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
2043{
2044 ssize_t nBytes = 0;
2045 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2046
2047 if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
2048 return osl_File_E_INVAL;
2049
2050 nBytes = read(pHandleImpl->fd, pBuffer, uBytesRequested);
2051
2052 if (-1 == nBytes)
2053 return oslTranslateFileError(OSL_FET_ERROR, errno);
2054
2055 *pBytesRead = nBytes;
2056 return osl_File_E_None;
2057}
2058
2059/*******************************************
2060 osl_writeFile
2061********************************************/
2062
2063oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
2064{
2065 ssize_t nBytes = 0;
2066 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
2067
2068 OSL_ASSERT(pHandleImpl);
2069 OSL_ASSERT(pBuffer);
2070 OSL_ASSERT(pBytesWritten);
2071
2072 if ((0 == pHandleImpl) || (0 == pBuffer) || (0 == pBytesWritten))
2073 return osl_File_E_INVAL;
2074
2075 OSL_ASSERT(pHandleImpl->fd >= 0);
2076
2077 if (pHandleImpl->fd < 0)
2078 return osl_File_E_INVAL;
2079
2080 nBytes = write(pHandleImpl->fd, pBuffer, uBytesToWrite);
2081
2082 if (-1 == nBytes)
2083 return oslTranslateFileError(OSL_FET_ERROR, errno);
2084
2085 *pBytesWritten = nBytes;
2086 return osl_File_E_None;
2087}
2088
2089/*******************************************
2090 osl_writeFile
2091********************************************/
2092
2093oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
2094{
2095 oslFileHandleImpl* pHandleImpl=0;
2096 int nRet=0;
2097 off_t nOffset=0;
2098
2099 pHandleImpl = (oslFileHandleImpl*) Handle;
2100 if ( pHandleImpl == 0 )
2101 {
2102 return osl_File_E_INVAL;
2103 }
2104
2105 if ( pHandleImpl->fd < 0 )
2106 {
2107 return osl_File_E_INVAL;
2108 }
2109
2110 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
2111 if ( uPos > LONG_MAX )
2112 {
2113 return osl_File_E_OVERFLOW;
2114 }
2115
2116 nOffset=(off_t)uPos;
2117
2118 switch(uHow)
2119 {
2120 case osl_Pos_Absolut:
2121 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
2122 break;
2123
2124 case osl_Pos_Current:
2125 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
2126 break;
2127
2128 case osl_Pos_End:
2129 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
2130 break;
2131
2132 default:
2133 return osl_File_E_INVAL;
2134 }
2135
2136 if ( nOffset < 0 )
2137 {
2138 nRet=errno;
2139 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2140 }
2141
2142 return osl_File_E_None;
2143}
2144
2145/************************************************
2146 * osl_getFilePos
2147 ***********************************************/
2148
2149oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
2150{
2151 oslFileHandleImpl* pHandleImpl=0;
2152 off_t nOffset=0;
2153 int nRet=0;
2154
2155 pHandleImpl = (oslFileHandleImpl*) Handle;
2156 if ( pHandleImpl == 0 || pPos == 0)
2157 {
2158 return osl_File_E_INVAL;
2159 }
2160
2161 if ( pHandleImpl->fd < 0 )
2162 {
2163 return osl_File_E_INVAL;
2164 }
2165
2166 nOffset = lseek(pHandleImpl->fd,0,SEEK_CUR);
2167
2168 if (nOffset < 0)
2169 {
2170 nRet =errno;
2171
2172 /* *pPos =0; */
2173
2174 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2175 }
2176
2177 *pPos=nOffset;
2178
2179 return osl_File_E_None;
2180}
2181
2182/****************************************************************************
2183 * osl_getFileSize
2184 ****************************************************************************/
2185
2186oslFileError osl_getFileSize( oslFileHandle Handle, sal_uInt64* pSize )
2187{
2188 oslFileHandleImpl* pHandleImpl=(oslFileHandleImpl*) Handle;
2189 if (pHandleImpl == 0)
2190 return osl_File_E_INVAL;
2191
2192 struct stat file_stat;
2193 if (fstat(pHandleImpl->fd, &file_stat) == -1)
2194 return oslTranslateFileError(OSL_FET_ERROR, errno);
2195
2196 *pSize = file_stat.st_size;
2197 return osl_File_E_None;
2198}
2199
2200/************************************************
2201 * osl_setFileSize
2202 ***********************************************/
2203
2204oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
2205{
2206 oslFileHandleImpl* pHandleImpl=0;
2207 off_t nOffset=0;
2208
2209 pHandleImpl = (oslFileHandleImpl*) Handle;
2210 if ( pHandleImpl == 0 )
2211 {
2212 return osl_File_E_INVAL;
2213 }
2214
2215 if ( pHandleImpl->fd < 0 )
2216 {
2217 return osl_File_E_INVAL;
2218 }
2219
2220 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
2221 if ( uSize > LONG_MAX )
2222 {
2223 return osl_File_E_OVERFLOW;
2224 }
2225
2226 nOffset = (off_t)uSize;
2227 if (ftruncate (pHandleImpl->fd, nOffset) < 0)
2228 {
2229 /* Failure. Try fallback algorithm */
2230 oslFileError result;
2231 struct stat aStat;
2232 off_t nCurPos;
2233
2234 /* Save original result */
2235 result = oslTranslateFileError (OSL_FET_ERROR, errno);
2236 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
2237
2238 /* Check against current size. Fail upon 'shrink' */
2239 if (fstat (pHandleImpl->fd, &aStat) < 0)
2240 {
2241 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
2242 return (result);
2243 }
2244 if ((0 <= nOffset) && (nOffset <= aStat.st_size))
2245 {
2246 /* Failure upon 'shrink'. Return original result */
2247 return (result);
2248 }
2249
2250 /* Save current position */
2251 nCurPos = (off_t)lseek (pHandleImpl->fd, (off_t)0, SEEK_CUR);
2252 if (nCurPos == (off_t)(-1))
2253 {
2254 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2255 return (result);
2256 }
2257
2258 /* Try 'expand' via 'lseek()' and 'write()' */
2259 if (lseek (pHandleImpl->fd, (off_t)(nOffset - 1), SEEK_SET) < 0)
2260 {
2261 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
2262 return (result);
2263 }
2264 if (write (pHandleImpl->fd, (char*)"", (size_t)1) < 0)
2265 {
2266 /* Failure. Restore saved position */
2267 PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
2268 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2269 {
2270#ifdef DEBUG_OSL_FILE
2271 perror("ftruncate: lseek");
2272#endif /* DEBUG_OSL_FILE */
2273 }
2274 return (result);
2275 }
2276
2277 /* Success. Restore saved position */
2278 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
2279 {
2280 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
2281 return (result);
2282 }
2283 }
2284
2285 return (osl_File_E_None);
2286}
2287
2288/*###############################################*/
2289oslFileError SAL_CALL osl_syncFile(oslFileHandle Handle)
2290{
2291 oslFileHandleImpl* handle_impl = (oslFileHandleImpl*)Handle;
2292
2293 if (handle_impl == 0)
2294 return osl_File_E_INVAL;
2295
2296 if (fsync(handle_impl->fd) == -1)
2297 return oslTranslateFileError(OSL_FET_ERROR, errno);
2298
2299 return osl_File_E_None;
2300}
2301
2302/******************************************************************************
2303 *
2304 * C-String Versions of Exported Module Functions
2305 *
2306 *****************************************************************************/
2307
3038/******************************************************************************
3039 *
3040 * C-String Versions of Exported Module Functions
3041 *
3042 *****************************************************************************/
3043
2308#ifdef HAVE_STATFS_H
2309
3044
2310#if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
2311# define __OSL_STATFS_STRUCT struct statfs
2312# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2313# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2314# define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
2315# define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
2316
2317/* always return true if queried for the properties of
2318 the file system. If you think this is wrong under any
2319 of the target platforms fix it!!!! */
2320# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2321# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2322#endif /* FREEBSD || NETBSD */
2323
2324#if defined(LINUX)
2325# define __OSL_NFS_SUPER_MAGIC 0x6969
2326# define __OSL_SMB_SUPER_MAGIC 0x517B
2327# define __OSL_MSDOS_SUPER_MAGIC 0x4d44
2328# define __OSL_NTFS_SUPER_MAGIC 0x5346544e
2329# define __OSL_STATFS_STRUCT struct statfs
2330# define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
2331# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
2332# define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
2333# define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
2334# define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
2335# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
2336# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
2337#endif /* LINUX */
2338
2339#if defined(SOLARIS)
2340# define __OSL_STATFS_STRUCT struct statvfs
2341# define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
2342# define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
2343# define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
2344# define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
2345
2346/* always return true if queried for the properties of
2347 the file system. If you think this is wrong under any
2348 of the target platforms fix it!!!! */
2349# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2350# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2351#endif /* SOLARIS */
2352
2353# define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
2354
2355#else /* no statfs available */
2356
2357# define __OSL_STATFS_STRUCT struct dummy {int i;}
2358# define __OSL_STATFS_INIT(a) ((void)0)
2359# define __OSL_STATFS(dir, sfs) (1)
2360# define __OSL_STATFS_ISREMOTE(sfs) (0)
2361# define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
2362# define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
2363#endif /* HAVE_STATFS_H */
2364
2365
2366static oslFileError osl_psz_getVolumeInformation (
2367 const sal_Char* pszDirectory, oslVolumeInfo* pInfo, sal_uInt32 uFieldMask)
2368{
2369 __OSL_STATFS_STRUCT sfs;
2370
2371 if (!pInfo)
2372 return osl_File_E_INVAL;
2373
2374 __OSL_STATFS_INIT(sfs);
2375
2376 pInfo->uValidFields = 0;
2377 pInfo->uAttributes = 0;
2378
2379 if ((__OSL_STATFS(pszDirectory, &sfs)) < 0)
2380 {
2381 oslFileError result = oslTranslateFileError(OSL_FET_ERROR, errno);
2382 return (result);
2383 }
2384
2385 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
2386 if (uFieldMask & osl_VolumeInfo_Mask_Attributes)
2387 {
2388 if (__OSL_STATFS_ISREMOTE(sfs))
2389 pInfo->uAttributes |= osl_Volume_Attribute_Remote;
2390
2391 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2392 }
2393
2394 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemCaseHandling)
2395 {
2396 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs))
2397 pInfo->uAttributes |= osl_Volume_Attribute_Case_Sensitive;
2398
2399 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs))
2400 pInfo->uAttributes |= osl_Volume_Attribute_Case_Is_Preserved;
2401
2402 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2403 }
2404
2405 pInfo->uTotalSpace = 0;
2406 pInfo->uFreeSpace = 0;
2407 pInfo->uUsedSpace = 0;
2408
2409#if defined(__OSL_STATFS_BLKSIZ)
2410
2411 if ((uFieldMask & osl_VolumeInfo_Mask_TotalSpace) ||
2412 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2413 {
2414 pInfo->uTotalSpace = __OSL_STATFS_BLKSIZ(sfs);
2415 pInfo->uTotalSpace *= (sal_uInt64)(sfs.f_blocks);
2416 pInfo->uValidFields |= osl_VolumeInfo_Mask_TotalSpace;
2417 }
2418
2419 if ((uFieldMask & osl_VolumeInfo_Mask_FreeSpace) ||
2420 (uFieldMask & osl_VolumeInfo_Mask_UsedSpace))
2421 {
2422 pInfo->uFreeSpace = __OSL_STATFS_BLKSIZ(sfs);
2423
2424 if (getuid() == 0)
2425 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
2426 else
2427 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bavail);
2428
2429 pInfo->uValidFields |= osl_VolumeInfo_Mask_FreeSpace;
2430 }
2431
2432#endif /* __OSL_STATFS_BLKSIZ */
2433
2434 if ((pInfo->uValidFields & osl_VolumeInfo_Mask_TotalSpace) &&
2435 (pInfo->uValidFields & osl_VolumeInfo_Mask_FreeSpace ))
2436 {
2437 pInfo->uUsedSpace = pInfo->uTotalSpace - pInfo->uFreeSpace;
2438 pInfo->uValidFields |= osl_VolumeInfo_Mask_UsedSpace;
2439 }
2440
2441 pInfo->uMaxNameLength = 0;
2442 if (uFieldMask & osl_VolumeInfo_Mask_MaxNameLength)
2443 {
2444 long nLen = pathconf(pszDirectory, _PC_NAME_MAX);
2445 if (nLen > 0)
2446 {
2447 pInfo->uMaxNameLength = (sal_uInt32)nLen;
2448 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxNameLength;
2449 }
2450 }
2451
2452 pInfo->uMaxPathLength = 0;
2453 if (uFieldMask & osl_VolumeInfo_Mask_MaxPathLength)
2454 {
2455 long nLen = pathconf (pszDirectory, _PC_PATH_MAX);
2456 if (nLen > 0)
2457 {
2458 pInfo->uMaxPathLength = (sal_uInt32)nLen;
2459 pInfo->uValidFields |= osl_VolumeInfo_Mask_MaxPathLength;
2460 }
2461 }
2462
2463#if defined(__OSL_STATFS_TYPENAME)
2464
2465 if (uFieldMask & osl_VolumeInfo_Mask_FileSystemName)
2466 {
2467 rtl_string2UString(
2468 &(pInfo->ustrFileSystemName),
2469 __OSL_STATFS_TYPENAME(sfs),
2470 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs)),
2471 osl_getThreadTextEncoding(),
2472 OUSTRING_TO_OSTRING_CVTFLAGS);
2473 OSL_ASSERT(pInfo->ustrFileSystemName != 0);
2474
2475 pInfo->uValidFields |= osl_VolumeInfo_Mask_FileSystemName;
2476 }
2477
2478#endif /* __OSL_STATFS_TYPENAME */
2479
2480 if (uFieldMask & osl_VolumeInfo_Mask_DeviceHandle)
2481 {
2482 /* FIXME: check also entries in mntent for the device
2483 and fill it with correct values */
2484
2485 *pInfo->pDeviceHandle = osl_isFloppyDrive(pszDirectory);
2486
2487 if (*pInfo->pDeviceHandle)
2488 {
2489 pInfo->uValidFields |= osl_VolumeInfo_Mask_DeviceHandle;
2490 pInfo->uAttributes |= osl_Volume_Attribute_Removeable;
2491 pInfo->uValidFields |= osl_VolumeInfo_Mask_Attributes;
2492 }
2493 }
2494 return osl_File_E_None;
2495}
2496
2497/******************************************
2498 * osl_psz_setFileTime
2499 *****************************************/
2500
2501static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
2502 const TimeValue* /*pCreationTime*/,
2503 const TimeValue* pLastAccessTime,
2504 const TimeValue* pLastWriteTime )

--- 69 unchanged lines hidden (view full) ---

2574 nRet=errno;
2575 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2576 }
2577
2578 return osl_File_E_None;
2579}
2580
2581
3045/******************************************
3046 * osl_psz_setFileTime
3047 *****************************************/
3048
3049static oslFileError osl_psz_setFileTime( const sal_Char* pszFilePath,
3050 const TimeValue* /*pCreationTime*/,
3051 const TimeValue* pLastAccessTime,
3052 const TimeValue* pLastWriteTime )

--- 69 unchanged lines hidden (view full) ---

3122 nRet=errno;
3123 return oslTranslateFileError(OSL_FET_ERROR, nRet);
3124 }
3125
3126 return osl_File_E_None;
3127}
3128
3129
2582/*****************************************
2583 * osl_psz_removeFile
2584 ****************************************/
2585#if 0
2586static oslFileError osl_psz_removeFile( const sal_Char* pszPath )
2587{
2588 int nRet=0;
2589 struct stat aStat;
2590
2591 nRet = stat(pszPath,&aStat);
2592 if ( nRet < 0 )
2593 {
2594 nRet=errno;
2595 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2596 }
2597
2598 if ( S_ISDIR(aStat.st_mode) )
2599 {
2600 return osl_File_E_ISDIR;
2601 }
2602
2603 nRet = unlink(pszPath);
2604 if ( nRet < 0 )
2605 {
2606 nRet=errno;
2607 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2608 }
2609
2610 return osl_File_E_None;
2611}
2612#endif
2613
2614/*****************************************
2615 * osl_psz_createDirectory
2616 ****************************************/
2617#if 0
2618static oslFileError osl_psz_createDirectory( const sal_Char* pszPath )
2619{
2620 int nRet=0;
2621 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
2622
2623 nRet = mkdir(pszPath,mode);
2624
2625 if ( nRet < 0 )
2626 {
2627 nRet=errno;
2628 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2629 }
2630
2631 return osl_File_E_None;
2632}
2633#endif
2634/*****************************************
2635 * osl_psz_removeDirectory
2636 ****************************************/
2637#if 0
2638static oslFileError osl_psz_removeDirectory( const sal_Char* pszPath )
2639{
2640 int nRet=0;
2641
2642 nRet = rmdir(pszPath);
2643
2644 if ( nRet < 0 )
2645 {
2646 nRet=errno;
2647 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2648 }
2649
2650 return osl_File_E_None;
2651}
2652#endif
2653/*****************************************
2654 * oslDoMoveFile
2655 ****************************************/
2656#if 0
2657static oslFileError oslDoMoveFile( const sal_Char* pszPath, const sal_Char* pszDestPath)
2658{
2659 oslFileError tErr=osl_File_E_invalidError;
2660
2661 tErr = osl_psz_moveFile(pszPath,pszDestPath);
2662 if ( tErr == osl_File_E_None )
2663 {
2664 return tErr;
2665 }
2666
2667 if ( tErr != osl_File_E_XDEV )
2668 {
2669 return tErr;
2670 }
2671
2672 tErr=osl_psz_copyFile(pszPath,pszDestPath);
2673
2674 if ( tErr != osl_File_E_None )
2675 {
2676 oslFileError tErrRemove;
2677 tErrRemove=osl_psz_removeFile(pszDestPath);
2678 return tErr;
2679 }
2680
2681 tErr=osl_psz_removeFile(pszPath);
2682
2683 return tErr;
2684}
2685#endif
2686/*****************************************
2687 * osl_psz_moveFile
2688 ****************************************/
2689#if 0
2690static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
2691{
2692
2693 int nRet = 0;
2694
2695 nRet = rename(pszPath,pszDestPath);
2696
2697 if ( nRet < 0 )
2698 {
2699 nRet=errno;
2700 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2701 }
2702
2703 return osl_File_E_None;
2704}
2705#endif
2706/*****************************************
2707 * osl_psz_copyFile
2708 ****************************************/
2709#if 0
2710static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
2711{
2712 time_t nAcTime=0;
2713 time_t nModTime=0;
2714 uid_t nUID=0;
2715 gid_t nGID=0;
2716 int nRet=0;
2717 mode_t nMode=0;
2718 struct stat aFileStat;
2719 oslFileError tErr=osl_File_E_invalidError;
2720 size_t nSourceSize=0;
2721 int DestFileExists=1;
2722
2723 /* mfe: does the source file really exists? */
2724 nRet = lstat(pszPath,&aFileStat);
2725
2726 if ( nRet < 0 )
2727 {
2728 nRet=errno;
2729 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2730 }
2731
2732 /* mfe: we do only copy files here! */
2733 if ( S_ISDIR(aFileStat.st_mode) )
2734 {
2735 return osl_File_E_ISDIR;
2736 }
2737
2738 nSourceSize=(size_t)aFileStat.st_size;
2739 nMode=aFileStat.st_mode;
2740 nAcTime=aFileStat.st_atime;
2741 nModTime=aFileStat.st_mtime;
2742 nUID=aFileStat.st_uid;
2743 nGID=aFileStat.st_gid;
2744
2745 nRet = stat(pszDestPath,&aFileStat);
2746 if ( nRet < 0 )
2747 {
2748 nRet=errno;
2749
2750 if ( nRet == ENOENT )
2751 {
2752 DestFileExists=0;
2753 }
2754/* return oslTranslateFileError(nRet);*/
2755 }
2756
2757 /* mfe: the destination file must not be a directory! */
2758 if ( nRet == 0 && S_ISDIR(aFileStat.st_mode) )
2759 {
2760 return osl_File_E_ISDIR;
2761 }
2762 else
2763 {
2764 /* mfe: file does not exists or is no dir */
2765 }
2766
2767 tErr = oslDoCopy(pszPath,pszDestPath,nMode,nSourceSize,DestFileExists);
2768
2769 if ( tErr != osl_File_E_None )
2770 {
2771 return tErr;
2772 }
2773
2774 /*
2775 * mfe: ignore return code
2776 * since only the success of the copy is
2777 * important
2778 */
2779 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
2780
2781 return tErr;
2782}
2783#endif
2784
2785/******************************************************************************
2786 *
2787 * Utility Functions
2788 *
2789 *****************************************************************************/
2790
2791
2792/*****************************************

--- 100 unchanged lines hidden (view full) ---

2893}
2894
2895/******************************************************************************
2896 *
2897 * GENERIC FLOPPY FUNCTIONS
2898 *
2899 *****************************************************************************/
2900
3130/******************************************************************************
3131 *
3132 * Utility Functions
3133 *
3134 *****************************************************************************/
3135
3136
3137/*****************************************

--- 100 unchanged lines hidden (view full) ---

3238}
3239
3240/******************************************************************************
3241 *
3242 * GENERIC FLOPPY FUNCTIONS
3243 *
3244 *****************************************************************************/
3245
2901
2902/*****************************************
2903 * osl_unmountVolumeDevice
2904 ****************************************/
3246/*****************************************
3247 * osl_unmountVolumeDevice
3248 ****************************************/
2905
2906oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
2907{
3249oslFileError osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle )
3250{
2908 oslFileError tErr = osl_File_E_NOSYS;
2909
2910 tErr = osl_unmountFloppy(Handle);
2911
2912 /* Perhaps current working directory is set to mount point */
2913
2914 if ( tErr )
2915 {
2916 sal_Char *pszHomeDir = getenv("HOME");
2917
2918 if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
2919 {
2920 /* try again */
2921
2922 tErr = osl_unmountFloppy(Handle);
2923
2924 OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2925 }
2926 }
2927
2928 return tErr;
3251 if ( Handle )
3252 return osl_File_E_None;
3253 else
3254 return osl_File_E_INVAL;
2929}
2930
2931/*****************************************
2932 * osl_automountVolumeDevice
2933 ****************************************/
3255}
3256
3257/*****************************************
3258 * osl_automountVolumeDevice
3259 ****************************************/
2934
2935oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
2936{
3260oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
3261{
2937 oslFileError tErr = osl_File_E_NOSYS;
2938
2939 tErr = osl_mountFloppy(Handle);
2940
2941 return tErr;
3262 if ( Handle )
3263 return osl_File_E_None;
3264 else
3265 return osl_File_E_INVAL;
2942}
2943
2944/*****************************************
2945 * osl_getVolumeDeviceMountPath
2946 ****************************************/
3266}
3267
3268/*****************************************
3269 * osl_getVolumeDeviceMountPath
3270 ****************************************/
2947
2948oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
2949{
3271oslFileError osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle, rtl_uString **pstrPath )
3272{
2950 oslVolumeDeviceHandleImpl* pItem = (oslVolumeDeviceHandleImpl*) Handle;
2951 sal_Char Buffer[PATH_MAX];
2952
2953 Buffer[0] = '\0';
2954
2955 if ( pItem == 0 || pstrPath == 0 )
2956 {
2957 return osl_File_E_INVAL;
2958 }
2959
2960 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
2961 {
2962 return osl_File_E_INVAL;
2963 }
2964
2965#ifdef DEBUG_OSL_FILE
2966 fprintf(stderr,"Handle is:\n");
2967 osl_printFloppyHandle(pItem);
2968#endif
2969
2970 snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
2971
2972#ifdef DEBUG_OSL_FILE
2973 fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
2974#endif
2975
2976 oslMakeUStrFromPsz(Buffer, pstrPath);
2977
2978 return osl_File_E_None;
3273 if ( Handle && pstrPath )
3274 {
3275 rtl_uString_assign( pstrPath, (rtl_uString *)Handle );
3276 return osl_File_E_None;
3277 }
3278 else
3279 return osl_File_E_INVAL;
2979}
2980
2981/*****************************************
2982 * osl_acquireVolumeDeviceHandle
2983 ****************************************/
2984
2985oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
2986{
3280}
3281
3282/*****************************************
3283 * osl_acquireVolumeDeviceHandle
3284 ****************************************/
3285
3286oslFileError SAL_CALL osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3287{
2987 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
2988
2989 if ( pItem == 0 )
2990 {
2991 return osl_File_E_INVAL;
2992 }
2993
2994 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
2995 {
2996 return osl_File_E_INVAL;
2997 }
2998
2999 ++pItem->RefCount;
3000
3001 return osl_File_E_None;
3288 if ( Handle )
3289 {
3290 rtl_uString_acquire( (rtl_uString *)Handle );
3291 return osl_File_E_None;
3292 }
3293 else
3294 return osl_File_E_INVAL;
3002}
3003
3004/*****************************************
3005 * osl_releaseVolumeDeviceHandle
3006 ****************************************/
3007
3008oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3009{
3295}
3296
3297/*****************************************
3298 * osl_releaseVolumeDeviceHandle
3299 ****************************************/
3300
3301oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
3302{
3010 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
3011
3012 if ( pItem == 0 )
3013 {
3014 return osl_File_E_INVAL;
3015 }
3016
3017 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3018 {
3019 return osl_File_E_INVAL;
3020 }
3021
3022 --pItem->RefCount;
3023
3024 if ( pItem->RefCount == 0 )
3025 {
3026 rtl_freeMemory(pItem);
3027 }
3028
3029 return osl_File_E_None;
3303 if ( Handle )
3304 {
3305 rtl_uString_release( (rtl_uString *)Handle );
3306 return osl_File_E_None;
3307 }
3308 else
3309 return osl_File_E_INVAL;
3030}
3031
3310}
3311
3032/*****************************************
3033 * osl_newVolumeDeviceHandleImpl
3034 ****************************************/
3035
3036static oslVolumeDeviceHandleImpl* osl_newVolumeDeviceHandleImpl()
3037{
3038 oslVolumeDeviceHandleImpl* pHandle;
3039 const size_t nSizeOfHandle = sizeof(oslVolumeDeviceHandleImpl);
3040
3041 pHandle = (oslVolumeDeviceHandleImpl*) rtl_allocateMemory (nSizeOfHandle);
3042 if (pHandle != NULL)
3043 {
3044 pHandle->ident[0] = 'O';
3045 pHandle->ident[1] = 'V';
3046 pHandle->ident[2] = 'D';
3047 pHandle->ident[3] = 'H';
3048 pHandle->pszMountPoint[0] = '\0';
3049 pHandle->pszFilePath[0] = '\0';
3050 pHandle->pszDevice[0] = '\0';
3051 pHandle->RefCount = 1;
3052 }
3053 return pHandle;
3054}
3055
3056/*****************************************
3057 * osl_freeVolumeDeviceHandleImpl
3058 ****************************************/
3059
3060static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
3061{
3062 if (pHandle != NULL)
3063 rtl_freeMemory (pHandle);
3064}
3065
3066
3067/******************************************************************************
3068 *
3069 * OS/2 FLOPPY FUNCTIONS
3070 *
3071 *****************************************************************************/
3312/******************************************************************************
3313 *
3314 * OS/2 FLOPPY FUNCTIONS
3315 *
3316 *****************************************************************************/
3072
3073#if defined(OS2)
3074static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
3075{
3076 return NULL;
3077}
3078
3317static oslVolumeDeviceHandle osl_isFloppyDrive(const sal_Char* pszPath)
3318{
3319 return NULL;
3320}
3321
3079static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
3080{
3081 return osl_File_E_BUSY;
3082}
3083
3084static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
3085{
3086 return osl_File_E_BUSY;
3087}
3088
3089static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
3090{
3091 return sal_False;
3092}
3093
3094static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
3095{
3096 return sal_False;
3097}
3098
3099
3100#ifdef DEBUG_OSL_FILE
3101static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
3102{
3103 if (pItem == 0 )
3104 {
3105 fprintf(stderr,"NULL Handle\n");
3106 return;
3107 }
3108 if ( pItem->ident[0] != 'O' || pItem->ident[1] != 'V' || pItem->ident[2] != 'D' || pItem->ident[3] != 'H' )
3109 {
3110#ifdef TRACE_OSL_FILE
3111 fprintf(stderr,"Invalid Handle]\n");
3112#endif
3113 return;
3114 }
3115
3116
3117 fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
3118 fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
3119 fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
3120
3121 return;
3122}
3123#endif
3124
3125#endif /* OS2 */