diff --git a/src/pal/src/cruntime/filecrt.cpp b/src/pal/src/cruntime/filecrt.cpp index e901a0d40cb0..48079b309c70 100644 --- a/src/pal/src/cruntime/filecrt.cpp +++ b/src/pal/src/cruntime/filecrt.cpp @@ -311,34 +311,6 @@ CorUnix::InternalOpen( } -/*++ -InternalDeleteFile - -Wrapper that does the same thing as unlink, except that -it uses the SYS_Delete system call present on Apple instead of unlink. - -Input parameters: - -szPath = a symbolic link or a hard link to a file - -Return value: - Returns 0 on success and -1 on failure ---*/ -int -CorUnix::InternalDeleteFile( - const char *szPath - ) -{ - int nRet = -1; -#if defined(__APPLE__) && defined(SYS_delete) - nRet = syscall(SYS_delete, szPath); -#else - nRet = unlink(szPath); -#endif // defined(__APPLE__) && defined(SYS_delete) - return nRet; -} - - /*++ PAL_rename diff --git a/src/pal/src/file/directory.cpp b/src/pal/src/file/directory.cpp index 1d4dd430dfd3..8e54f94d6965 100644 --- a/src/pal/src/file/directory.cpp +++ b/src/pal/src/file/directory.cpp @@ -134,12 +134,6 @@ RemoveDirectoryHelper ( FILEDosToUnixPathA( lpPathName ); - if ( !FILEGetFileNameFromSymLink(lpPathName)) - { - FILEGetProperNotFoundError( lpPathName, dwLastError ); - goto done; - } - if ( rmdir(lpPathName) != 0 ) { TRACE("Removal of directory [%s] was unsuccessful, errno = %d.\n", @@ -177,7 +171,6 @@ RemoveDirectoryHelper ( bRet = TRUE; } -done: return bRet; } diff --git a/src/pal/src/file/file.cpp b/src/pal/src/file/file.cpp index 6cb4a9392ddf..2a0d55b82de6 100644 --- a/src/pal/src/file/file.cpp +++ b/src/pal/src/file/file.cpp @@ -1094,7 +1094,6 @@ DeleteFileA( IN LPCSTR lpFileName) { PAL_ERROR palError = NO_ERROR; - DWORD dwShareMode = SHARE_MODE_NOT_INITALIZED; CPalThread *pThread; int result; BOOL bRet = FALSE; @@ -1115,12 +1114,6 @@ DeleteFileA( FILEDosToUnixPathA( lpunixFileName ); - if ( !FILEGetFileNameFromSymLink(lpunixFileName)) - { - dwLastError = FILEGetLastErrorFromErrnoAndFilename(lpunixFileName); - goto done; - } - // Compute the absolute pathname to the file. This pathname is used // to determine if two file names represent the same file. palError = InternalCanonicalizeRealPath(lpunixFileName, lpFullunixFileName); @@ -1133,31 +1126,9 @@ DeleteFileA( } } - palError = g_pFileLockManager->GetFileShareModeForFile(lpFullunixFileName, &dwShareMode); - - // Use unlink if we succesfully found the file to be opened with - // a FILE_SHARE_DELETE mode. - // Note that there is a window here where a race condition can occur: - // the check for the sharing mode and the unlink are two separate actions - // (not a single atomic action). So it's possible that between the check - // happening and the unlink happening, the file may have been closed. If - // it is just closed and not re-opened, no problems. - // If it is closed and re-opened without any sharing, we should be calling - // InternalDelete instead which would have failed. - // Instead, we call unlink which will succeed. - - if (palError == NO_ERROR && - dwShareMode != SHARE_MODE_NOT_INITALIZED && - (dwShareMode & FILE_SHARE_DELETE) != 0) - { - result = unlink( lpFullunixFileName ); - } - else - { - result = InternalDeleteFile( lpFullunixFileName ); - } + result = unlink( lpFullunixFileName ); - if ( result < 0 ) + if (result < 0) { TRACE("unlink returns %d\n", result); dwLastError = FILEGetLastErrorFromErrnoAndFilename(lpFullunixFileName); @@ -1172,12 +1143,12 @@ DeleteFileA( { pThread->SetLastError( dwLastError ); } + LOGEXIT("DeleteFileA returns BOOL %d\n", bRet); PERF_EXIT(DeleteFileA); return bRet; } - /*++ Function: DeleteFileW @@ -1350,15 +1321,8 @@ MoveFileExA( dwLastError = ERROR_NOT_ENOUGH_MEMORY; goto done; } - - FILEDosToUnixPathA( dest ); - if ( !FILEGetFileNameFromSymLink(source)) - { - TRACE( "FILEGetFileNameFromSymLink failed\n" ); - dwLastError = FILEGetLastErrorFromErrnoAndFilename(source); - goto done; - } + FILEDosToUnixPathA( dest ); if ( !(dwFlags & MOVEFILE_REPLACE_EXISTING) ) { @@ -1440,9 +1404,9 @@ MoveFileExA( case ENOENT: { struct stat buf; - if (stat(source, &buf) == -1) + if (lstat(source, &buf) == -1) { - FILEGetProperNotFoundError(dest, &dwLastError); + FILEGetProperNotFoundError(source, &dwLastError); } else { @@ -4754,7 +4718,6 @@ BOOL FILEInitStdHandles(void) return FALSE; } - /*++ FILECleanupStdHandles @@ -4794,44 +4757,6 @@ void FILECleanupStdHandles(void) } } - -/*++ -FILEGetFileNameFromSymLink - -Input parameters: - -source = path to the file on input, path to the file with all - symbolic links traversed on return - -Return value: - TRUE on success, FALSE on failure ---*/ -BOOL FILEGetFileNameFromSymLink(PathCharString& source) -{ - int ret; - PathCharString sLinkDataString; - struct stat sb; - - do - { - if (lstat(source, &sb) == -1) - { - break; - } - - char * sLinkData = sLinkDataString.OpenStringBuffer(sb.st_size); - ret = readlink(source, sLinkData, sb.st_size); - if (ret > 0) - { - sLinkDataString.CloseBuffer(ret); - source.Set(sLinkDataString); - } - } while (ret > 0); - - return (errno == EINVAL); -} - - /*++ Function: GetFileInformationByHandle diff --git a/src/pal/src/include/pal/file.h b/src/pal/src/include/pal/file.h index 32174cbc41c5..93c8ad9784b0 100644 --- a/src/pal/src/include/pal/file.h +++ b/src/pal/src/include/pal/file.h @@ -158,20 +158,6 @@ Close promary handles for stdin, stdout and stderr --*/ void FILECleanupStdHandles(void); -/*++ -FILEGetFileNameFromSymLink - -Input paramters: - -source = path to the file on input, path to the file with all - symbolic links traversed on return - - -Return value: - TRUE on success, FALSE on failure ---*/ -BOOL FILEGetFileNameFromSymLink(PathCharString& source); - /*++ Function : diff --git a/src/pal/src/include/pal/file.hpp b/src/pal/src/include/pal/file.hpp index cc9eb1ef3c0c..5acccb0a242a 100644 --- a/src/pal/src/include/pal/file.hpp +++ b/src/pal/src/include/pal/file.hpp @@ -191,15 +191,6 @@ namespace CorUnix char *szNameTemplate ); - /*++ - InternalDeleteFile - Wraps SYS_delete - --*/ - int - InternalDeleteFile( - const char *szPath - ); - /*++ InternalFgets Wraps fgets @@ -355,20 +346,6 @@ Close primary handles for stdin, stdout and stderr --*/ void FILECleanupStdHandles(void); -/*++ -FILEGetFileNameFromSymLink - -Input paramters: - -source = path to the file on input, path to the file with all - symbolic links traversed on return - - -Return value: - TRUE on success, FALSE on failure -BOOL FILEGetFileNameFromSymLink(PathCharString& source); ---*/ - /*++ Function : diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt index 3efdbbb411c2..b979c206b2b8 100644 --- a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt +++ b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - DeleteFileA.c + DeleteFileA.cpp ) add_executable(paltest_deletefilea_test1 diff --git a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.c b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp similarity index 80% rename from src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.c rename to src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp index da1738ab3f19..a8eb71decb5f 100644 --- a/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.c +++ b/src/pal/tests/palsuite/file_io/DeleteFileA/test1/DeleteFileA.cpp @@ -19,8 +19,12 @@ // delete a file without proper permissions // +#define PAL_STDCPP_COMPAT #include +#undef PAL_STDCPP_COMPAT +#include +#include int __cdecl main(int argc, char *argv[]) @@ -35,7 +39,7 @@ int __cdecl main(int argc, char *argv[]) } // - // deleting an existing file + // create a test file // tempFile = fopen("testFile01.txt", "w"); if (tempFile == NULL) @@ -51,6 +55,34 @@ int __cdecl main(int argc, char *argv[]) " testFile01.txt\"\n"); } + // + // delete a symlink to an existing file + // + if (symlink("testFile01.txt", "testFile01_symlink") != 0) + { + Fail("DeleteFileA: ERROR: Failed to create a symlink to testFile01.txt.\n"); + } + + bRc = DeleteFileA("testFile01_symlink"); + if (bRc != TRUE) + { + Fail ("DeleteFileA: ERROR: Couldn't delete symlink!\n Error is %d\n", GetLastError()); + } + + struct stat statBuffer; + if (lstat("testFile01.txt", &statBuffer) != 0) + { + Fail("DeleteFileA: ERROR: Deleting a symlink deleted the file it was pointing to.\n"); + } + + if (lstat("testFile01_symlink", &statBuffer) == 0) + { + Fail("DeleteFileA: ERROR: Failed to delete a symlink.\n"); + } + + // + // deleting an existing file + // bRc = DeleteFileA("testFile01.txt"); if (bRc != TRUE) { diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt index 3935d0482e50..7a8d1c9d57e7 100644 --- a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt +++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(SOURCES - RemoveDirectoryA.c + RemoveDirectoryA.cpp ) add_executable(paltest_removedirectorya_test1 diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.c b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp similarity index 66% rename from src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.c rename to src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp index 956dc0f349cd..167af58163bd 100644 --- a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.c +++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp @@ -12,7 +12,11 @@ **===================================================================*/ +#define PAL_STDCPP_COMPAT #include +#undef PAL_STDCPP_COMPAT + +#include int __cdecl main(int argc, char *argv[]) @@ -36,38 +40,57 @@ int __cdecl main(int argc, char *argv[]) bRc = RemoveDirectoryA(NULL); if (bRc != FALSE) { - Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove a" + Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove a" " NULL directory name\n", GetLastError()); } /* * remove a directory that does not exist */ - szTemp = (char *) malloc (sizeof("test_directory")); + szTemp = (char *) malloc (sizeof("test_directory")); sprintf(szTemp, "test_directory"); - bRc = RemoveDirectoryA(szTemp); + bRc = RemoveDirectoryA(szTemp); if (bRc != FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove" + Fail("Error[%ul]:RemoveDirectoryA: Failed since it was able to remove" " the non-existant directory \"test_directory\"\n", GetLastError()); } /* - * remove a directory that exists + * remove a symlink to a directory */ bRc = CreateDirectoryA(szTemp, NULL); if (bRc != TRUE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " - "\"test_directory\" when it exists already.\n", GetLastError()); + Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " + "\"test_directory\".\n", GetLastError()); + } + + char *szSymlinkName = (char *) malloc (sizeof("test_directory_symlink")); + sprintf(szSymlinkName, "test_directory_symlink"); + if (symlink(szTemp, szSymlinkName) != 0) + { + Fail("Error:RemoveDirectoryA: Failed to create a symlink to the directory \"test_directory\".\n"); + } + + bRc = RemoveDirectoryA(szSymlinkName); + if (bRc != FALSE) + { + Fail("Error:RemoveDirectoryA: RemoveDirectoryA should return FALSE when passed a symlink.\n"); } + + unlink(szSymlinkName); + + /* + * remove a directory that exists + */ bRc = RemoveDirectoryA(szTemp); if (bRc == FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryW: Failed to remove the directory " + Fail("Error[%ul]:RemoveDirectoryW: Failed to remove the directory " "\"test_directory\"\n", GetLastError()); } @@ -75,7 +98,7 @@ int __cdecl main(int argc, char *argv[]) if( -1 != GetFileAttributesA(szTemp) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " + Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " "the removed directory\n" , GetLastError()); } free(szTemp); @@ -86,21 +109,21 @@ int __cdecl main(int argc, char *argv[]) curDirLen = GetCurrentDirectoryA(0, NULL) + 1; memset(szDirName, 0, 252); memset(szDirName, 'a', 245 - curDirLen); - szTemp = (char *) malloc (sizeof(szDirName)); - szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); + szTemp = (char *) malloc (sizeof(szDirName)); + szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); bRc = CreateDirectoryA(szTemp, NULL); if (bRc == FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to create a directory name " + Fail("Error[%ul]:RemoveDirectoryA: Failed to create a directory name " "245 chars long\n" , GetLastError()); } bRc = RemoveDirectoryA(szTemp); if (bRc == FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to remove a 245 char " + Fail("Error[%ul]:RemoveDirectoryA: Failed to remove a 245 char " "long directory\n", GetLastError()); } @@ -108,7 +131,7 @@ int __cdecl main(int argc, char *argv[]) if( -1 != GetFileAttributesA(szTemp) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " + Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " "the removed directory\n", GetLastError()); } free(szTemp); @@ -118,27 +141,27 @@ int __cdecl main(int argc, char *argv[]) */ memset(szDirName, 0, 252); sprintf(szDirName, ".dotDirectory"); - szTemp = (char *) malloc (sizeof(szDirName)); - szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); + szTemp = (char *) malloc (sizeof(szDirName)); + szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); - bRc = CreateDirectoryA(szTemp, NULL); + bRc = CreateDirectoryA(szTemp, NULL); if (bRc == FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to create \"%s\"\n", GetLastError(), szDirName); + Fail("Error[%ul]:RemoveDirectoryA: Failed to create \"%s\"\n", GetLastError(), szDirName); } bRc = RemoveDirectoryA(szTemp); if (bRc == FALSE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to remove \"%s\"\n", GetLastError(), szDirName); + Fail("Error[%ul]:RemoveDirectoryA: Failed to remove \"%s\"\n", GetLastError(), szDirName); } /* Make sure the directory was removed */ if( -1 != GetFileAttributesA(szTemp) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " + Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " "the removed directory\n", GetLastError()); } free(szTemp); @@ -148,14 +171,14 @@ int __cdecl main(int argc, char *argv[]) */ memset(szDirName, 0, 252); sprintf(szDirName, "removedirectoryw.c"); - szTemp = (char *) malloc (sizeof(szDirName)); - szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); + szTemp = (char *) malloc (sizeof(szDirName)); + szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); bRc = RemoveDirectoryA(szTemp); free(szTemp); if (bRc != FALSE) { - Fail("Error[%ul]:RemoveDirectoryA: should have failed when " + Fail("Error[%ul]:RemoveDirectoryA: should have failed when " "called with a valid file name", GetLastError() ); } @@ -178,21 +201,21 @@ int __cdecl main(int argc, char *argv[]) } /* Create non_empty_dir */ - sprintf( szDirName, "non_empty_dir"); - szTemp = (char *) malloc (sizeof(szDirName)); - szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); + sprintf( szDirName, "non_empty_dir"); + szTemp = (char *) malloc (sizeof(szDirName)); + szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1); bRc = CreateDirectoryA(szTemp, NULL); if (bRc != TRUE) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " + Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " "\"non_empty_dir\" when it exists already.\n", GetLastError()); } if( 0 == SetCurrentDirectoryA(szTemp) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " + Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError()); } @@ -201,20 +224,20 @@ int __cdecl main(int argc, char *argv[]) if( 0 == GetCurrentDirectoryA(MAX_PATH, szwSubDir) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to get current directory " + Fail("Error[%ul]:RemoveDirectoryA: Failed to get current directory " "with GetCurrentDirectoryA.\n", GetLastError()); } /* Create sub_dir */ - sprintf (szDirName, "sub_dir"); - szTemp2 = (char *) malloc (sizeof(szDirName)); - szTemp2 = strncpy(szTemp2, szDirName, strlen(szDirName) + 1); + sprintf (szDirName, "sub_dir"); + szTemp2 = (char *) malloc (sizeof(szDirName)); + szTemp2 = strncpy(szTemp2, szDirName, strlen(szDirName) + 1); bRc = CreateDirectoryA(szTemp2, NULL); if (bRc != TRUE) { free(szTemp); free(szTemp2); - Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " + Fail("Error[%ul]:RemoveDirectoryA: Failed to create the directory " "\"sub_dir\" when it exists already.\n", GetLastError()); } @@ -223,7 +246,7 @@ int __cdecl main(int argc, char *argv[]) { free(szTemp); free(szTemp2); - Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " + Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError()); } @@ -233,7 +256,7 @@ int __cdecl main(int argc, char *argv[]) { free(szTemp); free(szTemp2); - Fail("Error[%ul]:RemoveDirectoryA: shouldn't have been able to remove " + Fail("Error[%ul]:RemoveDirectoryA: shouldn't have been able to remove " "the non empty directory \"non_empty_dir\"\n", GetLastError()); } @@ -242,7 +265,7 @@ int __cdecl main(int argc, char *argv[]) { free(szTemp); free(szTemp2); - Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " + Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " "\"non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError()); } @@ -251,7 +274,7 @@ int __cdecl main(int argc, char *argv[]) { free(szTemp); free(szTemp2); - Fail("Error[%ul]:RemoveDirectoryA: unable to remove " + Fail("Error[%ul]:RemoveDirectoryA: unable to remove " "directory \"sub_dir\" \n", GetLastError()); } @@ -267,7 +290,7 @@ int __cdecl main(int argc, char *argv[]) if( 0 == SetCurrentDirectoryA(szwCurrentDir) ) { free(szTemp); - Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " + Fail("Error[%ul]:RemoveDirectoryA: Failed to set current directory to " "\"..\non_empty_dir\" with SetCurrentDirectoryA.\n", GetLastError()); } bRc = RemoveDirectoryA(szTemp); @@ -281,7 +304,7 @@ int __cdecl main(int argc, char *argv[]) /* Make sure the directory was removed */ if( -1 != GetFileAttributesA(szTemp) ) { - Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " + Fail("Error[%ul]:RemoveDirectoryA: Able to get the attributes of " "the removed directory\n", GetLastError()); } free(szTemp);