1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sal.hxx"
35 /************************************************************************
38 * Fix osl_getCanonicalName
40 * - Fix: check for corresponding struct sizes in exported functions
41 * - check size/use of oslDirectory
42 * - check size/use of oslDirectoryItem
43 * - check size/use of oslFileStatus
44 * - check size/use of oslVolumeDeviceHandle
45 * - check size/use of oslVolumeInfo
46 * - check size/use of oslFileHandle
47 ***********************************************************************/
52 #include <rtl/alloc.h>
54 #include "osl/file.hxx"
57 #include <sal/types.h>
58 #include <osl/thread.h>
59 #include <osl/diagnose.h>
60 #include "file_error_transl.h"
67 #include "file_path_helper.hxx"
68 #include "uunxapi.hxx"
82 #include <sys/mnttab.h>
83 #include <sys/statvfs.h>
85 #include <sys/fs/ufs_quota.h>
86 static const sal_Char
* MOUNTTAB
="/etc/mnttab";
92 #include <sys/quota.h>
94 static const sal_Char
* MOUNTTAB
="/etc/mtab";
96 #elif defined(NETBSD) || defined(FREEBSD)
97 #include <sys/param.h>
98 #include <sys/ucred.h>
99 #include <sys/mount.h>
100 #include <ufs/ufs/quota.h>
102 #define HAVE_STATFS_H
103 /* No mounting table on *BSD
104 * This information is stored only in the kernel. */
105 /* static const sal_Char* MOUNTTAB="/etc/mtab"; */
109 #include <sys/mount.h>
110 #include <sys/statvfs.h>
111 #define HAVE_STATFS_H
112 #include <sys/quota.h>
114 static const sal_Char
* MOUNTTAB
="/etc/mtab";
116 #elif defined(MACOSX)
117 #include <ufs/ufs/quota.h>
119 // static const sal_Char* MOUNTTAB="/etc/mtab";
121 #include <sys/param.h>
122 #include <sys/mount.h>
123 #define HAVE_STATFS_H
124 #define HAVE_O_EXLOCK
126 // add MACOSX Time Value
128 #define TimeValue CFTimeValue
129 #include <CoreFoundation/CoreFoundation.h>
134 #ifdef _DIRENT_HAVE_D_TYPE
135 #include "file_impl.hxx"
136 oslDirectoryItemImpl
* oslDirectoryItemImpl_CreateNew( rtl_uString
* _ustrFilePath
, bool _bHasDType
, unsigned char _DType
)
138 oslDirectoryItemImpl
*pItemObject
= (oslDirectoryItemImpl
*) malloc( sizeof( oslDirectoryItemImpl
) );
139 pItemObject
->RefCount
= 1;
140 pItemObject
->bHasType
= _bHasDType
;
141 pItemObject
->DType
= _DType
;
142 pItemObject
->ustrFilePath
= _ustrFilePath
;
147 void oslDirectoryItemImpl_Destroy( oslDirectoryItemImpl
* pItem
)
149 if( pItem
->ustrFilePath
) {
150 rtl_uString_release( pItem
->ustrFilePath
);
151 pItem
->ustrFilePath
= NULL
;
156 void oslDirectoryItemImpl_acquire( oslDirectoryItemImpl
* pItem
)
161 void oslDirectoryItemImpl_release( oslDirectoryItemImpl
* pItem
)
165 if( pItem
->RefCount
<= 0 )
166 oslDirectoryItemImpl_Destroy( pItem
);
170 #if OSL_DEBUG_LEVEL > 1
172 extern void debug_ustring(rtl_uString
*);
177 #ifdef DEBUG_OSL_FILE
178 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
180 # define PERROR( a, b )
183 extern "C" oslFileHandle
osl_createFileHandleFromFD( int fd
);
185 /******************************************************************************
187 * Data Type Definition
189 ******************************************************************************/
192 /* FIXME: reintroducing this may save some extra bytes per Item */
195 rtl_uString
* ustrFileName
; /* holds native file name */
196 rtl_uString
* ustrDirPath
; /* holds native dir path */
198 } oslDirectoryItemImpl
;
203 rtl_uString
* ustrPath
; /* holds native directory path */
210 rtl_uString
* ustrFilePath
; /* holds native file path */
216 typedef struct _oslVolumeDeviceHandleImpl
218 sal_Char pszMountPoint
[PATH_MAX
];
219 sal_Char pszFilePath
[PATH_MAX
];
220 sal_Char pszDevice
[PATH_MAX
];
223 } oslVolumeDeviceHandleImpl
;
226 /******************************************************************************
230 *****************************************************************************/
232 static const char * pFileLockEnvVar
= (char *) -1;
235 /******************************************************************************
237 * C-String Function Declarations
239 *****************************************************************************/
241 static oslFileError
osl_psz_getVolumeInformation(const sal_Char
* , oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
);
242 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
243 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
244 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
245 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
246 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
247 static oslFileError
osl_psz_setFileAttributes(const sal_Char
* pszFilePath
, sal_uInt64 uAttributes
);
248 static oslFileError
osl_psz_setFileTime(const sal_Char
* strFilePath
, const TimeValue
* pCreationTime
, const TimeValue
* pLastAccessTime
, const TimeValue
* pLastWriteTime
);
251 /******************************************************************************
253 * Static Module Utility Function Declarations
255 *****************************************************************************/
257 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
258 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
259 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
260 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
261 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
262 static rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
,rtl_uString
** uStr
);
264 /******************************************************************************
266 * Non-Static Utility Function Declarations
268 *****************************************************************************/
270 extern "C" int UnicodeToText( char *, size_t, const sal_Unicode
*, sal_Int32
);
271 extern "C" int TextToUnicode(
272 const char* text
, size_t text_buffer_size
, sal_Unicode
* unic_text
, sal_Int32 unic_text_buffer_size
);
274 /******************************************************************************
276 * 'removeable device' aka floppy functions
278 *****************************************************************************/
280 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
);
281 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
);
282 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
);
286 static sal_Bool
osl_isFloppyMounted(sal_Char
* pszPath
, sal_Char
* pszMountPath
);
287 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, sal_Char
* pBuffer
);
288 static sal_Bool
osl_checkFloppyPath(sal_Char
* pszPath
, sal_Char
* pszFilePath
, sal_Char
* pszDevicePath
);
292 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
);
293 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
);
298 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
);
299 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
);
302 #ifdef DEBUG_OSL_FILE
303 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* hFloppy
);
308 /*******************************************************************
310 ******************************************************************/
312 /* The AFP implementation of MacOS X 10.4 treats O_EXLOCK in a way
313 * that makes it impossible for OOo to create a backup copy of the
314 * file it keeps opened. OTOH O_SHLOCK for AFP behaves as desired by
315 * the OOo file handling, so we need to check the path of the file
316 * for the filesystem name.
319 static int adjustLockFlags(const char * path
, int flags
)
323 if( 0 <= statfs( path
, &s
) )
325 if( 0 == strncmp("afpfs", s
.f_fstypename
, 5) )
332 /* Needed flags to allow opening a webdav file */
333 flags
&= ~( O_EXLOCK
| O_SHLOCK
);
343 /*******************************************************************
345 ******************************************************************/
347 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
349 rtl_uString
* ustrSystemPath
= NULL
;
354 OSL_ASSERT(ustrDirectoryURL
&& (ustrDirectoryURL
->length
> 0));
355 OSL_ASSERT(pDirectory
);
357 if (0 == ustrDirectoryURL
->length
)
358 return osl_File_E_INVAL
;
360 /* convert file URL to system path */
361 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
363 if( osl_File_E_None
!= eRet
)
366 osl_systemPathRemoveSeparator(ustrSystemPath
);
368 /* convert unicode path to text */
369 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
)
371 && macxp_resolveAlias( path
, PATH_MAX
) == 0
376 DIR *pdir
= opendir( path
);
380 /* create and initialize impl structure */
381 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
385 pDirImpl
->pDirStruct
= pdir
;
386 pDirImpl
->ustrPath
= ustrSystemPath
;
388 *pDirectory
= (oslDirectory
) pDirImpl
;
389 return osl_File_E_None
;
399 /* should be removed by optimizer in product version */
400 PERROR( "osl_openDirectory", path
);
404 rtl_uString_release( ustrSystemPath
);
406 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
409 /****************************************************************************/
410 /* osl_closeDirectory */
411 /****************************************************************************/
413 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
415 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) Directory
;
416 oslFileError err
= osl_File_E_None
;
418 OSL_ASSERT( Directory
);
420 if( NULL
== pDirImpl
)
421 return osl_File_E_INVAL
;
423 /* close directory */
424 if( closedir( pDirImpl
->pDirStruct
) )
426 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
429 /* cleanup members */
430 rtl_uString_release( pDirImpl
->ustrPath
);
432 rtl_freeMemory( pDirImpl
);
437 /**********************************************
440 * readdir wrapper, filters out "." and ".."
442 *********************************************/
444 static struct dirent
* osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
446 struct dirent
* pdirent
;
448 while ((pdirent
= readdir(pdir
)) != NULL
)
450 if (bFilterLocalAndParentDir
&&
451 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
460 /****************************************************************************
461 * osl_getNextDirectoryItem
462 ***************************************************************************/
464 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, sal_uInt32
/*uHint*/)
466 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*)Directory
;
467 rtl_uString
* ustrFileName
= NULL
;
468 rtl_uString
* ustrFilePath
= NULL
;
469 struct dirent
* pEntry
;
471 OSL_ASSERT(Directory
);
474 if ((NULL
== Directory
) || (NULL
== pItem
))
475 return osl_File_E_INVAL
;
477 pEntry
= osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
480 return osl_File_E_NOENT
;
485 // convert decomposed filename to precomposed unicode
486 char composed_name
[BUFSIZ
];
487 CFMutableStringRef strRef
= CFStringCreateMutable (NULL
, 0 );
488 CFStringAppendCString( strRef
, pEntry
->d_name
, kCFStringEncodingUTF8
); //UTF8 is default on Mac OSX
489 CFStringNormalize( strRef
, kCFStringNormalizationFormC
);
490 CFStringGetCString( strRef
, composed_name
, BUFSIZ
, kCFStringEncodingUTF8
);
492 rtl_string2UString( &ustrFileName
, composed_name
, strlen( composed_name
),
493 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
496 /* convert file name to unicode */
497 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
498 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
499 OSL_ASSERT(ustrFileName
!= 0);
503 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &ustrFilePath
);
504 rtl_uString_release( ustrFileName
);
506 #ifdef _DIRENT_HAVE_D_TYPE
508 oslDirectoryItemImpl_release( ( oslDirectoryItemImpl
* )( *pItem
) );
510 *pItem
= (oslDirectoryItem
) oslDirectoryItemImpl_CreateNew( ustrFilePath
, true, pEntry
->d_type
);
512 /* use path as directory item */
513 *pItem
= (oslDirectoryItem
) ustrFilePath
;
516 return osl_File_E_None
;
519 /****************************************************************************/
520 /* osl_getDirectoryItem */
521 /****************************************************************************/
523 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
525 rtl_uString
* ustrSystemPath
= NULL
;
526 oslFileError osl_error
= osl_File_E_INVAL
;
528 OSL_ASSERT(ustrFileURL
);
531 if (0 == ustrFileURL
->length
|| NULL
== pItem
)
532 return osl_File_E_INVAL
;
534 osl_error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &ustrSystemPath
, sal_False
);
536 if (osl_File_E_None
!= osl_error
)
539 osl_systemPathRemoveSeparator(ustrSystemPath
);
541 if (0 == access_u(ustrSystemPath
, F_OK
))
543 #ifdef _DIRENT_HAVE_D_TYPE
544 *pItem
= (oslDirectoryItem
) oslDirectoryItemImpl_CreateNew( ustrSystemPath
, false );
546 *pItem
= (oslDirectoryItem
)ustrSystemPath
;
548 osl_error
= osl_File_E_None
;
552 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
553 rtl_uString_release(ustrSystemPath
);
559 /****************************************************************************/
560 /* osl_acquireDirectoryItem */
561 /****************************************************************************/
563 oslFileError
osl_acquireDirectoryItem( oslDirectoryItem Item
)
565 #ifdef _DIRENT_HAVE_D_TYPE
566 oslDirectoryItemImpl
* pImpl
= (oslDirectoryItemImpl
*) Item
;
568 rtl_uString
* ustrFilePath
= (rtl_uString
*) Item
;
573 #ifdef _DIRENT_HAVE_D_TYPE
575 oslDirectoryItemImpl_acquire( pImpl
);
578 rtl_uString_acquire( ustrFilePath
);
581 return osl_File_E_None
;
584 /****************************************************************************/
585 /* osl_releaseDirectoryItem */
586 /****************************************************************************/
588 oslFileError
osl_releaseDirectoryItem( oslDirectoryItem Item
)
590 #ifdef _DIRENT_HAVE_D_TYPE
591 oslDirectoryItemImpl
* pImpl
= (oslDirectoryItemImpl
*) Item
;
593 rtl_uString
* ustrFilePath
= (rtl_uString
*) Item
;
598 #ifdef _DIRENT_HAVE_D_TYPE
600 oslDirectoryItemImpl_release( pImpl
);
603 rtl_uString_release( ustrFilePath
);
606 return osl_File_E_None
;
609 /****************************************************************************
610 * osl_createFileHandleFromFD
611 ***************************************************************************/
613 oslFileHandle
osl_createFileHandleFromFD( int fd
)
615 oslFileHandleImpl
* pHandleImpl
= NULL
;
619 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
623 pHandleImpl
->ustrFilePath
= NULL
;
624 rtl_uString_new( &pHandleImpl
->ustrFilePath
);
625 pHandleImpl
->fd
= fd
;
627 /* FIXME: it should be detected whether the file has been locked */
628 pHandleImpl
->bLocked
= sal_True
;
632 return (oslFileHandle
)pHandleImpl
;
636 /****************************************************************************
638 ***************************************************************************/
641 #define OPEN_WRITE_FLAGS ( O_RDWR | O_EXLOCK | O_NONBLOCK )
642 #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR | O_EXLOCK | O_NONBLOCK )
644 #define OPEN_WRITE_FLAGS ( O_RDWR )
645 #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
648 oslFileError
osl_openFile( rtl_uString
* ustrFileURL
, oslFileHandle
* pHandle
, sal_uInt32 uFlags
)
650 oslFileHandleImpl
* pHandleImpl
= NULL
;
652 rtl_uString
* ustrFilePath
= NULL
;
654 char buffer
[PATH_MAX
];
656 int mode
= S_IRUSR
| S_IRGRP
| S_IROTH
;
657 int flags
= O_RDONLY
;
661 /* locking the complete file */
663 aflock
.l_whence
= SEEK_SET
;
667 OSL_ASSERT( ustrFileURL
);
668 OSL_ASSERT( pHandle
);
670 if( ( 0 == ustrFileURL
->length
) )
671 return osl_File_E_INVAL
;
673 /* convert file URL to system path */
674 eRet
= osl_getSystemPathFromFileURL( ustrFileURL
, &ustrFilePath
);
676 if( osl_File_E_None
!= eRet
)
679 osl_systemPathRemoveSeparator(ustrFilePath
);
681 /* convert unicode path to text */
682 if( UnicodeToText( buffer
, PATH_MAX
, ustrFilePath
->buffer
, ustrFilePath
->length
)
684 && macxp_resolveAlias( buffer
, PATH_MAX
) == 0
688 /* we do not open devices or such here */
689 if( !( uFlags
& osl_File_OpenFlag_Create
) )
691 struct stat aFileStat
;
693 if( 0 > stat( buffer
, &aFileStat
) )
695 PERROR( "osl_openFile", buffer
);
696 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
699 else if( !S_ISREG( aFileStat
.st_mode
) )
701 eRet
= osl_File_E_INVAL
;
705 if( osl_File_E_None
== eRet
)
711 if ( uFlags
& osl_File_OpenFlag_Write
)
713 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
714 flags
= OPEN_WRITE_FLAGS
;
716 flags
= adjustLockFlags(buffer
, flags
);
718 aflock
.l_type
= F_WRLCK
;
721 if ( uFlags
& osl_File_OpenFlag_Create
)
723 mode
|= S_IWUSR
| S_IWGRP
| S_IWOTH
;
724 flags
= OPEN_CREATE_FLAGS
;
726 flags
= adjustLockFlags(buffer
, flags
);
730 sal_Bool bNeedsLock
= ( ( uFlags
& osl_File_OpenFlag_NoLock
) == 0 );
740 fd
= open( buffer
, flags
, mode
);
743 sal_Bool bLocked
= sal_False
;
746 #ifndef HAVE_O_EXLOCK
747 /* check if file lock is enabled and clear l_type member of flock otherwise */
748 if( (char *) -1 == pFileLockEnvVar
)
750 /* FIXME: this is not MT safe */
751 pFileLockEnvVar
= getenv("SAL_ENABLE_FILE_LOCKING");
753 if( NULL
== pFileLockEnvVar
)
754 pFileLockEnvVar
= getenv("STAR_ENABLE_FILE_LOCKING");
757 /* disable range based locking */
758 pFileLockEnvVar
= NULL
;
760 /* remove the NONBLOCK flag again */
761 flags
= fcntl(fd
, F_GETFL
, NULL
);
762 flags
&= ~O_NONBLOCK
;
763 if( 0 > fcntl(fd
, F_SETFL
, flags
) )
766 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
769 if( NULL
== pFileLockEnvVar
)
772 /* lock the file if flock.l_type is set */
774 bLocked
= ( F_WRLCK
!= aflock
.l_type
);
777 /* Mac OSX returns ENOTSUP for webdav drives. We should try read lock */
778 if ( 0 == flock( fd
, LOCK_EX
| LOCK_NB
) || errno
== ENOTSUP
)
779 bLocked
= ( errno
!= ENOTSUP
) || ( 0 == flock( fd
, LOCK_SH
| LOCK_NB
) || errno
== ENOTSUP
);
782 bLocked
= ( F_WRLCK
!= aflock
.l_type
|| -1 != fcntl( fd
, F_SETLK
, &aflock
) );
787 if ( !bNeedsLock
|| bLocked
)
789 /* allocate memory for impl structure */
790 pHandleImpl
= (oslFileHandleImpl
*) rtl_allocateMemory( sizeof(oslFileHandleImpl
) );
793 pHandleImpl
->ustrFilePath
= ustrFilePath
;
794 pHandleImpl
->fd
= fd
;
795 pHandleImpl
->bLocked
= bLocked
;
797 *pHandle
= (oslFileHandle
) pHandleImpl
;
799 return osl_File_E_None
;
810 PERROR( "osl_openFile", buffer
);
811 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
815 eRet
= osl_File_E_INVAL
;
817 rtl_uString_release( ustrFilePath
);
821 /****************************************************************************/
823 /****************************************************************************/
825 oslFileError
osl_closeFile( oslFileHandle Handle
)
827 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
828 oslFileError eRet
= osl_File_E_INVAL
;
830 OSL_ASSERT( Handle
);
834 rtl_uString_release( pHandleImpl
->ustrFilePath
);
836 /* release file lock if locking is enabled */
837 if( pFileLockEnvVar
)
841 aflock
.l_type
= F_UNLCK
;
842 aflock
.l_whence
= SEEK_SET
;
846 if ( pHandleImpl
->bLocked
)
848 /* FIXME: check if file is really locked ? */
850 /* release the file share lock on this file */
852 /* Mac OSX will return ENOTSUP for webdav drives. We should ignore the error */
853 if ( 0 != flock( pHandleImpl
->fd
, LOCK_UN
| LOCK_NB
) && errno
!= ENOTSUP
)
855 if( -1 == fcntl( pHandleImpl
->fd
, F_SETLK
, &aflock
) )
858 PERROR( "osl_closeFile", "unlock failed" );
863 if( 0 > close( pHandleImpl
->fd
) )
865 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
868 eRet
= osl_File_E_None
;
870 rtl_freeMemory( pHandleImpl
);
876 /****************************************************************************/
877 /* osl_isEndOfFile */
878 /****************************************************************************/
880 oslFileError SAL_CALL
osl_isEndOfFile( oslFileHandle Handle
, sal_Bool
*pIsEOF
)
882 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*) Handle
;
883 oslFileError eRet
= osl_File_E_INVAL
;
887 long curPos
= lseek( pHandleImpl
->fd
, 0, SEEK_CUR
);
891 long endPos
= lseek( pHandleImpl
->fd
, 0, SEEK_END
);
895 *pIsEOF
= ( curPos
== endPos
);
896 curPos
= lseek( pHandleImpl
->fd
, curPos
, SEEK_SET
);
899 eRet
= osl_File_E_None
;
901 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
904 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
907 eRet
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
914 /****************************************************************************/
916 /****************************************************************************/
918 oslFileError
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
920 char srcPath
[PATH_MAX
];
921 char destPath
[PATH_MAX
];
924 OSL_ASSERT( ustrFileURL
);
925 OSL_ASSERT( ustrDestURL
);
927 /* convert source url to system path */
928 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
929 if( eRet
!= osl_File_E_None
)
932 /* convert destination url to system path */
933 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
934 if( eRet
!= osl_File_E_None
)
938 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
939 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
942 return oslDoMoveFile( srcPath
, destPath
);
945 /****************************************************************************/
947 /****************************************************************************/
949 oslFileError
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
951 char srcPath
[PATH_MAX
];
952 char destPath
[PATH_MAX
];
955 OSL_ASSERT( ustrFileURL
);
956 OSL_ASSERT( ustrDestURL
);
958 /* convert source url to system path */
959 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
960 if( eRet
!= osl_File_E_None
)
963 /* convert destination url to system path */
964 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
965 if( eRet
!= osl_File_E_None
)
969 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
970 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
973 return osl_psz_copyFile( srcPath
, destPath
);
976 /****************************************************************************/
978 /****************************************************************************/
980 oslFileError
osl_removeFile( rtl_uString
* ustrFileURL
)
985 OSL_ASSERT( ustrFileURL
);
987 /* convert file url to system path */
988 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
989 if( eRet
!= osl_File_E_None
)
993 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
994 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
997 return osl_psz_removeFile( path
);
1000 /****************************************************************************/
1001 /* osl_getVolumeInformation */
1002 /****************************************************************************/
1004 oslFileError
osl_getVolumeInformation( rtl_uString
* ustrDirectoryURL
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
1006 char path
[PATH_MAX
];
1009 OSL_ASSERT( ustrDirectoryURL
);
1010 OSL_ASSERT( pInfo
);
1012 /* convert directory url to system path */
1013 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1014 if( eRet
!= osl_File_E_None
)
1018 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
1019 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
1022 return osl_psz_getVolumeInformation( path
, pInfo
, uFieldMask
);
1025 /****************************************************************************/
1026 /* osl_createDirectory */
1027 /****************************************************************************/
1029 oslFileError
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
1031 char path
[PATH_MAX
];
1034 OSL_ASSERT( ustrDirectoryURL
);
1036 /* convert directory url to system path */
1037 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1038 if( eRet
!= osl_File_E_None
)
1042 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
1043 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
1046 return osl_psz_createDirectory( path
);
1049 /****************************************************************************/
1050 /* osl_removeDirectory */
1051 /****************************************************************************/
1053 oslFileError
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
1055 char path
[PATH_MAX
];
1058 OSL_ASSERT( ustrDirectoryURL
);
1060 /* convert directory url to system path */
1061 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
1062 if( eRet
!= osl_File_E_None
)
1066 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
1067 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
1070 return osl_psz_removeDirectory( path
);
1073 //#############################################
1074 int path_make_parent(sal_Unicode
* path
)
1076 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
1087 //#############################################
1088 int create_dir_with_callback(
1089 sal_Unicode
* directory_path
,
1090 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1093 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
1095 if (osl::mkdir(directory_path
, mode
) == 0)
1097 if (aDirectoryCreationCallbackFunc
)
1100 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
1101 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
1108 //#############################################
1109 oslFileError
create_dir_recursively_(
1110 sal_Unicode
* dir_path
,
1111 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1114 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
1115 "Path must not end with a slash");
1117 int native_err
= create_dir_with_callback(
1118 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1120 if (native_err
== 0)
1121 return osl_File_E_None
;
1123 if (native_err
!= ENOENT
)
1124 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
1126 // we step back until '/a_dir' at maximum because
1127 // we should get an error unequal ENOENT when
1128 // we try to create 'a_dir' at '/' and would so
1130 int pos
= path_make_parent(dir_path
);
1132 oslFileError osl_error
= create_dir_recursively_(
1133 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1135 if (osl_File_E_None
!= osl_error
)
1138 dir_path
[pos
] = '/';
1140 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
1143 //#######################################
1144 oslFileError SAL_CALL
osl_createDirectoryPath(
1145 rtl_uString
* aDirectoryUrl
,
1146 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
1149 if (aDirectoryUrl
== NULL
)
1150 return osl_File_E_INVAL
;
1152 rtl::OUString sys_path
;
1153 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
1154 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
1156 if (osl_error
!= osl_File_E_None
)
1159 osl::systemPathRemoveSeparator(sys_path
);
1161 // const_cast because sys_path is a local copy which we want to modify inplace instead of
1162 // coyp it into another buffer on the heap again
1163 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
1166 /****************************************************************************/
1167 /* osl_getCanonicalName */
1168 /****************************************************************************/
1170 oslFileError
osl_getCanonicalName( rtl_uString
* ustrFileURL
, rtl_uString
** pustrValidURL
)
1172 OSL_ENSURE(sal_False
, "osl_getCanonicalName not implemented");
1174 rtl_uString_newFromString(pustrValidURL
, ustrFileURL
);
1175 return osl_File_E_None
;
1179 /****************************************************************************/
1180 /* osl_setFileAttributes */
1181 /****************************************************************************/
1183 oslFileError
osl_setFileAttributes( rtl_uString
* ustrFileURL
, sal_uInt64 uAttributes
)
1185 char path
[PATH_MAX
];
1188 OSL_ASSERT( ustrFileURL
);
1190 /* convert file url to system path */
1191 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1192 if( eRet
!= osl_File_E_None
)
1196 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
1197 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
1200 return osl_psz_setFileAttributes( path
, uAttributes
);
1203 /****************************************************************************/
1204 /* osl_setFileTime */
1205 /****************************************************************************/
1207 oslFileError
osl_setFileTime( rtl_uString
* ustrFileURL
, const TimeValue
* pCreationTime
,
1208 const TimeValue
* pLastAccessTime
, const TimeValue
* pLastWriteTime
)
1210 char path
[PATH_MAX
];
1213 OSL_ASSERT( ustrFileURL
);
1215 /* convert file url to system path */
1216 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
1217 if( eRet
!= osl_File_E_None
)
1221 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
1222 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
1225 return osl_psz_setFileTime( path
, pCreationTime
, pLastAccessTime
, pLastWriteTime
);
1228 /******************************************************************************
1230 * Exported Module Functions
1231 * (independent of C or Unicode Strings)
1233 *****************************************************************************/
1235 /*******************************************
1237 ********************************************/
1239 SAL_CALL
osl_mapFile (
1240 oslFileHandle Handle
,
1247 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
1249 if ((0 == pHandleImpl
) || (-1 == pHandleImpl
->fd
) || (0 == ppAddr
))
1250 return osl_File_E_INVAL
;
1253 static sal_uInt64
const g_limit_size_t
= std::numeric_limits
< size_t >::max();
1254 if (g_limit_size_t
< uLength
)
1255 return osl_File_E_OVERFLOW
;
1256 size_t const nLength
= sal::static_int_cast
< size_t >(uLength
);
1258 static sal_uInt64
const g_limit_off_t
= std::numeric_limits
< off_t
>::max();
1259 if (g_limit_off_t
< uOffset
)
1260 return osl_File_E_OVERFLOW
;
1261 off_t
const nOffset
= sal::static_int_cast
< off_t
>(uOffset
);
1263 void* p
= mmap(NULL
, nLength
, PROT_READ
, MAP_SHARED
, pHandleImpl
->fd
, nOffset
);
1264 if (MAP_FAILED
== p
)
1265 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1268 if (uFlags
& osl_File_MapFlag_RandomAccess
)
1270 // Determine memory pagesize.
1271 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
1272 size_t const nPageSize
= getpagesize();
1274 size_t const nPageSize
= sysconf(_SC_PAGESIZE
);
1275 #endif /* xBSD || POSIX */
1276 if (size_t(-1) != nPageSize
)
1279 * Pagein, touching first byte of every memory page.
1280 * Note: volatile disables optimizing the loop away.
1282 sal_uInt8
* pData (reinterpret_cast<sal_uInt8
*>(*ppAddr
));
1283 size_t nSize (nLength
);
1285 volatile sal_uInt8 c
= 0;
1286 while (nSize
> nPageSize
)
1300 return osl_File_E_None
;
1303 /*******************************************
1305 ********************************************/
1307 SAL_CALL
osl_unmapFile (void* pAddr
, sal_uInt64 uLength
)
1310 return osl_File_E_INVAL
;
1312 static sal_uInt64
const g_limit_size_t
= std::numeric_limits
< size_t >::max();
1313 if (g_limit_size_t
< uLength
)
1314 return osl_File_E_OVERFLOW
;
1315 size_t const nLength
= sal::static_int_cast
< size_t >(uLength
);
1317 if (-1 == munmap(static_cast<char*>(pAddr
), nLength
))
1318 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1320 return osl_File_E_None
;
1323 /*******************************************
1325 ********************************************/
1327 oslFileError
osl_readFile(oslFileHandle Handle
, void* pBuffer
, sal_uInt64 uBytesRequested
, sal_uInt64
* pBytesRead
)
1330 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
1332 if ((0 == pHandleImpl
) || (pHandleImpl
->fd
< 0) || (0 == pBuffer
) || (0 == pBytesRead
))
1333 return osl_File_E_INVAL
;
1336 pHandleImpl
->fd
, pBuffer
,
1338 <= static_cast< size_t >(std::numeric_limits
< ssize_t
>::max()))
1339 ? static_cast< size_t >(uBytesRequested
)
1340 : static_cast< size_t >(std::numeric_limits
< ssize_t
>::max())));
1343 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1345 *pBytesRead
= nBytes
;
1346 return osl_File_E_None
;
1349 /*******************************************
1351 ********************************************/
1353 oslFileError
osl_writeFile(oslFileHandle Handle
, const void* pBuffer
, sal_uInt64 uBytesToWrite
, sal_uInt64
* pBytesWritten
)
1356 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
1358 OSL_ASSERT(pHandleImpl
);
1359 OSL_ASSERT(pBuffer
);
1360 OSL_ASSERT(pBytesWritten
);
1362 if ((0 == pHandleImpl
) || (0 == pBuffer
) || (0 == pBytesWritten
))
1363 return osl_File_E_INVAL
;
1365 OSL_ASSERT(pHandleImpl
->fd
>= 0);
1367 if (pHandleImpl
->fd
< 0)
1368 return osl_File_E_INVAL
;
1371 pHandleImpl
->fd
, pBuffer
,
1373 <= static_cast< size_t >(std::numeric_limits
< ssize_t
>::max()))
1374 ? static_cast< size_t >(uBytesToWrite
)
1375 : static_cast< size_t >(std::numeric_limits
< ssize_t
>::max())));
1378 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1380 *pBytesWritten
= nBytes
;
1381 return osl_File_E_None
;
1384 /*******************************************
1386 ********************************************/
1388 SAL_CALL
osl_readFileAt (
1389 oslFileHandle Handle
,
1392 sal_uInt64 uBytesRequested
,
1393 sal_uInt64
* pBytesRead
)
1395 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
1397 if ((0 == pHandleImpl
) || (pHandleImpl
->fd
< 0) || (0 == pBuffer
) || (0 == pBytesRead
))
1398 return osl_File_E_INVAL
;
1400 static sal_uInt64
const g_limit_off_t
= std::numeric_limits
< off_t
>::max();
1401 if (g_limit_off_t
< uOffset
)
1402 return osl_File_E_OVERFLOW
;
1403 off_t
const nOffset
= sal::static_int_cast
< off_t
>(uOffset
);
1405 static sal_uInt64
const g_limit_ssize_t
= std::numeric_limits
< ssize_t
>::max();
1406 if (g_limit_ssize_t
< uBytesRequested
)
1407 return osl_File_E_OVERFLOW
;
1408 size_t const nBytesRequested
= sal::static_int_cast
< size_t >(uBytesRequested
);
1410 #if defined(LINUX) || defined(SOLARIS)
1412 ssize_t nBytes
= ::pread(pHandleImpl
->fd
, pBuffer
, nBytesRequested
, nOffset
);
1413 if ((-1 == nBytes
) && (EOVERFLOW
== errno
))
1416 * Workaround for 'pread()' failure at end-of-file:
1418 * Some 'pread()'s fail with EOVERFLOW when reading at (or past)
1419 * end-of-file, different from 'lseek() + read()' behaviour.
1420 * Returning '0 bytes read' and 'osl_File_E_None' instead.
1425 #else /* LINUX || SOLARIS */
1427 if (-1 == ::lseek (pHandleImpl
->fd
, nOffset
, SEEK_SET
))
1428 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1430 ssize_t nBytes
= ::read(pHandleImpl
->fd
, pBuffer
, nBytesRequested
);
1432 #endif /* LINUX || SOLARIS */
1435 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1437 *pBytesRead
= nBytes
;
1438 return osl_File_E_None
;
1441 /*******************************************
1443 ********************************************/
1445 SAL_CALL
osl_writeFileAt (
1446 oslFileHandle Handle
,
1448 const void* pBuffer
,
1449 sal_uInt64 uBytesToWrite
,
1450 sal_uInt64
* pBytesWritten
)
1452 oslFileHandleImpl
* pHandleImpl
= (oslFileHandleImpl
*)Handle
;
1454 if ((0 == pHandleImpl
) || (pHandleImpl
->fd
< 0) || (0 == pBuffer
) || (0 == pBytesWritten
))
1455 return osl_File_E_INVAL
;
1457 static sal_uInt64
const g_limit_off_t
= std::numeric_limits
< off_t
>::max();
1458 if (g_limit_off_t
< uOffset
)
1459 return osl_File_E_OVERFLOW
;
1460 off_t
const nOffset
= sal::static_int_cast
< off_t
>(uOffset
);
1462 static sal_uInt64
const g_limit_ssize_t
= std::numeric_limits
< ssize_t
>::max();
1463 if (g_limit_ssize_t
< uBytesToWrite
)
1464 return osl_File_E_OVERFLOW
;
1465 size_t const nBytesToWrite
= sal::static_int_cast
< size_t >(uBytesToWrite
);
1467 #if defined(LINUX) || defined(SOLARIS)
1469 ssize_t nBytes
= ::pwrite(pHandleImpl
->fd
, pBuffer
, nBytesToWrite
, nOffset
);
1471 #else /* LINUX || SOLARIS */
1473 if (-1 == ::lseek(pHandleImpl
->fd
, nOffset
, SEEK_SET
))
1474 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1476 ssize_t nBytes
= ::write(pHandleImpl
->fd
, pBuffer
, nBytesToWrite
);
1478 #endif /* LINUX || SOLARIS */
1481 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1483 *pBytesWritten
= nBytes
;
1484 return osl_File_E_None
;
1487 /*******************************************
1489 ********************************************/
1491 oslFileError
osl_setFilePos( oslFileHandle Handle
, sal_uInt32 uHow
, sal_Int64 uPos
)
1493 oslFileHandleImpl
* pHandleImpl
=0;
1497 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
1498 if ( pHandleImpl
== 0 )
1500 return osl_File_E_INVAL
;
1503 if ( pHandleImpl
->fd
< 0 )
1505 return osl_File_E_INVAL
;
1508 /* FIXME mfe: setFilePos: Do we have any runtime function to determine LONG_MAX? */
1509 if ( uPos
> LONG_MAX
)
1511 return osl_File_E_OVERFLOW
;
1514 nOffset
=(off_t
)uPos
;
1518 case osl_Pos_Absolut
:
1519 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_SET
);
1522 case osl_Pos_Current
:
1523 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_CUR
);
1527 nOffset
= lseek(pHandleImpl
->fd
,nOffset
,SEEK_END
);
1531 return osl_File_E_INVAL
;
1537 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1540 return osl_File_E_None
;
1543 /************************************************
1545 ***********************************************/
1547 oslFileError
osl_getFilePos( oslFileHandle Handle
, sal_uInt64
* pPos
)
1549 oslFileHandleImpl
* pHandleImpl
=0;
1553 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
1554 if ( pHandleImpl
== 0 || pPos
== 0)
1556 return osl_File_E_INVAL
;
1559 if ( pHandleImpl
->fd
< 0 )
1561 return osl_File_E_INVAL
;
1564 nOffset
= lseek(pHandleImpl
->fd
,0,SEEK_CUR
);
1572 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1577 return osl_File_E_None
;
1580 /****************************************************************************
1582 ****************************************************************************/
1584 oslFileError
osl_getFileSize( oslFileHandle Handle
, sal_uInt64
* pSize
)
1586 oslFileHandleImpl
* pHandleImpl
=(oslFileHandleImpl
*) Handle
;
1587 if (pHandleImpl
== 0)
1588 return osl_File_E_INVAL
;
1590 struct stat file_stat
;
1591 if (fstat(pHandleImpl
->fd
, &file_stat
) == -1)
1592 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1594 *pSize
= file_stat
.st_size
;
1595 return osl_File_E_None
;
1598 /************************************************
1600 ***********************************************/
1602 oslFileError
osl_setFileSize( oslFileHandle Handle
, sal_uInt64 uSize
)
1604 oslFileHandleImpl
* pHandleImpl
=0;
1607 pHandleImpl
= (oslFileHandleImpl
*) Handle
;
1608 if ( pHandleImpl
== 0 )
1610 return osl_File_E_INVAL
;
1613 if ( pHandleImpl
->fd
< 0 )
1615 return osl_File_E_INVAL
;
1618 /* FIXME: mfe: setFileSize: Do we have any runtime function to determine LONG_MAX? */
1619 if ( uSize
> LONG_MAX
)
1621 return osl_File_E_OVERFLOW
;
1624 nOffset
= (off_t
)uSize
;
1625 if (ftruncate (pHandleImpl
->fd
, nOffset
) < 0)
1627 /* Failure. Try fallback algorithm */
1628 oslFileError result
;
1632 /* Save original result */
1633 result
= oslTranslateFileError (OSL_FET_ERROR
, errno
);
1634 PERROR("ftruncate", "Try osl_setFileSize [fallback]\n");
1636 /* Check against current size. Fail upon 'shrink' */
1637 if (fstat (pHandleImpl
->fd
, &aStat
) < 0)
1639 PERROR("ftruncate: fstat", "Out osl_setFileSize [error]\n");
1642 if ((0 <= nOffset
) && (nOffset
<= aStat
.st_size
))
1644 /* Failure upon 'shrink'. Return original result */
1648 /* Save current position */
1649 nCurPos
= (off_t
)lseek (pHandleImpl
->fd
, (off_t
)0, SEEK_CUR
);
1650 if (nCurPos
== (off_t
)(-1))
1652 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
1656 /* Try 'expand' via 'lseek()' and 'write()' */
1657 if (lseek (pHandleImpl
->fd
, (off_t
)(nOffset
- 1), SEEK_SET
) < 0)
1659 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]\n");
1662 if (write (pHandleImpl
->fd
, (char*)"", (size_t)1) < 0)
1664 /* Failure. Restore saved position */
1665 PERROR("ftruncate: write", "Out osl_setFileSize [error]\n");
1666 if (lseek (pHandleImpl
->fd
, (off_t
)nCurPos
, SEEK_SET
) < 0)
1668 #ifdef DEBUG_OSL_FILE
1669 perror("ftruncate: lseek");
1670 #endif /* DEBUG_OSL_FILE */
1675 /* Success. Restore saved position */
1676 if (lseek (pHandleImpl
->fd
, (off_t
)nCurPos
, SEEK_SET
) < 0)
1678 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
1683 return (osl_File_E_None
);
1686 /*###############################################*/
1687 oslFileError SAL_CALL
osl_syncFile(oslFileHandle Handle
)
1689 oslFileHandleImpl
* handle_impl
= (oslFileHandleImpl
*)Handle
;
1691 if (handle_impl
== 0)
1692 return osl_File_E_INVAL
;
1694 if (fsync(handle_impl
->fd
) == -1)
1695 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
1697 return osl_File_E_None
;
1700 /******************************************************************************
1702 * C-String Versions of Exported Module Functions
1704 *****************************************************************************/
1706 #ifdef HAVE_STATFS_H
1708 #if defined(FREEBSD) || defined(NETBSD) || defined(MACOSX)
1709 # define __OSL_STATFS_STRUCT struct statfs
1710 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
1711 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
1712 # define __OSL_STATFS_TYPENAME(a) ((a).f_fstypename)
1713 # define __OSL_STATFS_ISREMOTE(a) (((a).f_type & MNT_LOCAL) == 0)
1715 /* always return true if queried for the properties of
1716 the file system. If you think this is wrong under any
1717 of the target platforms fix it!!!! */
1718 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
1719 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
1720 #endif /* FREEBSD || NETBSD || MACOSX */
1723 # define __OSL_NFS_SUPER_MAGIC 0x6969
1724 # define __OSL_SMB_SUPER_MAGIC 0x517B
1725 # define __OSL_MSDOS_SUPER_MAGIC 0x4d44
1726 # define __OSL_NTFS_SUPER_MAGIC 0x5346544e
1727 # define __OSL_STATFS_STRUCT struct statfs
1728 # define __OSL_STATFS(dir, sfs) statfs((dir), (sfs))
1729 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_bsize))
1730 # define __OSL_STATFS_IS_NFS(a) (__OSL_NFS_SUPER_MAGIC == (a).f_type)
1731 # define __OSL_STATFS_IS_SMB(a) (__OSL_SMB_SUPER_MAGIC == (a).f_type)
1732 # define __OSL_STATFS_ISREMOTE(a) (__OSL_STATFS_IS_NFS((a)) || __OSL_STATFS_IS_SMB((a)))
1733 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type) && (__OSL_NTFS_SUPER_MAGIC != (a).f_type))
1734 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) ((__OSL_MSDOS_SUPER_MAGIC != (a).f_type))
1737 #if defined(SOLARIS) || defined(IRIX)
1738 # define __OSL_STATFS_STRUCT struct statvfs
1739 # define __OSL_STATFS(dir, sfs) statvfs((dir), (sfs))
1740 # define __OSL_STATFS_BLKSIZ(a) ((sal_uInt64)((a).f_frsize))
1741 # define __OSL_STATFS_TYPENAME(a) ((a).f_basetype)
1742 # define __OSL_STATFS_ISREMOTE(a) (rtl_str_compare((a).f_basetype, "nfs") == 0)
1744 /* always return true if queried for the properties of
1745 the file system. If you think this is wrong under any
1746 of the target platforms fix it!!!! */
1747 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
1748 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
1749 #endif /* SOLARIS || IRIX*/
1751 # define __OSL_STATFS_INIT(a) (memset(&(a), 0, sizeof(__OSL_STATFS_STRUCT)))
1753 #else /* no statfs available */
1755 # define __OSL_STATFS_STRUCT struct dummy {int i;}
1756 # define __OSL_STATFS_INIT(a) ((void)0)
1757 # define __OSL_STATFS(dir, sfs) (1)
1758 # define __OSL_STATFS_ISREMOTE(sfs) (0)
1759 # define __OSL_STATFS_IS_CASE_SENSITIVE_FS(a) (1)
1760 # define __OSL_STATFS_IS_CASE_PRESERVING_FS(a) (1)
1761 #endif /* HAVE_STATFS_H */
1764 static oslFileError
osl_psz_getVolumeInformation (
1765 const sal_Char
* pszDirectory
, oslVolumeInfo
* pInfo
, sal_uInt32 uFieldMask
)
1767 __OSL_STATFS_STRUCT sfs
;
1770 return osl_File_E_INVAL
;
1772 __OSL_STATFS_INIT(sfs
);
1774 pInfo
->uValidFields
= 0;
1775 pInfo
->uAttributes
= 0;
1777 if ((__OSL_STATFS(pszDirectory
, &sfs
)) < 0)
1779 oslFileError result
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
1783 /* FIXME: how to detect the kind of storage (fixed, cdrom, ...) */
1784 if (uFieldMask
& osl_VolumeInfo_Mask_Attributes
)
1786 if (__OSL_STATFS_ISREMOTE(sfs
))
1787 pInfo
->uAttributes
|= osl_Volume_Attribute_Remote
;
1789 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1792 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemCaseHandling
)
1794 if (__OSL_STATFS_IS_CASE_SENSITIVE_FS(sfs
))
1795 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Sensitive
;
1797 if (__OSL_STATFS_IS_CASE_PRESERVING_FS(sfs
))
1798 pInfo
->uAttributes
|= osl_Volume_Attribute_Case_Is_Preserved
;
1800 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1803 pInfo
->uTotalSpace
= 0;
1804 pInfo
->uFreeSpace
= 0;
1805 pInfo
->uUsedSpace
= 0;
1807 #if defined(__OSL_STATFS_BLKSIZ)
1809 if ((uFieldMask
& osl_VolumeInfo_Mask_TotalSpace
) ||
1810 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
1812 pInfo
->uTotalSpace
= __OSL_STATFS_BLKSIZ(sfs
);
1813 pInfo
->uTotalSpace
*= (sal_uInt64
)(sfs
.f_blocks
);
1814 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_TotalSpace
;
1817 if ((uFieldMask
& osl_VolumeInfo_Mask_FreeSpace
) ||
1818 (uFieldMask
& osl_VolumeInfo_Mask_UsedSpace
))
1820 pInfo
->uFreeSpace
= __OSL_STATFS_BLKSIZ(sfs
);
1823 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bfree
);
1825 pInfo
->uFreeSpace
*= (sal_uInt64
)(sfs
.f_bavail
);
1827 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FreeSpace
;
1830 #endif /* __OSL_STATFS_BLKSIZ */
1832 if ((pInfo
->uValidFields
& osl_VolumeInfo_Mask_TotalSpace
) &&
1833 (pInfo
->uValidFields
& osl_VolumeInfo_Mask_FreeSpace
))
1835 pInfo
->uUsedSpace
= pInfo
->uTotalSpace
- pInfo
->uFreeSpace
;
1836 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_UsedSpace
;
1839 pInfo
->uMaxNameLength
= 0;
1840 if (uFieldMask
& osl_VolumeInfo_Mask_MaxNameLength
)
1842 long nLen
= pathconf(pszDirectory
, _PC_NAME_MAX
);
1845 pInfo
->uMaxNameLength
= (sal_uInt32
)nLen
;
1846 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxNameLength
;
1850 pInfo
->uMaxPathLength
= 0;
1851 if (uFieldMask
& osl_VolumeInfo_Mask_MaxPathLength
)
1853 long nLen
= pathconf (pszDirectory
, _PC_PATH_MAX
);
1856 pInfo
->uMaxPathLength
= (sal_uInt32
)nLen
;
1857 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_MaxPathLength
;
1861 #if defined(__OSL_STATFS_TYPENAME)
1863 if (uFieldMask
& osl_VolumeInfo_Mask_FileSystemName
)
1866 &(pInfo
->ustrFileSystemName
),
1867 __OSL_STATFS_TYPENAME(sfs
),
1868 rtl_str_getLength(__OSL_STATFS_TYPENAME(sfs
)),
1869 osl_getThreadTextEncoding(),
1870 OUSTRING_TO_OSTRING_CVTFLAGS
);
1871 OSL_ASSERT(pInfo
->ustrFileSystemName
!= 0);
1873 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_FileSystemName
;
1876 #endif /* __OSL_STATFS_TYPENAME */
1878 if (uFieldMask
& osl_VolumeInfo_Mask_DeviceHandle
)
1880 /* FIXME: check also entries in mntent for the device
1881 and fill it with correct values */
1883 *pInfo
->pDeviceHandle
= osl_isFloppyDrive(pszDirectory
);
1885 if (*pInfo
->pDeviceHandle
)
1887 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_DeviceHandle
;
1888 pInfo
->uAttributes
|= osl_Volume_Attribute_Removeable
;
1889 pInfo
->uValidFields
|= osl_VolumeInfo_Mask_Attributes
;
1892 return osl_File_E_None
;
1895 /*************************************
1896 * osl_psz_setFileAttributes
1897 ************************************/
1899 static oslFileError
osl_psz_setFileAttributes( const sal_Char
* pszFilePath
, sal_uInt64 uAttributes
)
1901 oslFileError osl_error
= osl_File_E_None
;
1902 mode_t nNewMode
= 0;
1904 OSL_ENSURE(!(osl_File_Attribute_Hidden
& uAttributes
), "osl_File_Attribute_Hidden doesn't work under Unix");
1906 if (uAttributes
& osl_File_Attribute_OwnRead
)
1907 nNewMode
|= S_IRUSR
;
1909 if (uAttributes
& osl_File_Attribute_OwnWrite
)
1912 if (uAttributes
& osl_File_Attribute_OwnExe
)
1915 if (uAttributes
& osl_File_Attribute_GrpRead
)
1918 if (uAttributes
& osl_File_Attribute_GrpWrite
)
1921 if (uAttributes
& osl_File_Attribute_GrpExe
)
1924 if (uAttributes
& osl_File_Attribute_OthRead
)
1927 if (uAttributes
& osl_File_Attribute_OthWrite
)
1930 if (uAttributes
& osl_File_Attribute_OthExe
)
1933 if (chmod(pszFilePath
, nNewMode
) < 0)
1934 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
1939 /******************************************
1940 * osl_psz_setFileTime
1941 *****************************************/
1943 static oslFileError
osl_psz_setFileTime( const sal_Char
* pszFilePath
,
1944 const TimeValue
* /*pCreationTime*/,
1945 const TimeValue
* pLastAccessTime
,
1946 const TimeValue
* pLastWriteTime
)
1949 struct utimbuf aTimeBuffer
;
1950 struct stat aFileStat
;
1951 #ifdef DEBUG_OSL_FILE
1955 nRet
= lstat(pszFilePath
,&aFileStat
);
1960 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
1963 #ifdef DEBUG_OSL_FILE
1964 fprintf(stderr
,"File Times are (in localtime):\n");
1965 pTM
=localtime(&aFileStat
.st_ctime
);
1966 fprintf(stderr
,"CreationTime is '%s'\n",asctime(pTM
));
1967 pTM
=localtime(&aFileStat
.st_atime
);
1968 fprintf(stderr
,"AccessTime is '%s'\n",asctime(pTM
));
1969 pTM
=localtime(&aFileStat
.st_mtime
);
1970 fprintf(stderr
,"Modification is '%s'\n",asctime(pTM
));
1972 fprintf(stderr
,"File Times are (in UTC):\n");
1973 fprintf(stderr
,"CreationTime is '%s'\n",ctime(&aFileStat
.st_ctime
));
1974 fprintf(stderr
,"AccessTime is '%s'\n",ctime(&aTimeBuffer
.actime
));
1975 fprintf(stderr
,"Modification is '%s'\n",ctime(&aTimeBuffer
.modtime
));
1978 if ( pLastAccessTime
!= 0 )
1980 aTimeBuffer
.actime
=pLastAccessTime
->Seconds
;
1984 aTimeBuffer
.actime
=aFileStat
.st_atime
;
1987 if ( pLastWriteTime
!= 0 )
1989 aTimeBuffer
.modtime
=pLastWriteTime
->Seconds
;
1993 aTimeBuffer
.modtime
=aFileStat
.st_mtime
;
1996 /* mfe: Creation time not used here! */
1998 #ifdef DEBUG_OSL_FILE
1999 fprintf(stderr
,"File Times are (in localtime):\n");
2000 pTM
=localtime(&aFileStat
.st_ctime
);
2001 fprintf(stderr
,"CreationTime now '%s'\n",asctime(pTM
));
2002 pTM
=localtime(&aTimeBuffer
.actime
);
2003 fprintf(stderr
,"AccessTime now '%s'\n",asctime(pTM
));
2004 pTM
=localtime(&aTimeBuffer
.modtime
);
2005 fprintf(stderr
,"Modification now '%s'\n",asctime(pTM
));
2007 fprintf(stderr
,"File Times are (in UTC):\n");
2008 fprintf(stderr
,"CreationTime now '%s'\n",ctime(&aFileStat
.st_ctime
));
2009 fprintf(stderr
,"AccessTime now '%s'\n",ctime(&aTimeBuffer
.actime
));
2010 fprintf(stderr
,"Modification now '%s'\n",ctime(&aTimeBuffer
.modtime
));
2013 nRet
=utime(pszFilePath
,&aTimeBuffer
);
2017 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2020 return osl_File_E_None
;
2024 /*****************************************
2025 * osl_psz_removeFile
2026 ****************************************/
2028 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
2033 nRet
= lstat(pszPath
,&aStat
);
2037 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2040 if ( S_ISDIR(aStat
.st_mode
) )
2042 return osl_File_E_ISDIR
;
2045 nRet
= unlink(pszPath
);
2049 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2052 return osl_File_E_None
;
2055 /*****************************************
2056 * osl_psz_createDirectory
2057 ****************************************/
2059 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
2062 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
2064 nRet
= mkdir(pszPath
,mode
);
2069 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2072 return osl_File_E_None
;
2075 /*****************************************
2076 * osl_psz_removeDirectory
2077 ****************************************/
2079 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
2083 nRet
= rmdir(pszPath
);
2088 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2091 return osl_File_E_None
;
2094 /*****************************************
2096 ****************************************/
2098 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2100 oslFileError tErr
=osl_File_E_invalidError
;
2102 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
2103 if ( tErr
== osl_File_E_None
)
2108 if ( tErr
!= osl_File_E_XDEV
)
2113 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
2115 if ( tErr
!= osl_File_E_None
)
2117 oslFileError tErrRemove
;
2118 tErrRemove
=osl_psz_removeFile(pszDestPath
);
2122 tErr
=osl_psz_removeFile(pszPath
);
2127 /*****************************************
2129 ****************************************/
2131 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2136 nRet
= rename(pszPath
,pszDestPath
);
2141 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2144 return osl_File_E_None
;
2147 /*****************************************
2149 ****************************************/
2151 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
2159 struct stat aFileStat
;
2160 oslFileError tErr
=osl_File_E_invalidError
;
2161 size_t nSourceSize
=0;
2162 int DestFileExists
=1;
2164 /* mfe: does the source file really exists? */
2165 nRet
= lstat(pszPath
,&aFileStat
);
2170 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2173 /* mfe: we do only copy files here! */
2174 if ( S_ISDIR(aFileStat
.st_mode
) )
2176 return osl_File_E_ISDIR
;
2179 nSourceSize
=(size_t)aFileStat
.st_size
;
2180 nMode
=aFileStat
.st_mode
;
2181 nAcTime
=aFileStat
.st_atime
;
2182 nModTime
=aFileStat
.st_mtime
;
2183 nUID
=aFileStat
.st_uid
;
2184 nGID
=aFileStat
.st_gid
;
2186 nRet
= stat(pszDestPath
,&aFileStat
);
2191 if ( nRet
== ENOENT
)
2195 /* return oslTranslateFileError(nRet);*/
2198 /* mfe: the destination file must not be a directory! */
2199 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
2201 return osl_File_E_ISDIR
;
2205 /* mfe: file does not exists or is no dir */
2208 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
2210 if ( tErr
!= osl_File_E_None
)
2216 * mfe: ignore return code
2217 * since only the success of the copy is
2220 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
2226 /******************************************************************************
2230 *****************************************************************************/
2232 /*****************************************
2234 ****************************************/
2236 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
2238 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
2241 sal_Char pszTmpDestFile
[PATH_MAX
];
2242 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
2244 /* Quick fix for #106048, the whole copy file function seems
2245 to be erroneous anyway and needs to be rewritten.
2246 Besides osl_copyFile is currently not used from OO/SO code.
2248 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
2250 if ( DestFileExists
)
2252 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
2254 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
2255 return osl_File_E_NAMETOOLONG
;
2257 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
2259 /* FIXME: what if pszTmpDestFile already exists? */
2260 /* with getcanonical??? */
2261 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
2264 /* mfe: should be S_ISREG */
2265 if ( !S_ISLNK(nMode
) )
2267 /* copy SourceFile to DestFile */
2268 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
2270 /* mfe: OK redundant at the moment */
2271 else if ( S_ISLNK(nMode
) )
2273 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
2277 /* mfe: what to do here? */
2281 if ( nRet
> 0 && DestFileExists
== 1 )
2283 unlink(pszDestFileName
);
2284 rename(pszTmpDestFile
,pszDestFileName
);
2289 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2292 if ( DestFileExists
== 1 )
2294 unlink(pszTmpDestFile
);
2297 return osl_File_E_None
;
2300 /*****************************************
2301 * oslChangeFileModes
2302 ****************************************/
2304 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
2307 struct utimbuf aTimeBuffer
;
2309 nRet
= chmod(pszFileName
,nMode
);
2313 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2316 aTimeBuffer
.actime
=nAcTime
;
2317 aTimeBuffer
.modtime
=nModTime
;
2318 nRet
=utime(pszFileName
,&aTimeBuffer
);
2322 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
2325 if ( nUID
!= getuid() )
2330 nRet
=chown(pszFileName
,nUID
,nGID
);
2335 /* mfe: do not return an error here! */
2336 /* return oslTranslateFileError(nRet);*/
2339 return osl_File_E_None
;
2342 /*****************************************
2344 ****************************************/
2346 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
2350 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
2351 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
2352 sal_Char pszLinkContent
[PATH_MAX
];
2354 pszLinkContent
[0] = '\0';
2356 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
2364 pszLinkContent
[ nRet
] = 0;
2366 nRet
= symlink(pszLinkContent
,pszDestFileName
);
2377 /*****************************************
2379 ****************************************/
2381 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
2386 void* pSourceFile
=0;
2388 SourceFileFD
=open(pszSourceFileName
,O_RDONLY
);
2389 if ( SourceFileFD
< 0 )
2395 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
, mode
);
2397 if ( DestFileFD
< 0 )
2400 close(SourceFileFD
);
2404 /* HACK: because memory mapping fails on various
2405 platforms if the size of the source file is 0 byte */
2406 if (0 == nSourceSize
)
2408 close(SourceFileFD
);
2413 /* FIXME doCopy: fall back code for systems not having mmap */
2414 /* mmap file -- open dest file -- write once -- fsync it */
2415 pSourceFile
=mmap(0,nSourceSize
,PROT_READ
,MAP_PRIVATE
,SourceFileFD
,0);
2417 if ( pSourceFile
== MAP_FAILED
)
2419 /* it's important to set nRet before the hack
2420 otherwise errno may be changed by lstat */
2422 close(SourceFileFD
);
2428 nRet
= write(DestFileFD
,pSourceFile
,nSourceSize
);
2430 /* #112584# if 'write' could not write the requested number of bytes
2431 we have to fail of course; because it's not exactly specified if 'write'
2432 sets errno if less than requested byte could be written we set nRet
2433 explicitly to ENOSPC */
2434 if ((nRet
< 0) || (nRet
!= sal::static_int_cast
< int >(nSourceSize
)))
2441 close(SourceFileFD
);
2443 munmap((char*)pSourceFile
,nSourceSize
);
2447 nRet
= munmap((char*)pSourceFile
,nSourceSize
);
2451 close(SourceFileFD
);
2456 close(SourceFileFD
);
2458 // Removed call to 'fsync' again (#112584#) and instead
2459 // evaluate the return value of 'close' in order to detect
2460 // and report ENOSPC and other erronous conditions on close
2461 if (close(DestFileFD
) == -1)
2467 /*****************************************
2468 * oslMakeUStrFromPsz
2469 ****************************************/
2471 static rtl_uString
* oslMakeUStrFromPsz(const sal_Char
* pszStr
, rtl_uString
** ustrValid
)
2476 rtl_str_getLength( pszStr
),
2477 osl_getThreadTextEncoding(),
2478 OUSTRING_TO_OSTRING_CVTFLAGS
);
2479 OSL_ASSERT(*ustrValid
!= 0);
2484 /*****************************************************************************
2486 * converting unicode to text manually saves us the penalty of a temporary
2487 * rtl_String object.
2488 ****************************************************************************/
2490 int UnicodeToText( char * buffer
, size_t bufLen
, const sal_Unicode
* uniText
, sal_Int32 uniTextLen
)
2492 rtl_UnicodeToTextConverter hConverter
;
2494 sal_Size nSrcChars
, nDestBytes
;
2496 /* stolen from rtl/string.c */
2497 hConverter
= rtl_createUnicodeToTextConverter( osl_getThreadTextEncoding() );
2499 nDestBytes
= rtl_convertUnicodeToText( hConverter
, 0, uniText
, uniTextLen
,
2501 OUSTRING_TO_OSTRING_CVTFLAGS
| RTL_UNICODETOTEXT_FLAGS_FLUSH
,
2502 &nInfo
, &nSrcChars
);
2504 rtl_destroyUnicodeToTextConverter( hConverter
);
2506 if( nInfo
& RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
)
2512 /* ensure trailing '\0' */
2513 buffer
[nDestBytes
] = '\0';
2518 /*****************************************************************************
2522 The text to convert.
2524 @param text_buffer_size
2525 The number of characters.
2530 @param unic_text_buffer_size
2531 The size in characters of the unicode buffer.
2533 ****************************************************************************/
2537 size_t text_buffer_size
,
2538 sal_Unicode
* unic_text
,
2539 sal_Int32 unic_text_buffer_size
)
2541 rtl_TextToUnicodeConverter hConverter
;
2544 sal_Size nDestBytes
;
2546 /* stolen from rtl/string.c */
2547 hConverter
= rtl_createTextToUnicodeConverter(osl_getThreadTextEncoding());
2549 nDestBytes
= rtl_convertTextToUnicode(hConverter
,
2551 text
, text_buffer_size
,
2552 unic_text
, unic_text_buffer_size
,
2553 OSTRING_TO_OUSTRING_CVTFLAGS
| RTL_TEXTTOUNICODE_FLAGS_FLUSH
,
2554 &nInfo
, &nSrcChars
);
2556 rtl_destroyTextToUnicodeConverter(hConverter
);
2558 if (nInfo
& RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
)
2564 /* ensure trailing '\0' */
2565 unic_text
[nDestBytes
] = '\0';
2570 /******************************************************************************
2572 * GENERIC FLOPPY FUNCTIONS
2574 *****************************************************************************/
2577 /*****************************************
2578 * osl_unmountVolumeDevice
2579 ****************************************/
2581 oslFileError
osl_unmountVolumeDevice( oslVolumeDeviceHandle Handle
)
2583 oslFileError tErr
= osl_File_E_NOSYS
;
2585 tErr
= osl_unmountFloppy(Handle
);
2587 /* Perhaps current working directory is set to mount point */
2591 sal_Char
*pszHomeDir
= getenv("HOME");
2593 if ( pszHomeDir
&& strlen( pszHomeDir
) && 0 == chdir( pszHomeDir
) )
2597 tErr
= osl_unmountFloppy(Handle
);
2599 OSL_ENSURE( tErr
, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2606 /*****************************************
2607 * osl_automountVolumeDevice
2608 ****************************************/
2610 oslFileError
osl_automountVolumeDevice( oslVolumeDeviceHandle Handle
)
2612 oslFileError tErr
= osl_File_E_NOSYS
;
2614 tErr
= osl_mountFloppy(Handle
);
2619 /*****************************************
2620 * osl_getVolumeDeviceMountPath
2621 ****************************************/
2623 oslFileError
osl_getVolumeDeviceMountPath( oslVolumeDeviceHandle Handle
, rtl_uString
**pstrPath
)
2625 oslVolumeDeviceHandleImpl
* pItem
= (oslVolumeDeviceHandleImpl
*) Handle
;
2626 sal_Char Buffer
[PATH_MAX
];
2630 if ( pItem
== 0 || pstrPath
== 0 )
2632 return osl_File_E_INVAL
;
2635 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
2637 return osl_File_E_INVAL
;
2640 #ifdef DEBUG_OSL_FILE
2641 fprintf(stderr
,"Handle is:\n");
2642 osl_printFloppyHandle(pItem
);
2645 snprintf(Buffer
, sizeof(Buffer
), "file://%s", pItem
->pszMountPoint
);
2647 #ifdef DEBUG_OSL_FILE
2648 fprintf(stderr
,"Mount Point is: '%s'\n",Buffer
);
2651 oslMakeUStrFromPsz(Buffer
, pstrPath
);
2653 return osl_File_E_None
;
2656 /*****************************************
2657 * osl_acquireVolumeDeviceHandle
2658 ****************************************/
2660 oslFileError SAL_CALL
osl_acquireVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
2662 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
2666 return osl_File_E_INVAL
;
2669 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
2671 return osl_File_E_INVAL
;
2676 return osl_File_E_None
;
2679 /*****************************************
2680 * osl_releaseVolumeDeviceHandle
2681 ****************************************/
2683 oslFileError
osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle
)
2685 oslVolumeDeviceHandleImpl
* pItem
=(oslVolumeDeviceHandleImpl
*) Handle
;
2689 return osl_File_E_INVAL
;
2692 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
2694 return osl_File_E_INVAL
;
2699 if ( pItem
->RefCount
== 0 )
2701 rtl_freeMemory(pItem
);
2704 return osl_File_E_None
;
2709 /*****************************************
2710 * osl_newVolumeDeviceHandleImpl
2711 ****************************************/
2713 static oslVolumeDeviceHandleImpl
* osl_newVolumeDeviceHandleImpl()
2715 oslVolumeDeviceHandleImpl
* pHandle
;
2716 const size_t nSizeOfHandle
= sizeof(oslVolumeDeviceHandleImpl
);
2718 pHandle
= (oslVolumeDeviceHandleImpl
*) rtl_allocateMemory (nSizeOfHandle
);
2719 if (pHandle
!= NULL
)
2721 pHandle
->ident
[0] = 'O';
2722 pHandle
->ident
[1] = 'V';
2723 pHandle
->ident
[2] = 'D';
2724 pHandle
->ident
[3] = 'H';
2725 pHandle
->pszMountPoint
[0] = '\0';
2726 pHandle
->pszFilePath
[0] = '\0';
2727 pHandle
->pszDevice
[0] = '\0';
2728 pHandle
->RefCount
= 1;
2733 /*****************************************
2734 * osl_freeVolumeDeviceHandleImpl
2735 ****************************************/
2737 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl
* pHandle
)
2739 if (pHandle
!= NULL
)
2740 rtl_freeMemory (pHandle
);
2744 /******************************************************************************
2746 * SOLARIS FLOPPY FUNCTIONS
2748 *****************************************************************************/
2750 #if defined(SOLARIS)
2751 /* compare a given devicename with the typical device names on a Solaris box */
2753 osl_isAFloppyDevice (const char* pDeviceName
)
2755 const char* pFloppyDevice
[] = {
2756 "/dev/fd", "/dev/rfd",
2757 "/dev/diskette", "/dev/rdiskette",
2758 "/vol/dev/diskette", "/vol/dev/rdiskette"
2762 for (i
= 0; i
< (sizeof(pFloppyDevice
)/sizeof(pFloppyDevice
[0])); i
++)
2764 if (strncmp(pDeviceName
, pFloppyDevice
[i
], strlen(pFloppyDevice
[i
])) == 0)
2770 /* compare two directories whether the first may be a parent of the second. this
2771 * does not realpath() resolving */
2773 osl_isAParentDirectory (const char* pParentDir
, const char* pSubDir
)
2775 return strncmp(pParentDir
, pSubDir
, strlen(pParentDir
)) == 0;
2778 /* the name of the routine is obviously silly. But anyway create a
2779 * oslVolumeDeviceHandle with correct mount point, device name and a resolved filepath
2780 * only if pszPath points to file or directory on a floppy */
2781 static oslVolumeDeviceHandle
2782 osl_isFloppyDrive(const sal_Char
* pszPath
)
2785 struct mnttab aMountEnt
;
2786 oslVolumeDeviceHandleImpl
* pHandle
;
2788 if ((pHandle
= osl_newVolumeDeviceHandleImpl()) == NULL
)
2792 if (realpath(pszPath
, pHandle
->pszFilePath
) == NULL
)
2794 osl_freeVolumeDeviceHandleImpl (pHandle
);
2797 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
2799 osl_freeVolumeDeviceHandleImpl (pHandle
);
2803 while (getmntent(pMountTab
, &aMountEnt
) == 0)
2805 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
2806 const char *pDevice
= aMountEnt
.mnt_special
;
2807 if ( osl_isAParentDirectory (aMountEnt
.mnt_mountp
, pHandle
->pszFilePath
)
2808 && osl_isAFloppyDevice (aMountEnt
.mnt_special
))
2810 /* skip the last item for it is the name of the disk */
2811 char * pc
= strrchr( aMountEnt
.mnt_special
, '/' );
2815 int len
= pc
- aMountEnt
.mnt_special
;
2817 strncpy( pHandle
->pszDevice
, aMountEnt
.mnt_special
, len
);
2818 pHandle
->pszDevice
[len
] = '\0';
2822 /* #106048 use save str functions to avoid buffer overflows */
2823 memset(pHandle
->pszDevice
, 0, sizeof(pHandle
->pszDevice
));
2824 strncpy(pHandle
->pszDevice
, aMountEnt
.mnt_special
, sizeof(pHandle
->pszDevice
) - 1);
2827 /* remember the mount point */
2828 memset(pHandle
->pszMountPoint
, 0, sizeof(pHandle
->pszMountPoint
));
2829 strncpy(pHandle
->pszMountPoint
, aMountEnt
.mnt_mountp
, sizeof(pHandle
->pszMountPoint
) - 1);
2837 osl_freeVolumeDeviceHandleImpl (pHandle
);
2841 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
2844 struct mnttab aMountEnt
;
2845 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
2848 sal_Char pszCmd
[512] = "";
2851 return osl_File_E_INVAL
;
2853 /* FIXME: don't know what this is good for */
2854 if ( pHandle
->ident
[0] != 'O' || pHandle
->ident
[1] != 'V' || pHandle
->ident
[2] != 'D' || pHandle
->ident
[3] != 'H' )
2855 return osl_File_E_INVAL
;
2857 snprintf(pszCmd
, sizeof(pszCmd
), "eject -q %s > /dev/null 2>&1", pHandle
->pszDevice
);
2859 nRet
= system( pszCmd
);
2861 switch ( WEXITSTATUS(nRet
) )
2865 /* lookup the device in mount tab again */
2866 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
2867 return osl_File_E_BUSY
;
2869 while (getmntent(pMountTab
, &aMountEnt
) == 0)
2871 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
2872 const char *pDevice
= aMountEnt
.mnt_special
;
2873 if ( 0 == strncmp( pHandle
->pszDevice
, aMountEnt
.mnt_special
, strlen(pHandle
->pszDevice
) ) )
2875 memset(pHandle
->pszMountPoint
, 0, sizeof(pHandle
->pszMountPoint
));
2876 strncpy (pHandle
->pszMountPoint
, aMountEnt
.mnt_mountp
, sizeof(pHandle
->pszMountPoint
) - 1);
2879 return osl_File_E_None
;
2884 return osl_File_E_BUSY
;
2886 //break; // break not necessary here, see return statements before
2889 return osl_File_E_BUSY
;
2895 return osl_File_E_BUSY
;
2898 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
2901 // struct mnttab aMountEnt;
2902 oslVolumeDeviceHandleImpl
* pHandle
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
2905 sal_Char pszCmd
[512] = "";
2908 return osl_File_E_INVAL
;
2910 /* FIXME: don't know what this is good for */
2911 if ( pHandle
->ident
[0] != 'O' || pHandle
->ident
[1] != 'V' || pHandle
->ident
[2] != 'D' || pHandle
->ident
[3] != 'H' )
2912 return osl_File_E_INVAL
;
2914 snprintf(pszCmd
, sizeof(pszCmd
), "eject %s > /dev/null 2>&1", pHandle
->pszDevice
);
2916 nRet
= system( pszCmd
);
2918 switch ( WEXITSTATUS(nRet
) )
2923 struct mnttab aMountEnt
;
2925 /* lookup if device is still in mount tab */
2926 if ((pMountTab
= fopen (MOUNTTAB
, "r")) == NULL
)
2927 return osl_File_E_BUSY
;
2929 while (getmntent(pMountTab
, &aMountEnt
) == 0)
2931 const char *pMountPoint
= aMountEnt
.mnt_mountp
;
2932 const char *pDevice
= aMountEnt
.mnt_special
;
2933 if ( 0 == strncmp( pHandle
->pszDevice
, aMountEnt
.mnt_special
, strlen(pHandle
->pszDevice
) ) )
2936 return osl_File_E_BUSY
;
2941 pHandle
->pszMountPoint
[0] = 0;
2942 return osl_File_E_None
;
2945 //break; //break not necessary, see return statements before
2948 return osl_File_E_NODEV
;
2951 pHandle
->pszMountPoint
[0] = 0;
2952 return osl_File_E_None
;
2958 return osl_File_E_BUSY
;
2961 #endif /* SOLARIS */
2963 /******************************************************************************
2965 * LINUX FLOPPY FUNCTIONS
2967 *****************************************************************************/
2970 static oslVolumeDeviceHandle
2971 osl_isFloppyDrive (const sal_Char
* pszPath
)
2973 oslVolumeDeviceHandleImpl
* pItem
= osl_newVolumeDeviceHandleImpl();
2974 if (osl_getFloppyMountEntry(pszPath
, pItem
))
2975 return (oslVolumeDeviceHandle
) pItem
;
2977 osl_freeVolumeDeviceHandleImpl (pItem
);
2983 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
2985 sal_Bool bRet
= sal_False
;
2986 oslVolumeDeviceHandleImpl
* pItem
=0;
2988 sal_Char pszCmd
[PATH_MAX
];
2989 const sal_Char
* pszMountProg
= "mount";
2990 sal_Char
* pszSuDo
= 0;
2991 sal_Char
* pszTmp
= 0;
2995 #ifdef TRACE_OSL_FILE
2996 fprintf(stderr
,"In osl_mountFloppy\n");
2999 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
3003 #ifdef TRACE_OSL_FILE
3004 fprintf(stderr
,"Out osl_mountFloppy [pItem == 0]\n");
3007 return osl_File_E_INVAL
;
3010 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3012 #ifdef TRACE_OSL_FILE
3013 fprintf(stderr
,"Out osl_mountFloppy [invalid handle]\n");
3015 return osl_File_E_INVAL
;
3018 bRet
= osl_isFloppyMounted(pItem
);
3019 if ( bRet
== sal_True
)
3021 #ifdef DEBUG_OSL_FILE
3022 fprintf(stderr
,"detected mounted floppy at '%s'\n",pItem
->pszMountPoint
);
3024 return osl_File_E_BUSY
;
3027 /* mfe: we can't use the mount(2) system call!!! */
3028 /* even if we are root */
3029 /* since mtab is not updated!!! */
3030 /* but we need it to be updated */
3031 /* some "magic" must be done */
3033 /* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
3034 /* if ( nRet != 0 ) */
3037 /* #ifdef DEBUG_OSL_FILE */
3038 /* perror("mount"); */
3042 pszTmp
= getenv("SAL_MOUNT_MOUNTPROG");
3045 pszMountProg
=pszTmp
;
3048 pszTmp
=getenv("SAL_MOUNT_SU_DO");
3056 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s %s",pszSuDo
,pszMountProg
,pItem
->pszDevice
,pItem
->pszMountPoint
);
3060 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszMountProg
,pItem
->pszMountPoint
);
3064 #ifdef DEBUG_OSL_FILE
3065 fprintf(stderr
,"executing '%s'\n",pszCmd
);
3068 nRet
= system(pszCmd
);
3070 #ifdef DEBUG_OSL_FILE
3071 fprintf(stderr
,"call returned '%i'\n",nRet
);
3072 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
3076 switch ( WEXITSTATUS(nRet
) )
3111 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
3117 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
3119 oslVolumeDeviceHandleImpl
* pItem
=0;
3121 sal_Char pszCmd
[PATH_MAX
];
3122 sal_Char
* pszTmp
= 0;
3123 sal_Char
* pszSuDo
= 0;
3124 const sal_Char
* pszUmountProg
= "umount";
3128 #ifdef TRACE_OSL_FILE
3129 fprintf(stderr
,"In osl_unmountFloppy\n");
3132 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
3136 #ifdef TRACE_OSL_FILE
3137 fprintf(stderr
,"Out osl_unmountFloppy [pItem==0]\n");
3139 return osl_File_E_INVAL
;
3142 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3144 #ifdef TRACE_OSL_FILE
3145 fprintf(stderr
,"Out osl_unmountFloppy [invalid handle]\n");
3147 return osl_File_E_INVAL
;
3150 /* mfe: we can't use the umount(2) system call!!! */
3151 /* even if we are root */
3152 /* since mtab is not updated!!! */
3153 /* but we need it to be updated */
3154 /* some "magic" must be done */
3156 /* nRet=umount(pItem->pszDevice); */
3157 /* if ( nRet != 0 ) */
3161 /* #ifdef DEBUG_OSL_FILE */
3162 /* perror("mount"); */
3167 pszTmp
= getenv("SAL_MOUNT_UMOUNTPROG");
3170 pszUmountProg
=pszTmp
;
3173 pszTmp
= getenv("SAL_MOUNT_SU_DO");
3181 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s",pszSuDo
,pszUmountProg
,pItem
->pszMountPoint
);
3185 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszUmountProg
,pItem
->pszMountPoint
);
3189 #ifdef DEBUG_OSL_FILE
3190 fprintf(stderr
,"executing '%s'\n",pszCmd
);
3193 nRet
= system(pszCmd
);
3195 #ifdef DEBUG_OSL_FILE
3196 fprintf(stderr
,"call returned '%i'\n",nRet
);
3197 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
3200 switch ( WEXITSTATUS(nRet
) )
3211 #ifdef TRACE_OSL_FILE
3212 fprintf(stderr
,"Out osl_unmountFloppy [ok]\n");
3215 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
3217 /* return osl_File_E_None;*/
3224 osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
3226 struct mntent
* pMountEnt
;
3229 pMountTab
= setmntent (MOUNTTAB
, "r");
3233 while ((pMountEnt
= getmntent(pMountTab
)) != 0)
3235 if ( strncmp(pMountEnt
->mnt_dir
, pszPath
, strlen(pMountEnt
->mnt_dir
)) == 0
3236 && strncmp(pMountEnt
->mnt_fsname
, "/dev/fd", strlen("/dev/fd")) == 0)
3238 memset(pItem
->pszMountPoint
, 0, sizeof(pItem
->pszMountPoint
));
3239 strncpy(pItem
->pszMountPoint
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszMountPoint
) - 1);
3241 memset(pItem
->pszFilePath
, 0, sizeof(pItem
->pszFilePath
));
3242 strncpy(pItem
->pszFilePath
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszFilePath
) - 1);
3244 memset(pItem
->pszDevice
, 0, sizeof(pItem
->pszDevice
));
3245 strncpy(pItem
->pszDevice
, pMountEnt
->mnt_fsname
, sizeof(pItem
->pszDevice
) - 1);
3247 endmntent (pMountTab
);
3252 endmntent (pMountTab
);
3259 osl_isFloppyMounted (oslVolumeDeviceHandleImpl
* pDevice
)
3261 oslVolumeDeviceHandleImpl aItem
;
3263 if ( osl_getFloppyMountEntry (pDevice
->pszMountPoint
, &aItem
)
3264 && strcmp (aItem
.pszMountPoint
, pDevice
->pszMountPoint
) == 0
3265 && strcmp (aItem
.pszDevice
, pDevice
->pszDevice
) == 0)
3273 /******************************************************************************
3275 * IRIX FLOPPY FUNCTIONS
3277 *****************************************************************************/
3280 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
3282 oslVolumeDeviceHandleImpl
* pItem
= osl_newVolumeDeviceHandleImpl ();
3283 sal_Bool bRet
= sal_False
;
3285 #ifdef TRACE_OSL_FILE
3286 fprintf(stderr
,"In osl_isFloppyDrive\n");
3289 bRet
=osl_getFloppyMountEntry(pszPath
,pItem
);
3291 if ( bRet
== sal_False
)
3293 #ifdef TRACE_OSL_FILE
3294 fprintf(stderr
,"Out osl_isFloppyDrive [not a floppy]\n");
3296 rtl_freeMemory(pItem
);
3301 #ifdef DEBUG_OSL_FILE
3302 osl_printFloppyHandle(pItem
);
3304 #ifdef TRACE_OSL_FILE
3305 fprintf(stderr
,"Out osl_isFloppyDrive [ok]\n");
3308 return (oslVolumeDeviceHandle
) pItem
;
3312 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
3314 sal_Bool bRet
= sal_False
;
3315 oslVolumeDeviceHandleImpl
* pItem
=0;
3317 sal_Char pszCmd
[PATH_MAX
];
3318 sal_Char
* pszMountProg
= "mount";
3319 sal_Char
* pszSuDo
= 0;
3320 sal_Char
* pszTmp
= 0;
3324 #ifdef TRACE_OSL_FILE
3325 fprintf(stderr
,"In osl_mountFloppy\n");
3328 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
3332 #ifdef TRACE_OSL_FILE
3333 fprintf(stderr
,"Out osl_mountFloppy [pItem == 0]\n");
3336 return osl_File_E_INVAL
;
3339 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3341 #ifdef TRACE_OSL_FILE
3342 fprintf(stderr
,"Out osl_mountFloppy [invalid handle]\n");
3344 return osl_File_E_INVAL
;
3347 bRet
= osl_isFloppyMounted(pItem
);
3348 if ( bRet
== sal_True
)
3350 #ifdef DEBUG_OSL_FILE
3351 fprintf(stderr
,"detected mounted floppy at '%s'\n",pItem
->pszMountPoint
);
3353 return osl_File_E_BUSY
;
3356 /* mfe: we can't use the mount(2) system call!!! */
3357 /* even if we are root */
3358 /* since mtab is not updated!!! */
3359 /* but we need it to be updated */
3360 /* some "magic" must be done */
3362 /* nRet = mount(pItem->pszDevice,pItem->pszMountPoint,0,0,0); */
3363 /* if ( nRet != 0 ) */
3366 /* #ifdef DEBUG_OSL_FILE */
3367 /* perror("mount"); */
3371 pszTmp
= getenv("SAL_MOUNT_MOUNTPROG");
3374 pszMountProg
=pszTmp
;
3377 pszTmp
=getenv("SAL_MOUNT_SU_DO");
3385 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s %s",pszSuDo
,pszMountProg
,pItem
->pszDevice
,pItem
->pszMountPoint
);
3389 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszMountProg
,pItem
->pszMountPoint
);
3393 #ifdef DEBUG_OSL_FILE
3394 fprintf(stderr
,"executing '%s'\n",pszCmd
);
3397 nRet
= system(pszCmd
);
3399 #ifdef DEBUG_OSL_FILE
3400 fprintf(stderr
,"call returned '%i'\n",nRet
);
3401 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
3405 switch ( WEXITSTATUS(nRet
) )
3440 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
3443 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
3445 oslVolumeDeviceHandleImpl
* pItem
=0;
3447 sal_Char pszCmd
[PATH_MAX
];
3448 sal_Char
* pszTmp
= 0;
3449 sal_Char
* pszSuDo
= 0;
3450 sal_Char
* pszUmountProg
= "umount";
3454 #ifdef TRACE_OSL_FILE
3455 fprintf(stderr
,"In osl_unmountFloppy\n");
3458 pItem
= (oslVolumeDeviceHandleImpl
*) hFloppy
;
3462 #ifdef TRACE_OSL_FILE
3463 fprintf(stderr
,"Out osl_unmountFloppy [pItem==0]\n");
3465 return osl_File_E_INVAL
;
3468 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3470 #ifdef TRACE_OSL_FILE
3471 fprintf(stderr
,"Out osl_unmountFloppy [invalid handle]\n");
3473 return osl_File_E_INVAL
;
3476 /* mfe: we can't use the umount(2) system call!!! */
3477 /* even if we are root */
3478 /* since mtab is not updated!!! */
3479 /* but we need it to be updated */
3480 /* some "magic" must be done */
3482 /* nRet=umount(pItem->pszDevice); */
3483 /* if ( nRet != 0 ) */
3487 /* #ifdef DEBUG_OSL_FILE */
3488 /* perror("mount"); */
3493 pszTmp
= getenv("SAL_MOUNT_UMOUNTPROG");
3496 pszUmountProg
=pszTmp
;
3499 pszTmp
= getenv("SAL_MOUNT_SU_DO");
3507 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s %s",pszSuDo
,pszUmountProg
,pItem
->pszMountPoint
);
3511 snprintf(pszCmd
, sizeof(pszCmd
), "%s %s",pszUmountProg
,pItem
->pszMountPoint
);
3515 #ifdef DEBUG_OSL_FILE
3516 fprintf(stderr
,"executing '%s'\n",pszCmd
);
3519 nRet
= system(pszCmd
);
3521 #ifdef DEBUG_OSL_FILE
3522 fprintf(stderr
,"call returned '%i'\n",nRet
);
3523 fprintf(stderr
,"exit status is '%i'\n", WEXITSTATUS(nRet
));
3526 switch ( WEXITSTATUS(nRet
) )
3537 #ifdef TRACE_OSL_FILE
3538 fprintf(stderr
,"Out osl_unmountFloppy [ok]\n");
3541 return ((0 == nRet
) ? oslTranslateFileError(OSL_FET_SUCCESS
, nRet
) : oslTranslateFileError(OSL_FET_ERROR
, nRet
));
3543 /* return osl_File_E_None;*/
3546 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
3548 struct mntent
* pMountEnt
=0;
3549 sal_Char buffer
[PATH_MAX
];
3555 mntfile
= setmntent(MOUNTTAB
,"r");
3557 #ifdef TRACE_OSL_FILE
3558 fprintf(stderr
,"In osl_getFloppyMountEntry\n");
3561 memset(buffer
, 0, sizeof(buffer
));
3562 strncpy(buffer
, pszPath
, sizeof(buffer
) - 1);
3564 #ifdef DEBUG_OSL_FILE
3565 fprintf(stderr
,"Checking mount of %s\n",buffer
);
3572 #ifdef DEBUG_OSL_FILE
3575 #ifdef TRACE_OSL_FILE
3576 fprintf(stderr
,"Out osl_getFloppyMountEntry [mntfile]\n");
3581 pMountEnt
=getmntent(mntfile
);
3582 while ( pMountEnt
!= 0 )
3584 #ifdef DEBUG_OSL_FILE
3585 /* fprintf(stderr,"mnt_fsname : %s\n",pMountEnt->mnt_fsname); */
3586 /* fprintf(stderr,"mnt_dir : %s\n",pMountEnt->mnt_dir); */
3587 /* fprintf(stderr,"mnt_type : %s\n",pMountEnt->mnt_type);*/
3589 if ( strcmp(pMountEnt
->mnt_dir
,buffer
) == 0 &&
3590 strncmp(pMountEnt
->mnt_fsname
,"/dev/fd",strlen("/dev/fd")) == 0 )
3593 memset(pItem
->pszMountPoint
, 0, sizeof(pItem
->pszMountPoint
));
3594 strncpy(pItem
->pszMountPoint
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszMountPoint
) - 1);
3596 memset(pItem
->pszFilePath
, 0, sizeof(pItem
->pszFilePath
));
3597 strncpy(pItem
->pszFilePath
, pMountEnt
->mnt_dir
, sizeof(pItem
->pszFilePath
) - 1);
3599 memset(pItem
->pszDevice
, 0, sizeof(pItem
->pszDevice
));
3600 strncpy(pItem
->pszDevice
, pMountEnt
->mnt_fsname
, sizeof(pItem
->pszDevice
) - 1);
3603 #ifdef DEBUG_OSL_FILE
3604 fprintf(stderr
,"Mount Point found '%s'\n",pItem
->pszMountPoint
);
3606 #ifdef TRACE_OSL_FILE
3607 fprintf(stderr
,"Out osl_getFloppyMountEntry [found]\n");
3611 #ifdef DEBUG_OSL_FILE
3612 /* fprintf(stderr,"=================\n");*/
3614 pMountEnt
=getmntent(mntfile
);
3617 #ifdef TRACE_OSL_FILE
3618 fprintf(stderr
,"Out osl_getFloppyMountEntry [not found]\n");
3625 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
3627 sal_Char buffer
[PATH_MAX
];
3628 oslVolumeDeviceHandleImpl
* pItem
=0;
3633 #ifdef TRACE_OSL_FILE
3634 fprintf(stderr
,"In osl_isFloppyMounted\n");
3637 pItem
= osl_newVolumeDeviceHandleImpl ();
3639 return osl_File_E_NOMEM
;
3641 memset(buffer
, 0, sizeof(buffer
));
3642 strncpy(buffer
, pDevice
->pszMountPoint
, sizeof(buffer
) - 1);
3644 #ifdef DEBUG_OSL_FILE
3645 fprintf(stderr
,"Checking mount of %s\n",buffer
);
3648 bRet
= osl_getFloppyMountEntry(buffer
,pItem
);
3650 if ( bRet
== sal_False
)
3652 #ifdef TRACE_OSL_FILE
3653 fprintf(stderr
,"Out osl_isFloppyMounted [not mounted]\n");
3658 if (strcmp(pItem
->pszMountPoint
, pDevice
->pszMountPoint
) == 0 &&
3659 strcmp(pItem
->pszDevice
,pDevice
->pszDevice
) == 0)
3661 #ifdef TRACE_OSL_FILE
3662 fprintf(stderr
,"Out osl_isFloppyMounted [is mounted]\n");
3664 rtl_freeMemory(pItem
);
3668 #ifdef TRACE_OSL_FILE
3669 fprintf(stderr
,"Out osl_isFloppyMounted [may be EBUSY]\n");
3672 rtl_freeMemory(pItem
);
3678 /* NetBSD floppy functions have to be added here. Until we have done that,
3679 * we use the MACOSX definitions for nonexistent floppy.
3682 /******************************************************************************
3684 * MAC OS X FLOPPY FUNCTIONS
3686 *****************************************************************************/
3688 #if (defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
3689 static oslVolumeDeviceHandle
osl_isFloppyDrive(const sal_Char
* pszPath
)
3695 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
3696 static oslFileError
osl_mountFloppy(oslVolumeDeviceHandle hFloppy
)
3698 return osl_File_E_BUSY
;
3702 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
3703 static oslFileError
osl_unmountFloppy(oslVolumeDeviceHandle hFloppy
)
3705 return osl_File_E_BUSY
;
3709 #if ( defined(NETBSD) || defined(FREEBSD) )
3710 static sal_Bool
osl_getFloppyMountEntry(const sal_Char
* pszPath
, oslVolumeDeviceHandleImpl
* pItem
)
3714 #endif /* NETBSD || FREEBSD */
3716 #if ( defined(NETBSD) || defined(FREEBSD) )
3717 static sal_Bool
osl_isFloppyMounted(oslVolumeDeviceHandleImpl
* pDevice
)
3721 #endif /* NETBSD || FREEBSD */
3724 #ifdef DEBUG_OSL_FILE
3725 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl
* pItem
)
3729 fprintf(stderr
,"NULL Handle\n");
3732 if ( pItem
->ident
[0] != 'O' || pItem
->ident
[1] != 'V' || pItem
->ident
[2] != 'D' || pItem
->ident
[3] != 'H' )
3734 #ifdef TRACE_OSL_FILE
3735 fprintf(stderr
,"Invalid Handle]\n");
3741 fprintf(stderr
,"MountPoint : '%s'\n",pItem
->pszMountPoint
);
3742 fprintf(stderr
,"FilePath : '%s'\n",pItem
->pszFilePath
);
3743 fprintf(stderr
,"Device : '%s'\n",pItem
->pszDevice
);