1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "osl/file.hxx"
30 #include "osl/diagnose.h"
31 #include "osl/thread.h"
32 #include "rtl/alloc.h"
35 #include "file_impl.hxx"
36 #include "file_error_transl.h"
37 #include "file_path_helper.hxx"
39 #include "uunxapi.hxx"
41 #include <sys/types.h>
51 /************************************************************************
54 * - Fix: check for corresponding struct sizes in exported functions
55 * - check size/use of oslDirectory
56 * - check size/use of oslDirectoryItem
57 ***********************************************************************/
58 /******************************************************************************
60 * Data Type Definition
62 ******************************************************************************/
66 rtl_uString
* ustrPath
; /* holds native directory path */
71 /* FIXME: reintroducing this may save some extra bytes per Item */
74 rtl_uString
* ustrFileName
; /* holds native file name */
75 rtl_uString
* ustrDirPath
; /* holds native dir path */
77 } oslDirectoryItemImpl
;
80 DirectoryItem_Impl::DirectoryItem_Impl(
81 rtl_uString
* ustrFilePath
, unsigned char DType
)
83 m_ustrFilePath (ustrFilePath
),
86 if (m_ustrFilePath
!= 0)
87 rtl_uString_acquire(m_ustrFilePath
);
89 DirectoryItem_Impl::~DirectoryItem_Impl()
91 if (m_ustrFilePath
!= 0)
92 rtl_uString_release(m_ustrFilePath
);
95 void * DirectoryItem_Impl::operator new(size_t n
)
97 return rtl_allocateMemory(n
);
99 void DirectoryItem_Impl::operator delete(void * p
, size_t)
104 void DirectoryItem_Impl::acquire()
108 void DirectoryItem_Impl::release()
110 if (0 == --m_RefCount
)
114 oslFileType
DirectoryItem_Impl::getFileType() const
118 #ifdef _DIRENT_HAVE_D_TYPE
120 return osl_File_Type_Link
;
122 return osl_File_Type_Directory
;
124 return osl_File_Type_Regular
;
126 return osl_File_Type_Fifo
;
128 return osl_File_Type_Socket
;
131 return osl_File_Type_Special
;
132 #endif /* _DIRENT_HAVE_D_TYPE */
136 return osl_File_Type_Unknown
;
139 /******************************************************************************
141 * C-String Function Declarations
143 *****************************************************************************/
145 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
146 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
148 /*******************************************************************
150 ******************************************************************/
152 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
154 rtl_uString
* ustrSystemPath
= NULL
;
159 if ((0 == ustrDirectoryURL
) || (0 == ustrDirectoryURL
->length
) || (0 == pDirectory
))
160 return osl_File_E_INVAL
;
162 /* convert file URL to system path */
163 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
165 if( osl_File_E_None
!= eRet
)
168 osl_systemPathRemoveSeparator(ustrSystemPath
);
170 /* convert unicode path to text */
171 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
)
173 && macxp_resolveAlias( path
, PATH_MAX
) == 0
178 DIR *pdir
= opendir( path
);
182 /* create and initialize impl structure */
183 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
187 pDirImpl
->pDirStruct
= pdir
;
188 pDirImpl
->ustrPath
= ustrSystemPath
;
190 *pDirectory
= (oslDirectory
) pDirImpl
;
191 return osl_File_E_None
;
201 #ifdef DEBUG_OSL_FILE
202 perror ("osl_openDirectory"); fprintf (stderr
, path
);
207 rtl_uString_release( ustrSystemPath
);
209 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
212 /****************************************************************************/
213 /* osl_closeDirectory */
214 /****************************************************************************/
216 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
218 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) Directory
;
219 oslFileError err
= osl_File_E_None
;
221 OSL_ASSERT( Directory
);
223 if( NULL
== pDirImpl
)
224 return osl_File_E_INVAL
;
226 /* close directory */
227 if( closedir( pDirImpl
->pDirStruct
) )
229 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
232 /* cleanup members */
233 rtl_uString_release( pDirImpl
->ustrPath
);
235 rtl_freeMemory( pDirImpl
);
240 /**********************************************
243 * readdir wrapper, filters out "." and ".."
245 *********************************************/
247 static struct dirent
* osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
249 struct dirent
* pdirent
;
251 while ((pdirent
= readdir(pdir
)) != NULL
)
253 if (bFilterLocalAndParentDir
&&
254 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
263 /****************************************************************************
264 * osl_getNextDirectoryItem
265 ***************************************************************************/
267 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, sal_uInt32
/*uHint*/)
269 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*)Directory
;
270 rtl_uString
* ustrFileName
= NULL
;
271 rtl_uString
* ustrFilePath
= NULL
;
272 struct dirent
* pEntry
;
274 OSL_ASSERT(Directory
);
277 if ((NULL
== Directory
) || (NULL
== pItem
))
278 return osl_File_E_INVAL
;
280 pEntry
= osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
283 return osl_File_E_NOENT
;
288 // convert decomposed filename to precomposed unicode
289 char composed_name
[BUFSIZ
];
290 CFMutableStringRef strRef
= CFStringCreateMutable (NULL
, 0 );
291 CFStringAppendCString( strRef
, pEntry
->d_name
, kCFStringEncodingUTF8
); //UTF8 is default on Mac OSX
292 CFStringNormalize( strRef
, kCFStringNormalizationFormC
);
293 CFStringGetCString( strRef
, composed_name
, BUFSIZ
, kCFStringEncodingUTF8
);
295 rtl_string2UString( &ustrFileName
, composed_name
, strlen( composed_name
),
296 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
299 /* convert file name to unicode */
300 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
301 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
302 OSL_ASSERT(ustrFileName
!= 0);
306 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &ustrFilePath
);
307 rtl_uString_release( ustrFileName
);
309 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(*pItem
);
312 pImpl
->release(), pImpl
= 0;
314 #ifdef _DIRENT_HAVE_D_TYPE
315 pImpl
= new DirectoryItem_Impl(ustrFilePath
, pEntry
->d_type
);
317 pImpl
= new DirectoryItem_Impl(ustrFilePath
);
318 #endif /* _DIRENT_HAVE_D_TYPE */
320 rtl_uString_release( ustrFilePath
);
322 return osl_File_E_None
;
325 /****************************************************************************/
326 /* osl_getDirectoryItem */
327 /****************************************************************************/
329 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
331 rtl_uString
* ustrSystemPath
= NULL
;
332 oslFileError osl_error
= osl_File_E_INVAL
;
334 OSL_ASSERT(ustrFileURL
);
337 if (0 == ustrFileURL
->length
|| NULL
== pItem
)
338 return osl_File_E_INVAL
;
340 osl_error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &ustrSystemPath
, sal_False
);
341 if (osl_File_E_None
!= osl_error
)
344 osl_systemPathRemoveSeparator(ustrSystemPath
);
346 if (-1 == access_u(ustrSystemPath
, F_OK
))
348 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
352 *pItem
= new DirectoryItem_Impl(ustrSystemPath
);
354 rtl_uString_release(ustrSystemPath
);
360 /****************************************************************************/
361 /* osl_acquireDirectoryItem */
362 /****************************************************************************/
364 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
366 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
368 return osl_File_E_INVAL
;
371 return osl_File_E_None
;
374 /****************************************************************************/
375 /* osl_releaseDirectoryItem */
376 /****************************************************************************/
378 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
380 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
382 return osl_File_E_INVAL
;
385 return osl_File_E_None
;
388 /****************************************************************************/
389 /* osl_createDirectory */
390 /****************************************************************************/
392 oslFileError SAL_CALL
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
397 OSL_ASSERT( ustrDirectoryURL
);
399 /* convert directory url to system path */
400 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
401 if( eRet
!= osl_File_E_None
)
405 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
406 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
409 return osl_psz_createDirectory( path
);
412 /****************************************************************************/
413 /* osl_removeDirectory */
414 /****************************************************************************/
416 oslFileError SAL_CALL
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
421 OSL_ASSERT( ustrDirectoryURL
);
423 /* convert directory url to system path */
424 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
425 if( eRet
!= osl_File_E_None
)
429 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
430 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
433 return osl_psz_removeDirectory( path
);
436 /*****************************************
437 * osl_psz_createDirectory
438 ****************************************/
440 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
443 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
445 nRet
= mkdir(pszPath
,mode
);
450 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
453 return osl_File_E_None
;
456 /*****************************************
457 * osl_psz_removeDirectory
458 ****************************************/
460 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
464 nRet
= rmdir(pszPath
);
469 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
472 return osl_File_E_None
;
475 /****************************************************************************/
476 /* osl_createDirectoryPath */
477 /****************************************************************************/
479 static int path_make_parent(sal_Unicode
* path
)
481 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
492 static int create_dir_with_callback(
493 sal_Unicode
* directory_path
,
494 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
497 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
499 if (osl::mkdir(directory_path
, mode
) == 0)
501 if (aDirectoryCreationCallbackFunc
)
504 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
505 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
512 static oslFileError
create_dir_recursively_(
513 sal_Unicode
* dir_path
,
514 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
517 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
518 "Path must not end with a slash");
520 int native_err
= create_dir_with_callback(
521 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
524 return osl_File_E_None
;
526 if (native_err
!= ENOENT
)
527 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
529 // we step back until '/a_dir' at maximum because
530 // we should get an error unequal ENOENT when
531 // we try to create 'a_dir' at '/' and would so
533 int pos
= path_make_parent(dir_path
);
535 oslFileError osl_error
= create_dir_recursively_(
536 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
538 if (osl_File_E_None
!= osl_error
)
543 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
546 oslFileError SAL_CALL
osl_createDirectoryPath(
547 rtl_uString
* aDirectoryUrl
,
548 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
551 if (aDirectoryUrl
== NULL
)
552 return osl_File_E_INVAL
;
554 rtl::OUString sys_path
;
555 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
556 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
558 if (osl_error
!= osl_File_E_None
)
561 osl::systemPathRemoveSeparator(sys_path
);
563 // const_cast because sys_path is a local copy which we want to modify inplace instead of
564 // coyp it into another buffer on the heap again
565 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
568 /******************************************************************************
570 * C-String Function Declarations
572 *****************************************************************************/
574 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
575 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
576 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
579 /******************************************************************************
581 * Static Module Utility Function Declarations
583 *****************************************************************************/
585 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
586 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
587 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
588 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
589 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
591 /****************************************************************************/
593 /****************************************************************************/
595 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
597 char srcPath
[PATH_MAX
];
598 char destPath
[PATH_MAX
];
601 OSL_ASSERT( ustrFileURL
);
602 OSL_ASSERT( ustrDestURL
);
604 /* convert source url to system path */
605 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
606 if( eRet
!= osl_File_E_None
)
609 /* convert destination url to system path */
610 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
611 if( eRet
!= osl_File_E_None
)
615 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
616 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
619 return oslDoMoveFile( srcPath
, destPath
);
622 /****************************************************************************/
624 /****************************************************************************/
626 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
628 char srcPath
[PATH_MAX
];
629 char destPath
[PATH_MAX
];
632 OSL_ASSERT( ustrFileURL
);
633 OSL_ASSERT( ustrDestURL
);
635 /* convert source url to system path */
636 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
637 if( eRet
!= osl_File_E_None
)
640 /* convert destination url to system path */
641 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
642 if( eRet
!= osl_File_E_None
)
646 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
647 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
650 return osl_psz_copyFile( srcPath
, destPath
);
653 /****************************************************************************/
655 /****************************************************************************/
657 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* ustrFileURL
)
662 OSL_ASSERT( ustrFileURL
);
664 /* convert file url to system path */
665 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
666 if( eRet
!= osl_File_E_None
)
670 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
671 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
674 return osl_psz_removeFile( path
);
677 /******************************************************************************
681 *****************************************************************************/
683 /*****************************************
685 ****************************************/
687 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
689 oslFileError tErr
=osl_File_E_invalidError
;
691 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
692 if ( tErr
== osl_File_E_None
)
697 if ( tErr
!= osl_File_E_XDEV
)
702 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
704 if ( tErr
!= osl_File_E_None
)
706 oslFileError tErrRemove
;
707 tErrRemove
=osl_psz_removeFile(pszDestPath
);
711 tErr
=osl_psz_removeFile(pszPath
);
716 /*****************************************
718 ****************************************/
719 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
724 nRet
= lstat(pszPath
,&aStat
);
728 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
731 if ( S_ISDIR(aStat
.st_mode
) )
733 return osl_File_E_ISDIR
;
736 nRet
= unlink(pszPath
);
740 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
743 return osl_File_E_None
;
746 /*****************************************
748 ****************************************/
750 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
755 nRet
= rename(pszPath
,pszDestPath
);
760 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
763 return osl_File_E_None
;
766 /*****************************************
768 ****************************************/
770 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
778 struct stat aFileStat
;
779 oslFileError tErr
=osl_File_E_invalidError
;
780 size_t nSourceSize
=0;
781 int DestFileExists
=1;
783 /* mfe: does the source file really exists? */
784 nRet
= lstat(pszPath
,&aFileStat
);
789 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
792 /* mfe: we do only copy files here! */
793 if ( S_ISDIR(aFileStat
.st_mode
) )
795 return osl_File_E_ISDIR
;
798 nSourceSize
=(size_t)aFileStat
.st_size
;
799 nMode
=aFileStat
.st_mode
;
800 nAcTime
=aFileStat
.st_atime
;
801 nModTime
=aFileStat
.st_mtime
;
802 nUID
=aFileStat
.st_uid
;
803 nGID
=aFileStat
.st_gid
;
805 nRet
= stat(pszDestPath
,&aFileStat
);
810 if ( nRet
== ENOENT
)
814 /* return oslTranslateFileError(nRet);*/
817 /* mfe: the destination file must not be a directory! */
818 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
820 return osl_File_E_ISDIR
;
824 /* mfe: file does not exists or is no dir */
827 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
829 if ( tErr
!= osl_File_E_None
)
835 * mfe: ignore return code
836 * since only the success of the copy is
839 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
845 /******************************************************************************
849 *****************************************************************************/
851 /*****************************************
853 ****************************************/
855 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
857 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
860 sal_Char pszTmpDestFile
[PATH_MAX
];
861 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
863 /* Quick fix for #106048, the whole copy file function seems
864 to be erroneous anyway and needs to be rewritten.
865 Besides osl_copyFile is currently not used from OO/SO code.
867 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
869 if ( DestFileExists
)
871 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
873 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
874 return osl_File_E_NAMETOOLONG
;
876 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
878 /* FIXME: what if pszTmpDestFile already exists? */
879 /* with getcanonical??? */
880 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
883 /* mfe: should be S_ISREG */
884 if ( !S_ISLNK(nMode
) )
886 /* copy SourceFile to DestFile */
887 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
889 /* mfe: OK redundant at the moment */
890 else if ( S_ISLNK(nMode
) )
892 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
896 /* mfe: what to do here? */
900 if ( nRet
> 0 && DestFileExists
== 1 )
902 unlink(pszDestFileName
);
903 rename(pszTmpDestFile
,pszDestFileName
);
908 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
911 if ( DestFileExists
== 1 )
913 unlink(pszTmpDestFile
);
916 return osl_File_E_None
;
919 /*****************************************
921 ****************************************/
923 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
926 struct utimbuf aTimeBuffer
;
928 nRet
= chmod(pszFileName
,nMode
);
932 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
935 aTimeBuffer
.actime
=nAcTime
;
936 aTimeBuffer
.modtime
=nModTime
;
937 nRet
=utime(pszFileName
,&aTimeBuffer
);
941 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
944 if ( nUID
!= getuid() )
949 nRet
=chown(pszFileName
,nUID
,nGID
);
954 /* mfe: do not return an error here! */
955 /* return oslTranslateFileError(nRet);*/
958 return osl_File_E_None
;
961 /*****************************************
963 ****************************************/
965 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
969 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
970 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
971 sal_Char pszLinkContent
[PATH_MAX
];
973 pszLinkContent
[0] = '\0';
975 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
983 pszLinkContent
[ nRet
] = 0;
985 nRet
= symlink(pszLinkContent
,pszDestFileName
);
996 /*****************************************
998 ****************************************/
1000 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
1005 void* pSourceFile
=0;
1007 SourceFileFD
=open(pszSourceFileName
,O_RDONLY
);
1008 if ( SourceFileFD
< 0 )
1014 DestFileFD
=open(pszDestFileName
, O_WRONLY
| O_CREAT
, mode
);
1016 if ( DestFileFD
< 0 )
1019 close(SourceFileFD
);
1023 /* HACK: because memory mapping fails on various
1024 platforms if the size of the source file is 0 byte */
1025 if (0 == nSourceSize
)
1027 close(SourceFileFD
);
1032 /* FIXME doCopy: fall back code for systems not having mmap */
1033 /* mmap file -- open dest file -- write once -- fsync it */
1034 pSourceFile
=mmap(0,nSourceSize
,PROT_READ
,MAP_PRIVATE
,SourceFileFD
,0);
1036 if ( pSourceFile
== MAP_FAILED
)
1038 /* it's important to set nRet before the hack
1039 otherwise errno may be changed by lstat */
1041 close(SourceFileFD
);
1047 nRet
= write(DestFileFD
,pSourceFile
,nSourceSize
);
1049 /* #112584# if 'write' could not write the requested number of bytes
1050 we have to fail of course; because it's not exactly specified if 'write'
1051 sets errno if less than requested byte could be written we set nRet
1052 explicitly to ENOSPC */
1053 if ((nRet
< 0) || (nRet
!= sal::static_int_cast
< int >(nSourceSize
)))
1060 close(SourceFileFD
);
1062 munmap((char*)pSourceFile
,nSourceSize
);
1066 nRet
= munmap((char*)pSourceFile
,nSourceSize
);
1070 close(SourceFileFD
);
1075 close(SourceFileFD
);
1077 // Removed call to 'fsync' again (#112584#) and instead
1078 // evaluate the return value of 'close' in order to detect
1079 // and report ENOSPC and other erronous conditions on close
1080 if (close(DestFileFD
) == -1)