update dev300-m57
[ooovba.git] / sal / osl / unx / file.cxx
blobf15f6bd37b5d512792f896c144d4f6323806c81f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: file.cxx,v $
10 * $Revision: 1.21 $
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 /************************************************************************
36 * ToDo
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 ***********************************************************************/
49 #include <algorithm>
50 #include <limits>
51 #include "system.h"
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"
61 #include <osl/time.h>
63 #ifndef _FILE_URL_H_
64 #include "file_url.h"
65 #endif
67 #include "file_path_helper.hxx"
68 #include "uunxapi.hxx"
71 #include <sys/mman.h>
73 #ifdef HAVE_STATFS_H
74 #undef HAVE_STATFS_H
75 #endif
77 #ifndef _STRING_H
78 #include <string.h>
79 #endif
81 #if defined(SOLARIS)
82 #include <sys/mnttab.h>
83 #include <sys/statvfs.h>
84 #define HAVE_STATFS_H
85 #include <sys/fs/ufs_quota.h>
86 static const sal_Char* MOUNTTAB="/etc/mnttab";
88 #elif defined(LINUX)
89 #include <mntent.h>
90 #include <sys/vfs.h>
91 #define HAVE_STATFS_H
92 #include <sys/quota.h>
93 #include <ctype.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>
101 #include <ctype.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"; */
107 #elif defined(IRIX)
108 #include <mntent.h>
109 #include <sys/mount.h>
110 #include <sys/statvfs.h>
111 #define HAVE_STATFS_H
112 #include <sys/quota.h>
113 #include <ctype.h>
114 static const sal_Char* MOUNTTAB="/etc/mtab";
116 #elif defined(MACOSX)
117 #include <ufs/ufs/quota.h>
118 #include <ctype.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>
130 #undef TimeValue
132 #endif
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;
144 return pItemObject;
147 void oslDirectoryItemImpl_Destroy( oslDirectoryItemImpl* pItem )
149 if( pItem->ustrFilePath ) {
150 rtl_uString_release( pItem->ustrFilePath );
151 pItem->ustrFilePath = NULL;
153 free( pItem );
156 void oslDirectoryItemImpl_acquire( oslDirectoryItemImpl* pItem )
158 pItem->RefCount ++;
161 void oslDirectoryItemImpl_release( oslDirectoryItemImpl* pItem )
163 pItem->RefCount --;
165 if( pItem->RefCount <= 0 )
166 oslDirectoryItemImpl_Destroy( pItem );
168 #endif
170 #if OSL_DEBUG_LEVEL > 1
172 extern void debug_ustring(rtl_uString*);
174 #endif
177 #ifdef DEBUG_OSL_FILE
178 # define PERROR( a, b ) perror( a ); fprintf( stderr, b )
179 #else
180 # define PERROR( a, b )
181 #endif
183 extern "C" oslFileHandle osl_createFileHandleFromFD( int fd );
185 /******************************************************************************
187 * Data Type Definition
189 ******************************************************************************/
191 #if 0
192 /* FIXME: reintroducing this may save some extra bytes per Item */
193 typedef struct
195 rtl_uString* ustrFileName; /* holds native file name */
196 rtl_uString* ustrDirPath; /* holds native dir path */
197 sal_uInt32 RefCount;
198 } oslDirectoryItemImpl;
199 #endif
201 typedef struct
203 rtl_uString* ustrPath; /* holds native directory path */
204 DIR* pDirStruct;
205 } oslDirectoryImpl;
208 typedef struct
210 rtl_uString* ustrFilePath; /* holds native file path */
211 int fd;
212 sal_Bool bLocked;
213 } oslFileHandleImpl;
216 typedef struct _oslVolumeDeviceHandleImpl
218 sal_Char pszMountPoint[PATH_MAX];
219 sal_Char pszFilePath[PATH_MAX];
220 sal_Char pszDevice[PATH_MAX];
221 sal_Char ident[4];
222 sal_uInt32 RefCount;
223 } oslVolumeDeviceHandleImpl;
226 /******************************************************************************
228 * static members
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);
285 #if defined(SOLARIS)
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);
289 #endif
291 #if defined(LINUX)
292 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
293 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
294 #endif
297 #if defined(IRIX)
298 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice);
299 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem);
300 #endif
302 #ifdef DEBUG_OSL_FILE
303 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* hFloppy);
304 #endif
306 #ifdef MACOSX
308 /*******************************************************************
309 * adjustLockFlags
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)
321 struct statfs s;
323 if( 0 <= statfs( path, &s ) )
325 if( 0 == strncmp("afpfs", s.f_fstypename, 5) )
327 flags &= ~O_EXLOCK;
328 flags |= O_SHLOCK;
330 else
332 /* Needed flags to allow opening a webdav file */
333 flags &= ~( O_EXLOCK | O_SHLOCK );
337 return flags;
340 #endif
343 /*******************************************************************
344 * osl_openDirectory
345 ******************************************************************/
347 oslFileError SAL_CALL osl_openDirectory(rtl_uString* ustrDirectoryURL, oslDirectory* pDirectory)
349 rtl_uString* ustrSystemPath = NULL;
350 oslFileError eRet;
352 char path[PATH_MAX];
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 )
364 return eRet;
366 osl_systemPathRemoveSeparator(ustrSystemPath);
368 /* convert unicode path to text */
369 if ( UnicodeToText( path, PATH_MAX, ustrSystemPath->buffer, ustrSystemPath->length )
370 #ifdef MACOSX
371 && macxp_resolveAlias( path, PATH_MAX ) == 0
372 #endif /* MACOSX */
375 /* open directory */
376 DIR *pdir = opendir( path );
378 if( pdir )
380 /* create and initialize impl structure */
381 oslDirectoryImpl* pDirImpl = (oslDirectoryImpl*) rtl_allocateMemory( sizeof(oslDirectoryImpl) );
383 if( pDirImpl )
385 pDirImpl->pDirStruct = pdir;
386 pDirImpl->ustrPath = ustrSystemPath;
388 *pDirectory = (oslDirectory) pDirImpl;
389 return osl_File_E_None;
391 else
393 errno = ENOMEM;
394 closedir( pdir );
397 else
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 );
434 return err;
437 /**********************************************
438 * osl_readdir_impl_
440 * readdir wrapper, filters out "." and ".."
441 * on request
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, ".."))))
452 continue;
453 else
454 break;
457 return pdirent;
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);
472 OSL_ASSERT(pItem);
474 if ((NULL == Directory) || (NULL == pItem))
475 return osl_File_E_INVAL;
477 pEntry = osl_readdir_impl_(pDirImpl->pDirStruct, sal_True);
479 if (NULL == pEntry)
480 return osl_File_E_NOENT;
483 #if defined(MACOSX)
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 );
491 CFRelease( strRef );
492 rtl_string2UString( &ustrFileName, composed_name, strlen( composed_name),
493 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS );
495 #else // not MACOSX
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);
501 #endif
503 osl_systemPathMakeAbsolutePath(pDirImpl->ustrPath, ustrFileName, &ustrFilePath);
504 rtl_uString_release( ustrFileName );
506 #ifdef _DIRENT_HAVE_D_TYPE
507 if(*pItem)
508 oslDirectoryItemImpl_release( ( oslDirectoryItemImpl* )( *pItem ) );
510 *pItem = (oslDirectoryItem) oslDirectoryItemImpl_CreateNew( ustrFilePath, true, pEntry->d_type );
511 #else
512 /* use path as directory item */
513 *pItem = (oslDirectoryItem) ustrFilePath;
514 #endif
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);
529 OSL_ASSERT(pItem);
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)
537 return 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 );
545 #else
546 *pItem = (oslDirectoryItem)ustrSystemPath;
547 #endif
548 osl_error = osl_File_E_None;
550 else
552 osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
553 rtl_uString_release(ustrSystemPath);
555 return osl_error;
559 /****************************************************************************/
560 /* osl_acquireDirectoryItem */
561 /****************************************************************************/
563 oslFileError osl_acquireDirectoryItem( oslDirectoryItem Item )
565 #ifdef _DIRENT_HAVE_D_TYPE
566 oslDirectoryItemImpl* pImpl = (oslDirectoryItemImpl*) Item;
567 #else
568 rtl_uString* ustrFilePath = (rtl_uString *) Item;
569 #endif
571 OSL_ASSERT( Item );
573 #ifdef _DIRENT_HAVE_D_TYPE
574 if( pImpl )
575 oslDirectoryItemImpl_acquire( pImpl );
576 #else
577 if( ustrFilePath )
578 rtl_uString_acquire( ustrFilePath );
579 #endif
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;
592 #else
593 rtl_uString* ustrFilePath = (rtl_uString *) Item;
594 #endif
596 OSL_ASSERT( Item );
598 #ifdef _DIRENT_HAVE_D_TYPE
599 if( pImpl )
600 oslDirectoryItemImpl_release( pImpl );
601 #else
602 if( ustrFilePath )
603 rtl_uString_release( ustrFilePath );
604 #endif
606 return osl_File_E_None;
609 /****************************************************************************
610 * osl_createFileHandleFromFD
611 ***************************************************************************/
613 oslFileHandle osl_createFileHandleFromFD( int fd )
615 oslFileHandleImpl* pHandleImpl = NULL;
617 if ( fd >= 0 )
619 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
621 if( pHandleImpl )
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 /****************************************************************************
637 * osl_openFile
638 ***************************************************************************/
640 #ifdef HAVE_O_EXLOCK
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 )
643 #else
644 #define OPEN_WRITE_FLAGS ( O_RDWR )
645 #define OPEN_CREATE_FLAGS ( O_CREAT | O_EXCL | O_RDWR )
646 #endif
648 oslFileError osl_openFile( rtl_uString* ustrFileURL, oslFileHandle* pHandle, sal_uInt32 uFlags )
650 oslFileHandleImpl* pHandleImpl = NULL;
651 oslFileError eRet;
652 rtl_uString* ustrFilePath = NULL;
654 char buffer[PATH_MAX];
655 int fd;
656 int mode = S_IRUSR | S_IRGRP | S_IROTH;
657 int flags = O_RDONLY;
659 struct flock aflock;
661 /* locking the complete file */
662 aflock.l_type = 0;
663 aflock.l_whence = SEEK_SET;
664 aflock.l_start = 0;
665 aflock.l_len = 0;
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 )
677 return eRet;
679 osl_systemPathRemoveSeparator(ustrFilePath);
681 /* convert unicode path to text */
682 if( UnicodeToText( buffer, PATH_MAX, ustrFilePath->buffer, ustrFilePath->length )
683 #ifdef MACOSX
684 && macxp_resolveAlias( buffer, PATH_MAX ) == 0
685 #endif /* MACOSX */
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 )
708 * set flags and mode
711 if ( uFlags & osl_File_OpenFlag_Write )
713 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
714 flags = OPEN_WRITE_FLAGS;
715 #ifdef MACOSX
716 flags = adjustLockFlags(buffer, flags);
717 #endif
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;
725 #ifdef MACOSX
726 flags = adjustLockFlags(buffer, flags);
727 #endif
730 sal_Bool bNeedsLock = ( ( uFlags & osl_File_OpenFlag_NoLock ) == 0 );
731 if ( !bNeedsLock )
733 #ifdef MACOSX
734 flags &= ~O_EXLOCK;
735 flags &= ~O_SHLOCK;
736 #endif
739 /* open the file */
740 fd = open( buffer, flags, mode );
741 if ( fd >= 0 )
743 sal_Bool bLocked = sal_False;
744 if( bNeedsLock )
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");
756 #else
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) )
765 close(fd);
766 return oslTranslateFileError(OSL_FET_ERROR, errno);
768 #endif
769 if( NULL == pFileLockEnvVar )
770 aflock.l_type = 0;
772 /* lock the file if flock.l_type is set */
773 #ifdef MACOSX
774 bLocked = ( F_WRLCK != aflock.l_type );
775 if (!bLocked)
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 );
781 #else /* MACOSX */
782 bLocked = ( F_WRLCK != aflock.l_type || -1 != fcntl( fd, F_SETLK, &aflock ) );
783 #endif /* MACOSX */
787 if ( !bNeedsLock || bLocked )
789 /* allocate memory for impl structure */
790 pHandleImpl = (oslFileHandleImpl*) rtl_allocateMemory( sizeof(oslFileHandleImpl) );
791 if( pHandleImpl )
793 pHandleImpl->ustrFilePath = ustrFilePath;
794 pHandleImpl->fd = fd;
795 pHandleImpl->bLocked = bLocked;
797 *pHandle = (oslFileHandle) pHandleImpl;
799 return osl_File_E_None;
801 else
803 errno = ENOMEM;
807 close( fd );
810 PERROR( "osl_openFile", buffer );
811 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
814 else
815 eRet = osl_File_E_INVAL;
817 rtl_uString_release( ustrFilePath );
818 return eRet;
821 /****************************************************************************/
822 /* osl_closeFile */
823 /****************************************************************************/
825 oslFileError osl_closeFile( oslFileHandle Handle )
827 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl *) Handle;
828 oslFileError eRet = osl_File_E_INVAL;
830 OSL_ASSERT( Handle );
832 if( pHandleImpl )
834 rtl_uString_release( pHandleImpl->ustrFilePath );
836 /* release file lock if locking is enabled */
837 if( pFileLockEnvVar )
839 struct flock aflock;
841 aflock.l_type = F_UNLCK;
842 aflock.l_whence = SEEK_SET;
843 aflock.l_start = 0;
844 aflock.l_len = 0;
846 if ( pHandleImpl->bLocked )
848 /* FIXME: check if file is really locked ? */
850 /* release the file share lock on this file */
851 #ifdef MACOSX
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 )
854 #else /* MACOSX */
855 if( -1 == fcntl( pHandleImpl->fd, F_SETLK, &aflock ) )
856 #endif /* MACOSX */
858 PERROR( "osl_closeFile", "unlock failed" );
863 if( 0 > close( pHandleImpl->fd ) )
865 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
867 else
868 eRet = osl_File_E_None;
870 rtl_freeMemory( pHandleImpl );
873 return eRet;
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;
885 if ( pHandleImpl)
887 long curPos = lseek( pHandleImpl->fd, 0, SEEK_CUR );
889 if ( curPos >= 0 )
891 long endPos = lseek( pHandleImpl->fd, 0, SEEK_END );
893 if ( endPos >= 0 )
895 *pIsEOF = ( curPos == endPos );
896 curPos = lseek( pHandleImpl->fd, curPos, SEEK_SET );
898 if ( curPos >= 0 )
899 eRet = osl_File_E_None;
900 else
901 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
903 else
904 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
906 else
907 eRet = oslTranslateFileError(OSL_FET_ERROR, errno );
910 return eRet;
914 /****************************************************************************/
915 /* osl_moveFile */
916 /****************************************************************************/
918 oslFileError osl_moveFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
920 char srcPath[PATH_MAX];
921 char destPath[PATH_MAX];
922 oslFileError eRet;
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 )
930 return eRet;
932 /* convert destination url to system path */
933 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
934 if( eRet != osl_File_E_None )
935 return eRet;
937 #ifdef MACOSX
938 if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
939 return oslTranslateFileError( OSL_FET_ERROR, errno );
940 #endif/* MACOSX */
942 return oslDoMoveFile( srcPath, destPath );
945 /****************************************************************************/
946 /* osl_copyFile */
947 /****************************************************************************/
949 oslFileError osl_copyFile( rtl_uString* ustrFileURL, rtl_uString* ustrDestURL )
951 char srcPath[PATH_MAX];
952 char destPath[PATH_MAX];
953 oslFileError eRet;
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 )
961 return eRet;
963 /* convert destination url to system path */
964 eRet = FileURLToPath( destPath, PATH_MAX, ustrDestURL );
965 if( eRet != osl_File_E_None )
966 return eRet;
968 #ifdef MACOSX
969 if ( macxp_resolveAlias( srcPath, PATH_MAX ) != 0 || macxp_resolveAlias( destPath, PATH_MAX ) != 0 )
970 return oslTranslateFileError( OSL_FET_ERROR, errno );
971 #endif/* MACOSX */
973 return osl_psz_copyFile( srcPath, destPath );
976 /****************************************************************************/
977 /* osl_removeFile */
978 /****************************************************************************/
980 oslFileError osl_removeFile( rtl_uString* ustrFileURL )
982 char path[PATH_MAX];
983 oslFileError eRet;
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 )
990 return eRet;
992 #ifdef MACOSX
993 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
994 return oslTranslateFileError( OSL_FET_ERROR, errno );
995 #endif/* MACOSX */
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];
1007 oslFileError eRet;
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 )
1015 return eRet;
1017 #ifdef MACOSX
1018 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
1019 return oslTranslateFileError( OSL_FET_ERROR, errno );
1020 #endif/* MACOSX */
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];
1032 oslFileError eRet;
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 )
1039 return eRet;
1041 #ifdef MACOSX
1042 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
1043 return oslTranslateFileError( OSL_FET_ERROR, errno );
1044 #endif/* MACOSX */
1046 return osl_psz_createDirectory( path );
1049 /****************************************************************************/
1050 /* osl_removeDirectory */
1051 /****************************************************************************/
1053 oslFileError osl_removeDirectory( rtl_uString* ustrDirectoryURL )
1055 char path[PATH_MAX];
1056 oslFileError eRet;
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 )
1063 return eRet;
1065 #ifdef MACOSX
1066 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
1067 return oslTranslateFileError( OSL_FET_ERROR, errno );
1068 #endif/* MACOSX */
1070 return osl_psz_removeDirectory( path );
1073 //#############################################
1074 int path_make_parent(sal_Unicode* path)
1076 int i = rtl_ustr_lastIndexOfChar(path, '/');
1078 if (i > 0)
1080 *(path + i) = 0;
1081 return i;
1083 else
1084 return 0;
1087 //#############################################
1088 int create_dir_with_callback(
1089 sal_Unicode* directory_path,
1090 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1091 void* pData)
1093 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
1095 if (osl::mkdir(directory_path, mode) == 0)
1097 if (aDirectoryCreationCallbackFunc)
1099 rtl::OUString url;
1100 osl::FileBase::getFileURLFromSystemPath(directory_path, url);
1101 aDirectoryCreationCallbackFunc(pData, url.pData);
1103 return 0;
1105 return errno;
1108 //#############################################
1109 oslFileError create_dir_recursively_(
1110 sal_Unicode* dir_path,
1111 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc,
1112 void* pData)
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
1129 // return before
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)
1136 return 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,
1147 void* pData)
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)
1157 return osl_error;
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];
1186 oslFileError eRet;
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 )
1193 return eRet;
1195 #ifdef MACOSX
1196 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
1197 return oslTranslateFileError( OSL_FET_ERROR, errno );
1198 #endif/* MACOSX */
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];
1211 oslFileError eRet;
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 )
1218 return eRet;
1220 #ifdef MACOSX
1221 if ( macxp_resolveAlias( path, PATH_MAX ) != 0 )
1222 return oslTranslateFileError( OSL_FET_ERROR, errno );
1223 #endif/* MACOSX */
1225 return osl_psz_setFileTime( path, pCreationTime, pLastAccessTime, pLastWriteTime );
1228 /******************************************************************************
1230 * Exported Module Functions
1231 * (independent of C or Unicode Strings)
1233 *****************************************************************************/
1235 /*******************************************
1236 osl_mapFile
1237 ********************************************/
1238 oslFileError
1239 SAL_CALL osl_mapFile (
1240 oslFileHandle Handle,
1241 void** ppAddr,
1242 sal_uInt64 uLength,
1243 sal_uInt64 uOffset,
1244 sal_uInt32 uFlags
1247 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
1249 if ((0 == pHandleImpl) || (-1 == pHandleImpl->fd) || (0 == ppAddr))
1250 return osl_File_E_INVAL;
1251 *ppAddr = 0;
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);
1266 *ppAddr = p;
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();
1273 #else /* POSIX */
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)
1288 c ^= pData[0];
1289 pData += nPageSize;
1290 nSize -= nPageSize;
1292 if (nSize > 0)
1294 c^= pData[0];
1295 pData += nSize;
1296 nSize -= nSize;
1300 return osl_File_E_None;
1303 /*******************************************
1304 osl_unmapFile
1305 ********************************************/
1306 oslFileError
1307 SAL_CALL osl_unmapFile (void* pAddr, sal_uInt64 uLength)
1309 if (0 == pAddr)
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 /*******************************************
1324 osl_readFile
1325 ********************************************/
1327 oslFileError osl_readFile(oslFileHandle Handle, void* pBuffer, sal_uInt64 uBytesRequested, sal_uInt64* pBytesRead)
1329 ssize_t nBytes = 0;
1330 oslFileHandleImpl* pHandleImpl = (oslFileHandleImpl*)Handle;
1332 if ((0 == pHandleImpl) || (pHandleImpl->fd < 0) || (0 == pBuffer) || (0 == pBytesRead))
1333 return osl_File_E_INVAL;
1335 nBytes = read(
1336 pHandleImpl->fd, pBuffer,
1337 ((uBytesRequested
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())));
1342 if (-1 == nBytes)
1343 return oslTranslateFileError(OSL_FET_ERROR, errno);
1345 *pBytesRead = nBytes;
1346 return osl_File_E_None;
1349 /*******************************************
1350 osl_writeFile
1351 ********************************************/
1353 oslFileError osl_writeFile(oslFileHandle Handle, const void* pBuffer, sal_uInt64 uBytesToWrite, sal_uInt64* pBytesWritten)
1355 ssize_t nBytes = 0;
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;
1370 nBytes = write(
1371 pHandleImpl->fd, pBuffer,
1372 ((uBytesToWrite
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())));
1377 if (-1 == nBytes)
1378 return oslTranslateFileError(OSL_FET_ERROR, errno);
1380 *pBytesWritten = nBytes;
1381 return osl_File_E_None;
1384 /*******************************************
1385 osl_readFileAt
1386 ********************************************/
1387 oslFileError
1388 SAL_CALL osl_readFileAt (
1389 oslFileHandle Handle,
1390 sal_uInt64 uOffset,
1391 void* pBuffer,
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.
1422 nBytes = 0;
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 */
1434 if (-1 == nBytes)
1435 return oslTranslateFileError(OSL_FET_ERROR, errno);
1437 *pBytesRead = nBytes;
1438 return osl_File_E_None;
1441 /*******************************************
1442 osl_writeFileAt
1443 ********************************************/
1444 oslFileError
1445 SAL_CALL osl_writeFileAt (
1446 oslFileHandle Handle,
1447 sal_uInt64 uOffset,
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 */
1480 if (-1 == nBytes)
1481 return oslTranslateFileError(OSL_FET_ERROR, errno);
1483 *pBytesWritten = nBytes;
1484 return osl_File_E_None;
1487 /*******************************************
1488 osl_setFilePos
1489 ********************************************/
1491 oslFileError osl_setFilePos( oslFileHandle Handle, sal_uInt32 uHow, sal_Int64 uPos )
1493 oslFileHandleImpl* pHandleImpl=0;
1494 int nRet=0;
1495 off_t nOffset=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;
1516 switch(uHow)
1518 case osl_Pos_Absolut:
1519 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_SET);
1520 break;
1522 case osl_Pos_Current:
1523 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_CUR);
1524 break;
1526 case osl_Pos_End:
1527 nOffset = lseek(pHandleImpl->fd,nOffset,SEEK_END);
1528 break;
1530 default:
1531 return osl_File_E_INVAL;
1534 if ( nOffset < 0 )
1536 nRet=errno;
1537 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1540 return osl_File_E_None;
1543 /************************************************
1544 * osl_getFilePos
1545 ***********************************************/
1547 oslFileError osl_getFilePos( oslFileHandle Handle, sal_uInt64* pPos )
1549 oslFileHandleImpl* pHandleImpl=0;
1550 off_t nOffset=0;
1551 int nRet=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);
1566 if (nOffset < 0)
1568 nRet =errno;
1570 /* *pPos =0; */
1572 return oslTranslateFileError(OSL_FET_ERROR, nRet);
1575 *pPos=nOffset;
1577 return osl_File_E_None;
1580 /****************************************************************************
1581 * osl_getFileSize
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 /************************************************
1599 * osl_setFileSize
1600 ***********************************************/
1602 oslFileError osl_setFileSize( oslFileHandle Handle, sal_uInt64 uSize )
1604 oslFileHandleImpl* pHandleImpl=0;
1605 off_t nOffset=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;
1629 struct stat aStat;
1630 off_t nCurPos;
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");
1640 return (result);
1642 if ((0 <= nOffset) && (nOffset <= aStat.st_size))
1644 /* Failure upon 'shrink'. Return original result */
1645 return (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");
1653 return (result);
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");
1660 return (result);
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 */
1672 return (result);
1675 /* Success. Restore saved position */
1676 if (lseek (pHandleImpl->fd, (off_t)nCurPos, SEEK_SET) < 0)
1678 PERROR("ftruncate: lseek", "Out osl_setFileSize [error]");
1679 return (result);
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 */
1722 #if defined(LINUX)
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))
1735 #endif /* LINUX */
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;
1769 if (!pInfo)
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);
1780 return (result);
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);
1822 if (getuid() == 0)
1823 pInfo->uFreeSpace *= (sal_uInt64)(sfs.f_bfree);
1824 else
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);
1843 if (nLen > 0)
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);
1854 if (nLen > 0)
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)
1865 rtl_string2UString(
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)
1910 nNewMode|=S_IWUSR;
1912 if (uAttributes & osl_File_Attribute_OwnExe)
1913 nNewMode|=S_IXUSR;
1915 if (uAttributes & osl_File_Attribute_GrpRead)
1916 nNewMode|=S_IRGRP;
1918 if (uAttributes & osl_File_Attribute_GrpWrite)
1919 nNewMode|=S_IWGRP;
1921 if (uAttributes & osl_File_Attribute_GrpExe)
1922 nNewMode|=S_IXGRP;
1924 if (uAttributes & osl_File_Attribute_OthRead)
1925 nNewMode|=S_IROTH;
1927 if (uAttributes & osl_File_Attribute_OthWrite)
1928 nNewMode|=S_IWOTH;
1930 if (uAttributes & osl_File_Attribute_OthExe)
1931 nNewMode|=S_IXOTH;
1933 if (chmod(pszFilePath, nNewMode) < 0)
1934 osl_error = oslTranslateFileError(OSL_FET_ERROR, errno);
1936 return osl_error;
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 )
1948 int nRet=0;
1949 struct utimbuf aTimeBuffer;
1950 struct stat aFileStat;
1951 #ifdef DEBUG_OSL_FILE
1952 struct tm* pTM=0;
1953 #endif
1955 nRet = lstat(pszFilePath,&aFileStat);
1957 if ( nRet < 0 )
1959 nRet=errno;
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));
1976 #endif
1978 if ( pLastAccessTime != 0 )
1980 aTimeBuffer.actime=pLastAccessTime->Seconds;
1982 else
1984 aTimeBuffer.actime=aFileStat.st_atime;
1987 if ( pLastWriteTime != 0 )
1989 aTimeBuffer.modtime=pLastWriteTime->Seconds;
1991 else
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));
2011 #endif
2013 nRet=utime(pszFilePath,&aTimeBuffer);
2014 if ( nRet < 0 )
2016 nRet=errno;
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 )
2030 int nRet=0;
2031 struct stat aStat;
2033 nRet = lstat(pszPath,&aStat);
2034 if ( nRet < 0 )
2036 nRet=errno;
2037 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2040 if ( S_ISDIR(aStat.st_mode) )
2042 return osl_File_E_ISDIR;
2045 nRet = unlink(pszPath);
2046 if ( nRet < 0 )
2048 nRet=errno;
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 )
2061 int nRet=0;
2062 int mode = S_IRWXU | S_IRWXG | S_IRWXO;
2064 nRet = mkdir(pszPath,mode);
2066 if ( nRet < 0 )
2068 nRet=errno;
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 )
2081 int nRet=0;
2083 nRet = rmdir(pszPath);
2085 if ( nRet < 0 )
2087 nRet=errno;
2088 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2091 return osl_File_E_None;
2094 /*****************************************
2095 * oslDoMoveFile
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 )
2105 return tErr;
2108 if ( tErr != osl_File_E_XDEV )
2110 return tErr;
2113 tErr=osl_psz_copyFile(pszPath,pszDestPath);
2115 if ( tErr != osl_File_E_None )
2117 oslFileError tErrRemove;
2118 tErrRemove=osl_psz_removeFile(pszDestPath);
2119 return tErr;
2122 tErr=osl_psz_removeFile(pszPath);
2124 return tErr;
2127 /*****************************************
2128 * osl_psz_moveFile
2129 ****************************************/
2131 static oslFileError osl_psz_moveFile(const sal_Char* pszPath, const sal_Char* pszDestPath)
2134 int nRet = 0;
2136 nRet = rename(pszPath,pszDestPath);
2138 if ( nRet < 0 )
2140 nRet=errno;
2141 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2144 return osl_File_E_None;
2147 /*****************************************
2148 * osl_psz_copyFile
2149 ****************************************/
2151 static oslFileError osl_psz_copyFile( const sal_Char* pszPath, const sal_Char* pszDestPath )
2153 time_t nAcTime=0;
2154 time_t nModTime=0;
2155 uid_t nUID=0;
2156 gid_t nGID=0;
2157 int nRet=0;
2158 mode_t nMode=0;
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);
2167 if ( nRet < 0 )
2169 nRet=errno;
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);
2187 if ( nRet < 0 )
2189 nRet=errno;
2191 if ( nRet == ENOENT )
2193 DestFileExists=0;
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;
2203 else
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 )
2212 return tErr;
2216 * mfe: ignore return code
2217 * since only the success of the copy is
2218 * important
2220 oslChangeFileModes(pszDestPath,nMode,nAcTime,nModTime,nUID,nGID);
2222 return tErr;
2226 /******************************************************************************
2228 * Utility Functions
2230 *****************************************************************************/
2232 /*****************************************
2233 * oslDoCopy
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)
2240 int nRet=0;
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);
2275 else
2277 /* mfe: what to do here? */
2278 nRet=ENOSYS;
2281 if ( nRet > 0 && DestFileExists == 1 )
2283 unlink(pszDestFileName);
2284 rename(pszTmpDestFile,pszDestFileName);
2287 if ( nRet > 0 )
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)
2306 int nRet=0;
2307 struct utimbuf aTimeBuffer;
2309 nRet = chmod(pszFileName,nMode);
2310 if ( nRet < 0 )
2312 nRet=errno;
2313 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2316 aTimeBuffer.actime=nAcTime;
2317 aTimeBuffer.modtime=nModTime;
2318 nRet=utime(pszFileName,&aTimeBuffer);
2319 if ( nRet < 0 )
2321 nRet=errno;
2322 return oslTranslateFileError(OSL_FET_ERROR, nRet);
2325 if ( nUID != getuid() )
2327 nUID=getuid();
2330 nRet=chown(pszFileName,nUID,nGID);
2331 if ( nRet < 0 )
2333 nRet=errno;
2335 /* mfe: do not return an error here! */
2336 /* return oslTranslateFileError(nRet);*/
2339 return osl_File_E_None;
2342 /*****************************************
2343 * oslDoCopyLink
2344 ****************************************/
2346 static int oslDoCopyLink(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName)
2348 int nRet=0;
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);
2358 if ( nRet < 0 )
2360 nRet=errno;
2361 return nRet;
2363 else
2364 pszLinkContent[ nRet ] = 0;
2366 nRet = symlink(pszLinkContent,pszDestFileName);
2368 if ( nRet < 0 )
2370 nRet=errno;
2371 return nRet;
2374 return 0;
2377 /*****************************************
2378 * oslDoCopyFile
2379 ****************************************/
2381 static int oslDoCopyFile(const sal_Char* pszSourceFileName, const sal_Char* pszDestFileName, size_t nSourceSize, mode_t mode)
2383 int SourceFileFD=0;
2384 int DestFileFD=0;
2385 int nRet=0;
2386 void* pSourceFile=0;
2388 SourceFileFD=open(pszSourceFileName,O_RDONLY);
2389 if ( SourceFileFD < 0 )
2391 nRet=errno;
2392 return nRet;
2395 DestFileFD=open(pszDestFileName, O_WRONLY | O_CREAT, mode);
2397 if ( DestFileFD < 0 )
2399 nRet=errno;
2400 close(SourceFileFD);
2401 return nRet;
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);
2409 close(DestFileFD);
2410 return 0;
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 */
2421 nRet = errno;
2422 close(SourceFileFD);
2423 close(DestFileFD);
2425 return nRet;
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)))
2436 if (nRet < 0)
2437 nRet = errno;
2438 else
2439 nRet = ENOSPC;
2441 close(SourceFileFD);
2442 close(DestFileFD);
2443 munmap((char*)pSourceFile,nSourceSize);
2444 return nRet;
2447 nRet = munmap((char*)pSourceFile,nSourceSize);
2448 if ( nRet < 0 )
2450 nRet=errno;
2451 close(SourceFileFD);
2452 close(DestFileFD);
2453 return nRet;
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)
2462 return errno;
2463 else
2464 return 0;
2467 /*****************************************
2468 * oslMakeUStrFromPsz
2469 ****************************************/
2471 static rtl_uString* oslMakeUStrFromPsz(const sal_Char* pszStr, rtl_uString** ustrValid)
2473 rtl_string2UString(
2474 ustrValid,
2475 pszStr,
2476 rtl_str_getLength( pszStr ),
2477 osl_getThreadTextEncoding(),
2478 OUSTRING_TO_OSTRING_CVTFLAGS );
2479 OSL_ASSERT(*ustrValid != 0);
2481 return *ustrValid;
2484 /*****************************************************************************
2485 * UnicodeToText
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;
2493 sal_uInt32 nInfo;
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,
2500 buffer, bufLen,
2501 OUSTRING_TO_OSTRING_CVTFLAGS | RTL_UNICODETOTEXT_FLAGS_FLUSH,
2502 &nInfo, &nSrcChars );
2504 rtl_destroyUnicodeToTextConverter( hConverter );
2506 if( nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL )
2508 errno = EOVERFLOW;
2509 return 0;
2512 /* ensure trailing '\0' */
2513 buffer[nDestBytes] = '\0';
2515 return nDestBytes;
2518 /*****************************************************************************
2519 TextToUnicode
2521 @param text
2522 The text to convert.
2524 @param text_buffer_size
2525 The number of characters.
2527 @param unic_text
2528 The unicode buffer.
2530 @param unic_text_buffer_size
2531 The size in characters of the unicode buffer.
2533 ****************************************************************************/
2535 int TextToUnicode(
2536 const char* text,
2537 size_t text_buffer_size,
2538 sal_Unicode* unic_text,
2539 sal_Int32 unic_text_buffer_size)
2541 rtl_TextToUnicodeConverter hConverter;
2542 sal_uInt32 nInfo;
2543 sal_Size nSrcChars;
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)
2560 errno = EOVERFLOW;
2561 return 0;
2564 /* ensure trailing '\0' */
2565 unic_text[nDestBytes] = '\0';
2567 return nDestBytes;
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 */
2589 if ( tErr )
2591 sal_Char *pszHomeDir = getenv("HOME");
2593 if ( pszHomeDir && strlen( pszHomeDir ) && 0 == chdir( pszHomeDir ) )
2595 /* try again */
2597 tErr = osl_unmountFloppy(Handle);
2599 OSL_ENSURE( tErr, "osl_unmountvolumeDevice: CWD was set to volume mount point" );
2603 return tErr;
2606 /*****************************************
2607 * osl_automountVolumeDevice
2608 ****************************************/
2610 oslFileError osl_automountVolumeDevice( oslVolumeDeviceHandle Handle )
2612 oslFileError tErr = osl_File_E_NOSYS;
2614 tErr = osl_mountFloppy(Handle);
2616 return tErr;
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];
2628 Buffer[0] = '\0';
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);
2643 #endif
2645 snprintf(Buffer, sizeof(Buffer), "file://%s", pItem->pszMountPoint);
2647 #ifdef DEBUG_OSL_FILE
2648 fprintf(stderr,"Mount Point is: '%s'\n",Buffer);
2649 #endif
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;
2664 if ( pItem == 0 )
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;
2674 ++pItem->RefCount;
2676 return osl_File_E_None;
2679 /*****************************************
2680 * osl_releaseVolumeDeviceHandle
2681 ****************************************/
2683 oslFileError osl_releaseVolumeDeviceHandle( oslVolumeDeviceHandle Handle )
2685 oslVolumeDeviceHandleImpl* pItem =(oslVolumeDeviceHandleImpl*) Handle;
2687 if ( pItem == 0 )
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;
2697 --pItem->RefCount;
2699 if ( pItem->RefCount == 0 )
2701 rtl_freeMemory(pItem);
2704 return osl_File_E_None;
2707 #ifndef MACOSX
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;
2730 return pHandle;
2733 /*****************************************
2734 * osl_freeVolumeDeviceHandleImpl
2735 ****************************************/
2737 static void osl_freeVolumeDeviceHandleImpl (oslVolumeDeviceHandleImpl* pHandle)
2739 if (pHandle != NULL)
2740 rtl_freeMemory (pHandle);
2742 #endif
2744 /******************************************************************************
2746 * SOLARIS FLOPPY FUNCTIONS
2748 *****************************************************************************/
2750 #if defined(SOLARIS)
2751 /* compare a given devicename with the typical device names on a Solaris box */
2752 static sal_Bool
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"
2761 int i;
2762 for (i = 0; i < (sizeof(pFloppyDevice)/sizeof(pFloppyDevice[0])); i++)
2764 if (strncmp(pDeviceName, pFloppyDevice[i], strlen(pFloppyDevice[i])) == 0)
2765 return sal_True;
2767 return sal_False;
2770 /* compare two directories whether the first may be a parent of the second. this
2771 * does not realpath() resolving */
2772 static sal_Bool
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)
2784 FILE* pMountTab;
2785 struct mnttab aMountEnt;
2786 oslVolumeDeviceHandleImpl* pHandle;
2788 if ((pHandle = osl_newVolumeDeviceHandleImpl()) == NULL)
2790 return NULL;
2792 if (realpath(pszPath, pHandle->pszFilePath) == NULL)
2794 osl_freeVolumeDeviceHandleImpl (pHandle);
2795 return NULL;
2797 if ((pMountTab = fopen (MOUNTTAB, "r")) == NULL)
2799 osl_freeVolumeDeviceHandleImpl (pHandle);
2800 return NULL;
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, '/' );
2813 if ( NULL != pc )
2815 int len = pc - aMountEnt.mnt_special;
2817 strncpy( pHandle->pszDevice, aMountEnt.mnt_special, len );
2818 pHandle->pszDevice[len] = '\0';
2820 else
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);
2831 fclose (pMountTab);
2832 return pHandle;
2836 fclose (pMountTab);
2837 osl_freeVolumeDeviceHandleImpl (pHandle);
2838 return NULL;
2841 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
2843 FILE* pMountTab;
2844 struct mnttab aMountEnt;
2845 oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
2847 int nRet=0;
2848 sal_Char pszCmd[512] = "";
2850 if ( pHandle == 0 )
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) )
2863 case 0:
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);
2878 fclose (pMountTab);
2879 return osl_File_E_None;
2883 fclose (pMountTab);
2884 return osl_File_E_BUSY;
2886 //break; // break not necessary here, see return statements before
2888 case 1:
2889 return osl_File_E_BUSY;
2891 default:
2892 break;
2895 return osl_File_E_BUSY;
2898 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
2900 // FILE* pMountTab;
2901 // struct mnttab aMountEnt;
2902 oslVolumeDeviceHandleImpl* pHandle = (oslVolumeDeviceHandleImpl*) hFloppy;
2904 int nRet=0;
2905 sal_Char pszCmd[512] = "";
2907 if ( pHandle == 0 )
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) )
2920 case 0:
2922 FILE* pMountTab;
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) ) )
2935 fclose (pMountTab);
2936 return osl_File_E_BUSY;
2940 fclose (pMountTab);
2941 pHandle->pszMountPoint[0] = 0;
2942 return osl_File_E_None;
2945 //break; //break not necessary, see return statements before
2947 case 1:
2948 return osl_File_E_NODEV;
2950 case 4:
2951 pHandle->pszMountPoint[0] = 0;
2952 return osl_File_E_None;
2954 default:
2955 break;
2958 return osl_File_E_BUSY;
2961 #endif /* SOLARIS */
2963 /******************************************************************************
2965 * LINUX FLOPPY FUNCTIONS
2967 *****************************************************************************/
2969 #if defined(LINUX)
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);
2978 return 0;
2980 #endif /* LINUX */
2982 #if defined(LINUX)
2983 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
2985 sal_Bool bRet = sal_False;
2986 oslVolumeDeviceHandleImpl* pItem=0;
2987 int nRet;
2988 sal_Char pszCmd[PATH_MAX];
2989 const sal_Char* pszMountProg = "mount";
2990 sal_Char* pszSuDo = 0;
2991 sal_Char* pszTmp = 0;
2993 pszCmd[0] = '\0';
2995 #ifdef TRACE_OSL_FILE
2996 fprintf(stderr,"In osl_mountFloppy\n");
2997 #endif
2999 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
3001 if ( pItem == 0 )
3003 #ifdef TRACE_OSL_FILE
3004 fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
3005 #endif
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");
3014 #endif
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);
3023 #endif
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 ) */
3035 /* { */
3036 /* nRet=errno; */
3037 /* #ifdef DEBUG_OSL_FILE */
3038 /* perror("mount"); */
3039 /* #endif */
3040 /* } */
3042 pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
3043 if ( pszTmp != 0 )
3045 pszMountProg=pszTmp;
3048 pszTmp=getenv("SAL_MOUNT_SU_DO");
3049 if ( pszTmp != 0 )
3051 pszSuDo=pszTmp;
3054 if ( pszSuDo != 0 )
3056 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
3058 else
3060 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
3064 #ifdef DEBUG_OSL_FILE
3065 fprintf(stderr,"executing '%s'\n",pszCmd);
3066 #endif
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));
3073 #endif
3076 switch ( WEXITSTATUS(nRet) )
3078 case 0:
3079 nRet=0;
3080 break;
3082 case 2:
3083 nRet=EPERM;
3084 break;
3086 case 4:
3087 nRet=ENOENT;
3088 break;
3090 case 8:
3091 nRet=EINTR;
3092 break;
3094 case 16:
3095 nRet=EPERM;
3096 break;
3098 case 32:
3099 nRet=EBUSY;
3100 break;
3102 case 64:
3103 nRet=EAGAIN;
3104 break;
3106 default:
3107 nRet=EBUSY;
3108 break;
3111 return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
3113 #endif /* LINUX */
3116 #if defined(LINUX)
3117 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
3119 oslVolumeDeviceHandleImpl* pItem=0;
3120 int nRet=0;
3121 sal_Char pszCmd[PATH_MAX];
3122 sal_Char* pszTmp = 0;
3123 sal_Char* pszSuDo = 0;
3124 const sal_Char* pszUmountProg = "umount";
3126 pszCmd[0] = '\0';
3128 #ifdef TRACE_OSL_FILE
3129 fprintf(stderr,"In osl_unmountFloppy\n");
3130 #endif
3132 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
3134 if ( pItem == 0 )
3136 #ifdef TRACE_OSL_FILE
3137 fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
3138 #endif
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");
3146 #endif
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 ) */
3158 /* { */
3159 /* nRet = errno; */
3161 /* #ifdef DEBUG_OSL_FILE */
3162 /* perror("mount"); */
3163 /* #endif */
3164 /* } */
3167 pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
3168 if ( pszTmp != 0 )
3170 pszUmountProg=pszTmp;
3173 pszTmp = getenv("SAL_MOUNT_SU_DO");
3174 if ( pszTmp != 0 )
3176 pszSuDo=pszTmp;
3179 if ( pszSuDo != 0 )
3181 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
3183 else
3185 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
3189 #ifdef DEBUG_OSL_FILE
3190 fprintf(stderr,"executing '%s'\n",pszCmd);
3191 #endif
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));
3198 #endif
3200 switch ( WEXITSTATUS(nRet) )
3202 case 0:
3203 nRet=0;
3204 break;
3206 default:
3207 nRet=EBUSY;
3208 break;
3211 #ifdef TRACE_OSL_FILE
3212 fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
3213 #endif
3215 return ((0 == nRet) ? oslTranslateFileError(OSL_FET_SUCCESS, nRet) : oslTranslateFileError(OSL_FET_ERROR, nRet));
3217 /* return osl_File_E_None;*/
3220 #endif /* LINUX */
3222 #if defined(LINUX)
3223 static sal_Bool
3224 osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
3226 struct mntent* pMountEnt;
3227 FILE* pMountTab;
3229 pMountTab = setmntent (MOUNTTAB, "r");
3230 if (pMountTab == 0)
3231 return sal_False;
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);
3248 return sal_True;
3252 endmntent (pMountTab);
3253 return sal_False;
3255 #endif /* LINUX */
3257 #if defined(LINUX)
3258 static sal_Bool
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)
3267 return sal_True;
3269 return sal_False;
3271 #endif /* LINUX */
3273 /******************************************************************************
3275 * IRIX FLOPPY FUNCTIONS
3277 *****************************************************************************/
3279 #if defined(IRIX)
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");
3287 #endif
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");
3295 #endif
3296 rtl_freeMemory(pItem);
3297 return 0;
3301 #ifdef DEBUG_OSL_FILE
3302 osl_printFloppyHandle(pItem);
3303 #endif
3304 #ifdef TRACE_OSL_FILE
3305 fprintf(stderr,"Out osl_isFloppyDrive [ok]\n");
3306 #endif
3308 return (oslVolumeDeviceHandle) pItem;
3312 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
3314 sal_Bool bRet = sal_False;
3315 oslVolumeDeviceHandleImpl* pItem=0;
3316 int nRet;
3317 sal_Char pszCmd[PATH_MAX];
3318 sal_Char* pszMountProg = "mount";
3319 sal_Char* pszSuDo = 0;
3320 sal_Char* pszTmp = 0;
3322 pszCmd[0] = '\0';
3324 #ifdef TRACE_OSL_FILE
3325 fprintf(stderr,"In osl_mountFloppy\n");
3326 #endif
3328 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
3330 if ( pItem == 0 )
3332 #ifdef TRACE_OSL_FILE
3333 fprintf(stderr,"Out osl_mountFloppy [pItem == 0]\n");
3334 #endif
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");
3343 #endif
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);
3352 #endif
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 ) */
3364 /* { */
3365 /* nRet=errno; */
3366 /* #ifdef DEBUG_OSL_FILE */
3367 /* perror("mount"); */
3368 /* #endif */
3369 /* } */
3371 pszTmp = getenv("SAL_MOUNT_MOUNTPROG");
3372 if ( pszTmp != 0 )
3374 pszMountProg=pszTmp;
3377 pszTmp=getenv("SAL_MOUNT_SU_DO");
3378 if ( pszTmp != 0 )
3380 pszSuDo=pszTmp;
3383 if ( pszSuDo != 0 )
3385 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s %s",pszSuDo,pszMountProg,pItem->pszDevice,pItem->pszMountPoint);
3387 else
3389 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszMountProg,pItem->pszMountPoint);
3393 #ifdef DEBUG_OSL_FILE
3394 fprintf(stderr,"executing '%s'\n",pszCmd);
3395 #endif
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));
3402 #endif
3405 switch ( WEXITSTATUS(nRet) )
3407 case 0:
3408 nRet=0;
3409 break;
3411 case 2:
3412 nRet=EPERM;
3413 break;
3415 case 4:
3416 nRet=ENOENT;
3417 break;
3419 case 8:
3420 nRet=EINTR;
3421 break;
3423 case 16:
3424 nRet=EPERM;
3425 break;
3427 case 32:
3428 nRet=EBUSY;
3429 break;
3431 case 64:
3432 nRet=EAGAIN;
3433 break;
3435 default:
3436 nRet=EBUSY;
3437 break;
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;
3446 int nRet=0;
3447 sal_Char pszCmd[PATH_MAX];
3448 sal_Char* pszTmp = 0;
3449 sal_Char* pszSuDo = 0;
3450 sal_Char* pszUmountProg = "umount";
3452 pszCmd[0] = '\0';
3454 #ifdef TRACE_OSL_FILE
3455 fprintf(stderr,"In osl_unmountFloppy\n");
3456 #endif
3458 pItem = (oslVolumeDeviceHandleImpl*) hFloppy;
3460 if ( pItem == 0 )
3462 #ifdef TRACE_OSL_FILE
3463 fprintf(stderr,"Out osl_unmountFloppy [pItem==0]\n");
3464 #endif
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");
3472 #endif
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 ) */
3484 /* { */
3485 /* nRet = errno; */
3487 /* #ifdef DEBUG_OSL_FILE */
3488 /* perror("mount"); */
3489 /* #endif */
3490 /* } */
3493 pszTmp = getenv("SAL_MOUNT_UMOUNTPROG");
3494 if ( pszTmp != 0 )
3496 pszUmountProg=pszTmp;
3499 pszTmp = getenv("SAL_MOUNT_SU_DO");
3500 if ( pszTmp != 0 )
3502 pszSuDo=pszTmp;
3505 if ( pszSuDo != 0 )
3507 snprintf(pszCmd, sizeof(pszCmd), "%s %s %s",pszSuDo,pszUmountProg,pItem->pszMountPoint);
3509 else
3511 snprintf(pszCmd, sizeof(pszCmd), "%s %s",pszUmountProg,pItem->pszMountPoint);
3515 #ifdef DEBUG_OSL_FILE
3516 fprintf(stderr,"executing '%s'\n",pszCmd);
3517 #endif
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));
3524 #endif
3526 switch ( WEXITSTATUS(nRet) )
3528 case 0:
3529 nRet=0;
3530 break;
3532 default:
3533 nRet=EBUSY;
3534 break;
3537 #ifdef TRACE_OSL_FILE
3538 fprintf(stderr,"Out osl_unmountFloppy [ok]\n");
3539 #endif
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];
3550 FILE* mntfile=0;
3551 int nRet=0;
3553 buffer[0] = '\0';
3555 mntfile = setmntent(MOUNTTAB,"r");
3557 #ifdef TRACE_OSL_FILE
3558 fprintf(stderr,"In osl_getFloppyMountEntry\n");
3559 #endif
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);
3566 #endif
3569 if ( mntfile == 0 )
3571 nRet=errno;
3572 #ifdef DEBUG_OSL_FILE
3573 perror("mounttab");
3574 #endif
3575 #ifdef TRACE_OSL_FILE
3576 fprintf(stderr,"Out osl_getFloppyMountEntry [mntfile]\n");
3577 #endif
3578 return sal_False;
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);*/
3588 #endif
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);
3602 fclose(mntfile);
3603 #ifdef DEBUG_OSL_FILE
3604 fprintf(stderr,"Mount Point found '%s'\n",pItem->pszMountPoint);
3605 #endif
3606 #ifdef TRACE_OSL_FILE
3607 fprintf(stderr,"Out osl_getFloppyMountEntry [found]\n");
3608 #endif
3609 return sal_True;
3611 #ifdef DEBUG_OSL_FILE
3612 /* fprintf(stderr,"=================\n");*/
3613 #endif
3614 pMountEnt=getmntent(mntfile);
3617 #ifdef TRACE_OSL_FILE
3618 fprintf(stderr,"Out osl_getFloppyMountEntry [not found]\n");
3619 #endif
3621 fclose(mntfile);
3622 return sal_False;
3625 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
3627 sal_Char buffer[PATH_MAX];
3628 oslVolumeDeviceHandleImpl* pItem=0;
3629 sal_Bool bRet=0;
3631 buffer[0] = '\0';
3633 #ifdef TRACE_OSL_FILE
3634 fprintf(stderr,"In osl_isFloppyMounted\n");
3635 #endif
3637 pItem = osl_newVolumeDeviceHandleImpl ();
3638 if ( pItem == 0 )
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);
3646 #endif
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");
3654 #endif
3655 return sal_False;
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");
3663 #endif
3664 rtl_freeMemory(pItem);
3665 return sal_True;
3668 #ifdef TRACE_OSL_FILE
3669 fprintf(stderr,"Out osl_isFloppyMounted [may be EBUSY]\n");
3670 #endif
3672 rtl_freeMemory(pItem);
3673 return sal_False;
3675 #endif /* IRIX */
3678 /* NetBSD floppy functions have to be added here. Until we have done that,
3679 * we use the MACOSX definitions for nonexistent floppy.
3680 * */
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)
3691 return NULL;
3693 #endif /* MACOSX */
3695 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
3696 static oslFileError osl_mountFloppy(oslVolumeDeviceHandle hFloppy)
3698 return osl_File_E_BUSY;
3700 #endif /* MACOSX */
3702 #if ( defined(MACOSX) || defined(NETBSD) || defined(FREEBSD))
3703 static oslFileError osl_unmountFloppy(oslVolumeDeviceHandle hFloppy)
3705 return osl_File_E_BUSY;
3707 #endif /* MACOSX */
3709 #if ( defined(NETBSD) || defined(FREEBSD) )
3710 static sal_Bool osl_getFloppyMountEntry(const sal_Char* pszPath, oslVolumeDeviceHandleImpl* pItem)
3712 return sal_False;
3714 #endif /* NETBSD || FREEBSD */
3716 #if ( defined(NETBSD) || defined(FREEBSD) )
3717 static sal_Bool osl_isFloppyMounted(oslVolumeDeviceHandleImpl* pDevice)
3719 return sal_False;
3721 #endif /* NETBSD || FREEBSD */
3724 #ifdef DEBUG_OSL_FILE
3725 static void osl_printFloppyHandle(oslVolumeDeviceHandleImpl* pItem)
3727 if (pItem == 0 )
3729 fprintf(stderr,"NULL Handle\n");
3730 return;
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");
3736 #endif
3737 return;
3741 fprintf(stderr,"MountPoint : '%s'\n",pItem->pszMountPoint);
3742 fprintf(stderr,"FilePath : '%s'\n",pItem->pszFilePath);
3743 fprintf(stderr,"Device : '%s'\n",pItem->pszDevice);
3745 return;
3747 #endif