Merge branch 'upstream-kwsys' into update-kwsys

This commit is contained in:
Brad King 2015-09-26 10:42:35 -04:00
commit 946e861519
2 changed files with 82 additions and 76 deletions

View File

@ -9,7 +9,6 @@
# resulting memory leaks are not logged by valgrind anyway. Therefore, we # resulting memory leaks are not logged by valgrind anyway. Therefore, we
# don't have to exclude it. # don't have to exclude it.
set(CTEST_CUSTOM_MEMCHECK_IGNORE list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
${CTEST_CUSTOM_MEMCHECK_IGNORE}
kwsys.testProcess-10 kwsys.testProcess-10
) )

View File

@ -2365,95 +2365,102 @@ bool SystemTools::CopyFileAlways(const std::string& source, const std::string& d
} }
mode_t perm = 0; mode_t perm = 0;
bool perms = SystemTools::GetPermissions(source, perm); bool perms = SystemTools::GetPermissions(source, perm);
const int bufferSize = 4096;
char buffer[bufferSize];
// If destination is a directory, try to create a file with the same
// name as the source in that directory.
std::string real_destination = destination; std::string real_destination = destination;
std::string destination_dir;
if(SystemTools::FileExists(destination) && if(SystemTools::FileIsDirectory(source))
SystemTools::FileIsDirectory(destination))
{ {
destination_dir = real_destination; SystemTools::MakeDirectory(destination);
SystemTools::ConvertToUnixSlashes(real_destination);
real_destination += '/';
std::string source_name = source;
real_destination += SystemTools::GetFilenameName(source_name);
} }
else else
{ {
destination_dir = SystemTools::GetFilenamePath(destination); const int bufferSize = 4096;
} char buffer[bufferSize];
// Create destination directory // If destination is a directory, try to create a file with the same
// name as the source in that directory.
SystemTools::MakeDirectory(destination_dir); std::string destination_dir;
if(SystemTools::FileExists(destination) &&
// Open files SystemTools::FileIsDirectory(destination))
#if defined(_WIN32)
kwsys::ifstream fin(Encoding::ToNarrow(
SystemTools::ConvertToWindowsExtendedPath(source)).c_str(),
std::ios::in | std::ios::binary);
#else
kwsys::ifstream fin(source.c_str(),
std::ios::in | std::ios::binary);
#endif
if(!fin)
{
return false;
}
// try and remove the destination file so that read only destination files
// can be written to.
// If the remove fails continue so that files in read only directories
// that do not allow file removal can be modified.
SystemTools::RemoveFile(real_destination);
#if defined(_WIN32)
kwsys::ofstream fout(Encoding::ToNarrow(
SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#else
kwsys::ofstream fout(real_destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#endif
if(!fout)
{
return false;
}
// This copy loop is very sensitive on certain platforms with
// slightly broken stream libraries (like HPUX). Normally, it is
// incorrect to not check the error condition on the fin.read()
// before using the data, but the fin.gcount() will be zero if an
// error occurred. Therefore, the loop should be safe everywhere.
while(fin)
{
fin.read(buffer, bufferSize);
if(fin.gcount())
{ {
fout.write(buffer, fin.gcount()); destination_dir = real_destination;
SystemTools::ConvertToUnixSlashes(real_destination);
real_destination += '/';
std::string source_name = source;
real_destination += SystemTools::GetFilenameName(source_name);
} }
else else
{ {
break; destination_dir = SystemTools::GetFilenamePath(destination);
} }
}
// Make sure the operating system has finished writing the file // Create destination directory
// before closing it. This will ensure the file is finished before
// the check below.
fout.flush();
fin.close(); SystemTools::MakeDirectory(destination_dir);
fout.close();
if(!fout) // Open files
{ #if defined(_WIN32)
return false; kwsys::ifstream fin(Encoding::ToNarrow(
SystemTools::ConvertToWindowsExtendedPath(source)).c_str(),
std::ios::in | std::ios::binary);
#else
kwsys::ifstream fin(source.c_str(),
std::ios::in | std::ios::binary);
#endif
if(!fin)
{
return false;
}
// try and remove the destination file so that read only destination files
// can be written to.
// If the remove fails continue so that files in read only directories
// that do not allow file removal can be modified.
SystemTools::RemoveFile(real_destination);
#if defined(_WIN32)
kwsys::ofstream fout(Encoding::ToNarrow(
SystemTools::ConvertToWindowsExtendedPath(real_destination)).c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#else
kwsys::ofstream fout(real_destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
#endif
if(!fout)
{
return false;
}
// This copy loop is very sensitive on certain platforms with
// slightly broken stream libraries (like HPUX). Normally, it is
// incorrect to not check the error condition on the fin.read()
// before using the data, but the fin.gcount() will be zero if an
// error occurred. Therefore, the loop should be safe everywhere.
while(fin)
{
fin.read(buffer, bufferSize);
if(fin.gcount())
{
fout.write(buffer, fin.gcount());
}
else
{
break;
}
}
// Make sure the operating system has finished writing the file
// before closing it. This will ensure the file is finished before
// the check below.
fout.flush();
fin.close();
fout.close();
if(!fout)
{
return false;
}
} }
if ( perms ) if ( perms )
{ {