1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
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 <osl/signal.h>
33 #include "rtl/alloc.h"
36 #include "file_impl.hxx"
37 #include "file_error_transl.h"
38 #include "file_path_helper.hxx"
40 #include "uunxapi.hxx"
42 #include <sys/types.h>
54 /************************************************************************
57 * - Fix: check for corresponding struct sizes in exported functions
58 * - check size/use of oslDirectory
59 * - check size/use of oslDirectoryItem
60 ***********************************************************************/
61 /******************************************************************************
63 * Data Type Definition
65 ******************************************************************************/
69 rtl_uString
* ustrPath
; /* holds native directory path */
74 /* FIXME: reintroducing this may save some extra bytes per Item */
77 rtl_uString
* ustrFileName
; /* holds native file name */
78 rtl_uString
* ustrDirPath
; /* holds native dir path */
80 } oslDirectoryItemImpl
;
83 DirectoryItem_Impl::DirectoryItem_Impl(
84 rtl_uString
* ustrFilePath
, unsigned char DType
)
86 m_ustrFilePath (ustrFilePath
),
89 if (m_ustrFilePath
!= 0)
90 rtl_uString_acquire(m_ustrFilePath
);
92 DirectoryItem_Impl::~DirectoryItem_Impl()
94 if (m_ustrFilePath
!= 0)
95 rtl_uString_release(m_ustrFilePath
);
98 void * DirectoryItem_Impl::operator new(size_t n
)
100 return rtl_allocateMemory(n
);
102 void DirectoryItem_Impl::operator delete(void * p
, size_t)
107 void DirectoryItem_Impl::acquire()
111 void DirectoryItem_Impl::release()
113 if (0 == --m_RefCount
)
117 oslFileType
DirectoryItem_Impl::getFileType() const
121 #ifdef _DIRENT_HAVE_D_TYPE
123 return osl_File_Type_Link
;
125 return osl_File_Type_Directory
;
127 return osl_File_Type_Regular
;
129 return osl_File_Type_Fifo
;
131 return osl_File_Type_Socket
;
134 return osl_File_Type_Special
;
135 #endif /* _DIRENT_HAVE_D_TYPE */
139 return osl_File_Type_Unknown
;
142 /******************************************************************************
144 * C-String Function Declarations
146 *****************************************************************************/
148 static oslFileError
osl_psz_createDirectory(const sal_Char
* pszPath
);
149 static oslFileError
osl_psz_removeDirectory(const sal_Char
* pszPath
);
151 /*******************************************************************
153 ******************************************************************/
155 oslFileError SAL_CALL
osl_openDirectory(rtl_uString
* ustrDirectoryURL
, oslDirectory
* pDirectory
)
157 rtl_uString
* ustrSystemPath
= NULL
;
162 if ((0 == ustrDirectoryURL
) || (0 == ustrDirectoryURL
->length
) || (0 == pDirectory
))
163 return osl_File_E_INVAL
;
165 /* convert file URL to system path */
166 eRet
= osl_getSystemPathFromFileURL_Ex(ustrDirectoryURL
, &ustrSystemPath
, sal_False
);
168 if( osl_File_E_None
!= eRet
)
171 osl_systemPathRemoveSeparator(ustrSystemPath
);
173 /* convert unicode path to text */
174 if ( UnicodeToText( path
, PATH_MAX
, ustrSystemPath
->buffer
, ustrSystemPath
->length
)
176 && macxp_resolveAlias( path
, PATH_MAX
) == 0
181 DIR *pdir
= opendir( path
);
185 /* create and initialize impl structure */
186 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) rtl_allocateMemory( sizeof(oslDirectoryImpl
) );
190 pDirImpl
->pDirStruct
= pdir
;
191 pDirImpl
->ustrPath
= ustrSystemPath
;
193 *pDirectory
= (oslDirectory
) pDirImpl
;
194 return osl_File_E_None
;
204 #ifdef DEBUG_OSL_FILE
205 perror ("osl_openDirectory"); fprintf (stderr
, path
);
210 rtl_uString_release( ustrSystemPath
);
212 return oslTranslateFileError(OSL_FET_ERROR
, errno
);
215 /****************************************************************************/
216 /* osl_closeDirectory */
217 /****************************************************************************/
219 oslFileError SAL_CALL
osl_closeDirectory( oslDirectory Directory
)
221 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*) Directory
;
222 oslFileError err
= osl_File_E_None
;
224 OSL_ASSERT( Directory
);
226 if( NULL
== pDirImpl
)
227 return osl_File_E_INVAL
;
229 /* close directory */
230 if( closedir( pDirImpl
->pDirStruct
) )
232 err
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
235 /* cleanup members */
236 rtl_uString_release( pDirImpl
->ustrPath
);
238 rtl_freeMemory( pDirImpl
);
243 /**********************************************
246 * readdir wrapper, filters out "." and ".."
248 *********************************************/
250 static struct dirent
* osl_readdir_impl_(DIR* pdir
, sal_Bool bFilterLocalAndParentDir
)
252 struct dirent
* pdirent
;
254 while ((pdirent
= readdir(pdir
)) != NULL
)
256 if (bFilterLocalAndParentDir
&&
257 ((0 == strcmp(pdirent
->d_name
, ".")) || (0 == strcmp(pdirent
->d_name
, ".."))))
266 /****************************************************************************
267 * osl_getNextDirectoryItem
268 ***************************************************************************/
270 oslFileError SAL_CALL
osl_getNextDirectoryItem(oslDirectory Directory
, oslDirectoryItem
* pItem
, sal_uInt32
/*uHint*/)
272 oslDirectoryImpl
* pDirImpl
= (oslDirectoryImpl
*)Directory
;
273 rtl_uString
* ustrFileName
= NULL
;
274 rtl_uString
* ustrFilePath
= NULL
;
275 struct dirent
* pEntry
;
277 OSL_ASSERT(Directory
);
280 if ((NULL
== Directory
) || (NULL
== pItem
))
281 return osl_File_E_INVAL
;
283 pEntry
= osl_readdir_impl_(pDirImpl
->pDirStruct
, sal_True
);
286 return osl_File_E_NOENT
;
291 // convert decomposed filename to precomposed unicode
292 char composed_name
[BUFSIZ
];
293 CFMutableStringRef strRef
= CFStringCreateMutable (NULL
, 0 );
294 CFStringAppendCString( strRef
, pEntry
->d_name
, kCFStringEncodingUTF8
); //UTF8 is default on Mac OSX
295 CFStringNormalize( strRef
, kCFStringNormalizationFormC
);
296 CFStringGetCString( strRef
, composed_name
, BUFSIZ
, kCFStringEncodingUTF8
);
298 rtl_string2UString( &ustrFileName
, composed_name
, strlen( composed_name
),
299 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
302 /* convert file name to unicode */
303 rtl_string2UString( &ustrFileName
, pEntry
->d_name
, strlen( pEntry
->d_name
),
304 osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS
);
305 OSL_ASSERT(ustrFileName
!= 0);
309 osl_systemPathMakeAbsolutePath(pDirImpl
->ustrPath
, ustrFileName
, &ustrFilePath
);
310 rtl_uString_release( ustrFileName
);
312 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(*pItem
);
315 pImpl
->release(), pImpl
= 0;
317 #ifdef _DIRENT_HAVE_D_TYPE
318 pImpl
= new DirectoryItem_Impl(ustrFilePath
, pEntry
->d_type
);
320 pImpl
= new DirectoryItem_Impl(ustrFilePath
);
321 #endif /* _DIRENT_HAVE_D_TYPE */
323 rtl_uString_release( ustrFilePath
);
325 return osl_File_E_None
;
328 /****************************************************************************/
329 /* osl_getDirectoryItem */
330 /****************************************************************************/
332 oslFileError SAL_CALL
osl_getDirectoryItem( rtl_uString
* ustrFileURL
, oslDirectoryItem
* pItem
)
334 rtl_uString
* ustrSystemPath
= NULL
;
335 oslFileError osl_error
= osl_File_E_INVAL
;
337 OSL_ASSERT((0 != ustrFileURL
) && (0 != pItem
));
338 if ((0 == ustrFileURL
) || (0 == ustrFileURL
->length
) || (0 == pItem
))
339 return osl_File_E_INVAL
;
341 osl_error
= osl_getSystemPathFromFileURL_Ex(ustrFileURL
, &ustrSystemPath
, sal_False
);
342 if (osl_File_E_None
!= osl_error
)
345 osl_systemPathRemoveSeparator(ustrSystemPath
);
347 if (-1 == access_u(ustrSystemPath
, F_OK
))
349 osl_error
= oslTranslateFileError(OSL_FET_ERROR
, errno
);
353 *pItem
= new DirectoryItem_Impl(ustrSystemPath
);
355 rtl_uString_release(ustrSystemPath
);
361 /****************************************************************************/
362 /* osl_acquireDirectoryItem */
363 /****************************************************************************/
365 oslFileError SAL_CALL
osl_acquireDirectoryItem( oslDirectoryItem Item
)
367 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
369 return osl_File_E_INVAL
;
372 return osl_File_E_None
;
375 /****************************************************************************/
376 /* osl_releaseDirectoryItem */
377 /****************************************************************************/
379 oslFileError SAL_CALL
osl_releaseDirectoryItem( oslDirectoryItem Item
)
381 DirectoryItem_Impl
* pImpl
= static_cast< DirectoryItem_Impl
* >(Item
);
383 return osl_File_E_INVAL
;
386 return osl_File_E_None
;
389 /****************************************************************************/
390 /* osl_createDirectory */
391 /****************************************************************************/
393 oslFileError SAL_CALL
osl_createDirectory( rtl_uString
* ustrDirectoryURL
)
398 OSL_ASSERT( ustrDirectoryURL
);
400 /* convert directory url to system path */
401 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
402 if( eRet
!= osl_File_E_None
)
406 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
407 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
410 return osl_psz_createDirectory( path
);
413 /****************************************************************************/
414 /* osl_removeDirectory */
415 /****************************************************************************/
417 oslFileError SAL_CALL
osl_removeDirectory( rtl_uString
* ustrDirectoryURL
)
422 OSL_ASSERT( ustrDirectoryURL
);
424 /* convert directory url to system path */
425 eRet
= FileURLToPath( path
, PATH_MAX
, ustrDirectoryURL
);
426 if( eRet
!= osl_File_E_None
)
430 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
431 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
434 return osl_psz_removeDirectory( path
);
437 /*****************************************
438 * osl_psz_createDirectory
439 ****************************************/
441 static oslFileError
osl_psz_createDirectory( const sal_Char
* pszPath
)
444 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
446 nRet
= mkdir(pszPath
,mode
);
451 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
454 return osl_File_E_None
;
457 /*****************************************
458 * osl_psz_removeDirectory
459 ****************************************/
461 static oslFileError
osl_psz_removeDirectory( const sal_Char
* pszPath
)
465 nRet
= rmdir(pszPath
);
470 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
473 return osl_File_E_None
;
476 /****************************************************************************/
477 /* osl_createDirectoryPath */
478 /****************************************************************************/
480 static int path_make_parent(sal_Unicode
* path
)
482 int i
= rtl_ustr_lastIndexOfChar(path
, '/');
493 static int create_dir_with_callback(
494 sal_Unicode
* directory_path
,
495 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
498 int mode
= S_IRWXU
| S_IRWXG
| S_IRWXO
;
500 if (osl::mkdir(directory_path
, mode
) == 0)
502 if (aDirectoryCreationCallbackFunc
)
505 osl::FileBase::getFileURLFromSystemPath(directory_path
, url
);
506 aDirectoryCreationCallbackFunc(pData
, url
.pData
);
513 static oslFileError
create_dir_recursively_(
514 sal_Unicode
* dir_path
,
515 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
518 OSL_PRECOND((rtl_ustr_getLength(dir_path
) > 0) && ((dir_path
+ (rtl_ustr_getLength(dir_path
) - 1)) != (dir_path
+ rtl_ustr_lastIndexOfChar(dir_path
, '/'))), \
519 "Path must not end with a slash");
521 int native_err
= create_dir_with_callback(
522 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
525 return osl_File_E_None
;
527 if (native_err
!= ENOENT
)
528 return oslTranslateFileError(OSL_FET_ERROR
, native_err
);
530 // we step back until '/a_dir' at maximum because
531 // we should get an error unequal ENOENT when
532 // we try to create 'a_dir' at '/' and would so
534 int pos
= path_make_parent(dir_path
);
536 oslFileError osl_error
= create_dir_recursively_(
537 dir_path
, aDirectoryCreationCallbackFunc
, pData
);
539 if (osl_File_E_None
!= osl_error
)
544 return create_dir_recursively_(dir_path
, aDirectoryCreationCallbackFunc
, pData
);
547 oslFileError SAL_CALL
osl_createDirectoryPath(
548 rtl_uString
* aDirectoryUrl
,
549 oslDirectoryCreationCallbackFunc aDirectoryCreationCallbackFunc
,
552 if (aDirectoryUrl
== NULL
)
553 return osl_File_E_INVAL
;
555 rtl::OUString sys_path
;
556 oslFileError osl_error
= osl_getSystemPathFromFileURL_Ex(
557 aDirectoryUrl
, &sys_path
.pData
, sal_False
);
559 if (osl_error
!= osl_File_E_None
)
562 osl::systemPathRemoveSeparator(sys_path
);
564 // const_cast because sys_path is a local copy which we want to modify inplace instead of
565 // coyp it into another buffer on the heap again
566 return create_dir_recursively_(sys_path
.pData
->buffer
, aDirectoryCreationCallbackFunc
, pData
);
569 /******************************************************************************
571 * C-String Function Declarations
573 *****************************************************************************/
575 static oslFileError
osl_psz_removeFile(const sal_Char
* pszPath
);
576 static oslFileError
osl_psz_copyFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
577 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
580 /******************************************************************************
582 * Static Module Utility Function Declarations
584 *****************************************************************************/
586 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
);
587 static oslFileError
oslChangeFileModes(const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
);
588 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
);
589 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
);
590 static oslFileError
oslDoMoveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
);
592 /****************************************************************************/
594 /****************************************************************************/
596 oslFileError SAL_CALL
osl_moveFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
598 char srcPath
[PATH_MAX
];
599 char destPath
[PATH_MAX
];
602 OSL_ASSERT( ustrFileURL
);
603 OSL_ASSERT( ustrDestURL
);
605 /* convert source url to system path */
606 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
607 if( eRet
!= osl_File_E_None
)
610 /* convert destination url to system path */
611 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
612 if( eRet
!= osl_File_E_None
)
616 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
617 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
620 return oslDoMoveFile( srcPath
, destPath
);
623 /****************************************************************************/
625 /****************************************************************************/
627 oslFileError SAL_CALL
osl_copyFile( rtl_uString
* ustrFileURL
, rtl_uString
* ustrDestURL
)
629 char srcPath
[PATH_MAX
];
630 char destPath
[PATH_MAX
];
633 OSL_ASSERT( ustrFileURL
);
634 OSL_ASSERT( ustrDestURL
);
636 /* convert source url to system path */
637 eRet
= FileURLToPath( srcPath
, PATH_MAX
, ustrFileURL
);
638 if( eRet
!= osl_File_E_None
)
641 /* convert destination url to system path */
642 eRet
= FileURLToPath( destPath
, PATH_MAX
, ustrDestURL
);
643 if( eRet
!= osl_File_E_None
)
647 if ( macxp_resolveAlias( srcPath
, PATH_MAX
) != 0 || macxp_resolveAlias( destPath
, PATH_MAX
) != 0 )
648 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
651 return osl_psz_copyFile( srcPath
, destPath
);
654 /****************************************************************************/
656 /****************************************************************************/
658 oslFileError SAL_CALL
osl_removeFile( rtl_uString
* ustrFileURL
)
663 OSL_ASSERT( ustrFileURL
);
665 /* convert file url to system path */
666 eRet
= FileURLToPath( path
, PATH_MAX
, ustrFileURL
);
667 if( eRet
!= osl_File_E_None
)
671 if ( macxp_resolveAlias( path
, PATH_MAX
) != 0 )
672 return oslTranslateFileError( OSL_FET_ERROR
, errno
);
675 return osl_psz_removeFile( path
);
678 /******************************************************************************
682 *****************************************************************************/
684 /*****************************************
686 ****************************************/
688 static oslFileError
oslDoMoveFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
690 oslFileError tErr
=osl_File_E_invalidError
;
692 tErr
= osl_psz_moveFile(pszPath
,pszDestPath
);
693 if ( tErr
== osl_File_E_None
)
698 if ( tErr
!= osl_File_E_XDEV
)
703 tErr
=osl_psz_copyFile(pszPath
,pszDestPath
);
705 if ( tErr
!= osl_File_E_None
)
707 oslFileError tErrRemove
;
708 tErrRemove
=osl_psz_removeFile(pszDestPath
);
712 tErr
=osl_psz_removeFile(pszPath
);
717 /*****************************************
719 ****************************************/
720 static oslFileError
osl_psz_removeFile( const sal_Char
* pszPath
)
725 nRet
= lstat(pszPath
,&aStat
);
729 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
732 if ( S_ISDIR(aStat
.st_mode
) )
734 return osl_File_E_ISDIR
;
737 nRet
= unlink(pszPath
);
741 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
744 return osl_File_E_None
;
747 /*****************************************
749 ****************************************/
751 static oslFileError
osl_psz_moveFile(const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
756 nRet
= rename(pszPath
,pszDestPath
);
761 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
764 return osl_File_E_None
;
767 /*****************************************
769 ****************************************/
771 static oslFileError
osl_psz_copyFile( const sal_Char
* pszPath
, const sal_Char
* pszDestPath
)
779 struct stat aFileStat
;
780 oslFileError tErr
=osl_File_E_invalidError
;
781 size_t nSourceSize
=0;
782 int DestFileExists
=1;
784 /* mfe: does the source file really exists? */
785 nRet
= lstat(pszPath
,&aFileStat
);
790 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
793 /* mfe: we do only copy files here! */
794 if ( S_ISDIR(aFileStat
.st_mode
) )
796 return osl_File_E_ISDIR
;
799 nSourceSize
=(size_t)aFileStat
.st_size
;
800 nMode
=aFileStat
.st_mode
;
801 nAcTime
=aFileStat
.st_atime
;
802 nModTime
=aFileStat
.st_mtime
;
803 nUID
=aFileStat
.st_uid
;
804 nGID
=aFileStat
.st_gid
;
806 nRet
= stat(pszDestPath
,&aFileStat
);
811 if ( nRet
== ENOENT
)
815 /* return oslTranslateFileError(nRet);*/
818 /* mfe: the destination file must not be a directory! */
819 if ( nRet
== 0 && S_ISDIR(aFileStat
.st_mode
) )
821 return osl_File_E_ISDIR
;
825 /* mfe: file does not exists or is no dir */
828 tErr
= oslDoCopy(pszPath
,pszDestPath
,nMode
,nSourceSize
,DestFileExists
);
830 if ( tErr
!= osl_File_E_None
)
836 * mfe: ignore return code
837 * since only the success of the copy is
840 oslChangeFileModes(pszDestPath
,nMode
,nAcTime
,nModTime
,nUID
,nGID
);
846 /******************************************************************************
850 *****************************************************************************/
852 /*****************************************
854 ****************************************/
856 #define TMP_DEST_FILE_EXTENSION ".osl-tmp"
858 static oslFileError
oslDoCopy(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, mode_t nMode
, size_t nSourceSize
, int DestFileExists
)
861 sal_Char pszTmpDestFile
[PATH_MAX
];
862 size_t size_tmp_dest_buff
= sizeof(pszTmpDestFile
);
864 /* Quick fix for #106048, the whole copy file function seems
865 to be erroneous anyway and needs to be rewritten.
866 Besides osl_copyFile is currently not used from OO/SO code.
868 memset(pszTmpDestFile
, 0, size_tmp_dest_buff
);
870 if ( DestFileExists
)
872 strncpy(pszTmpDestFile
, pszDestFileName
, size_tmp_dest_buff
- 1);
874 if ((strlen(pszTmpDestFile
) + strlen(TMP_DEST_FILE_EXTENSION
)) >= size_tmp_dest_buff
)
875 return osl_File_E_NAMETOOLONG
;
877 strncat(pszTmpDestFile
, TMP_DEST_FILE_EXTENSION
, strlen(TMP_DEST_FILE_EXTENSION
));
879 /* FIXME: what if pszTmpDestFile already exists? */
880 /* with getcanonical??? */
881 nRet
=rename(pszDestFileName
,pszTmpDestFile
);
884 /* mfe: should be S_ISREG */
885 if ( !S_ISLNK(nMode
) )
887 /* copy SourceFile to DestFile */
888 nRet
= oslDoCopyFile(pszSourceFileName
,pszDestFileName
,nSourceSize
, nMode
);
890 /* mfe: OK redundant at the moment */
891 else if ( S_ISLNK(nMode
) )
893 nRet
= oslDoCopyLink(pszSourceFileName
,pszDestFileName
);
897 /* mfe: what to do here? */
901 if ( nRet
> 0 && DestFileExists
== 1 )
903 unlink(pszDestFileName
);
904 rename(pszTmpDestFile
,pszDestFileName
);
909 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
912 if ( DestFileExists
== 1 )
914 unlink(pszTmpDestFile
);
917 return osl_File_E_None
;
920 /*****************************************
922 ****************************************/
924 static oslFileError
oslChangeFileModes( const sal_Char
* pszFileName
, mode_t nMode
, time_t nAcTime
, time_t nModTime
, uid_t nUID
, gid_t nGID
)
927 struct utimbuf aTimeBuffer
;
929 nRet
= chmod(pszFileName
,nMode
);
933 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
936 aTimeBuffer
.actime
=nAcTime
;
937 aTimeBuffer
.modtime
=nModTime
;
938 nRet
=utime(pszFileName
,&aTimeBuffer
);
942 return oslTranslateFileError(OSL_FET_ERROR
, nRet
);
945 if ( nUID
!= getuid() )
950 nRet
=chown(pszFileName
,nUID
,nGID
);
955 /* mfe: do not return an error here! */
956 /* return oslTranslateFileError(nRet);*/
959 return osl_File_E_None
;
962 /*****************************************
964 ****************************************/
966 static int oslDoCopyLink(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
)
970 /* mfe: if dest file is symbolic link remove the link and place the file instead (hro says so) */
971 /* mfe: if source is a link copy the link and not the file it points to (hro says so) */
972 sal_Char pszLinkContent
[PATH_MAX
];
974 pszLinkContent
[0] = '\0';
976 nRet
= readlink(pszSourceFileName
,pszLinkContent
,PATH_MAX
);
984 pszLinkContent
[ nRet
] = 0;
986 nRet
= symlink(pszLinkContent
,pszDestFileName
);
997 /*****************************************
999 ****************************************/
1001 static int oslDoCopyFile(const sal_Char
* pszSourceFileName
, const sal_Char
* pszDestFileName
, size_t nSourceSize
, mode_t mode
)
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 size_t nWritten
= 0;
1024 size_t nRemains
= nSourceSize
;
1028 /* mmap has problems, try the direct streaming */
1029 char pBuffer
[0x8000];
1032 nRemains
= nSourceSize
;
1039 size_t nToRead
= std::min( (size_t)0x8000, nRemains
);
1040 nRead
= read( SourceFileFD
, pBuffer
, nToRead
);
1041 if ( (size_t)-1 != nRead
)
1042 nWritten
= write( DestFileFD
, pBuffer
, nRead
);
1044 if ( (size_t)-1 != nWritten
)
1045 nRemains
-= nWritten
;
1047 while( nRemains
&& (size_t)-1 != nRead
&& nRead
== nWritten
);
1058 close( SourceFileFD
);
1059 if ( close( DestFileFD
) == -1 && nRet
== 0 )