[Common] Add copy file for linux

This commit is contained in:
zilmar 2016-08-03 21:30:46 +10:00
parent c11b874b63
commit b79c995bfb
1 changed files with 131 additions and 25 deletions

View File

@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#endif
#include "Platform.h"
@ -131,7 +132,7 @@ CPath::CPath(const char * lpszPath)
CPath::CPath(const char * lpszPath, const char * NameExten)
{
WriteTrace(TracePath, TraceDebug, "Start (lpszPath: \"%s\" NameExten: \"%s\")",lpszPath ? lpszPath: "(null)",NameExten ? NameExten : "(null)");
WriteTrace(TracePath, TraceDebug, "Start (lpszPath: \"%s\" NameExten: \"%s\")", lpszPath ? lpszPath : "(null)", NameExten ? NameExten : "(null)");
Init();
#ifdef _WIN32
SetDriveDirectory(lpszPath);
@ -139,7 +140,7 @@ CPath::CPath(const char * lpszPath, const char * NameExten)
SetDirectory(lpszPath);
#endif
SetNameExtension(NameExten);
WriteTrace(TracePath, TraceDebug, "Done (m_strPath: \"%s\")",m_strPath.c_str());
WriteTrace(TracePath, TraceDebug, "Done (m_strPath: \"%s\")", m_strPath.c_str());
}
//-------------------------------------------------------------
@ -939,6 +940,7 @@ bool CPath::IsDirectory() const
//-------------------------------------------------------------
bool CPath::DirectoryExists() const
{
WriteTrace(TracePath, TraceDebug, "m_strPath = %s",m_strPath.c_str());
#ifdef _WIN32
// Create test path
CPath TestPath(m_strPath.c_str());
@ -949,18 +951,24 @@ bool CPath::DirectoryExists() const
WIN32_FIND_DATA FindData;
HANDLE hFindFile = FindFirstFile((const char *)TestPath, &FindData); // Find anything
bool bGotFile = (hFindFile != INVALID_HANDLE_VALUE);
bool res = (hFindFile != INVALID_HANDLE_VALUE);
if (hFindFile != NULL) // Make sure we close the search
{
FindClose(hFindFile);
}
return bGotFile;
#else
std::string PathText;
GetDirectory(PathText);
StripTrailingBackslash(PathText);
WriteTrace(TracePath, TraceDebug, "Checking if directory \"%s\" exists",PathText.c_str());
struct stat fileinfo;
return stat(m_strPath.c_str(), &fileinfo) == 0 && S_ISDIR(fileinfo.st_mode);
bool res = stat(PathText.c_str(), &fileinfo) == 0 && S_ISDIR(fileinfo.st_mode);
#endif
WriteTrace(TracePath, TraceDebug, "Exist = %s",res ? "True" : "False");
return res;
}
//-------------------------------------------------------------
@ -1009,7 +1017,7 @@ bool CPath::Delete(bool bEvenIfReadOnly) const
SetFileAttributes(m_strPath.c_str(), FILE_ATTRIBUTE_NORMAL);
return DeleteFile(m_strPath.c_str()) != 0;
#else
return false;
return unlink(m_strPath.c_str()) == 0;
#endif
}
@ -1022,6 +1030,11 @@ bool CPath::Delete(bool bEvenIfReadOnly) const
//-------------------------------------------------------------
bool CPath::CopyTo(const char * lpcszTargetFile, bool bOverwrite)
{
if (lpcszTargetFile == NULL)
{
return false;
}
WriteTrace(TracePath, TraceDebug, "copy \"%s\" to \"%s\"",m_strPath.c_str(),lpcszTargetFile);
#ifdef _WIN32
// Check if the target file exists
CPath TargetFile(lpcszTargetFile);
@ -1045,7 +1058,89 @@ bool CPath::CopyTo(const char * lpcszTargetFile, bool bOverwrite)
// the source after copying
return CopyFile(m_strPath.c_str(), lpcszTargetFile, !bOverwrite) != 0;
#else
return false;
bool res = true;
WriteTrace(TracePath, TraceDebug, "opening \"%s\" for reading",m_strPath.c_str());
FILE * infile = fopen(m_strPath.c_str(), "rb");
if(infile == NULL)
{
WriteTrace(TracePath, TraceWarning, "failed to open m_strPath = %s",m_strPath.c_str());
res = false;
}
else
{
WriteTrace(TracePath, TraceDebug, "opened \"%s\"",m_strPath.c_str());
}
FILE * outfile = NULL;
if (res)
{
WriteTrace(TracePath, TraceDebug, "opening \"%s\" for writing",lpcszTargetFile);
outfile = fopen(lpcszTargetFile, "wb");
if (outfile == NULL)
{
WriteTrace(TracePath, TraceWarning, "failed to open m_strPath = %s errno=%d",lpcszTargetFile, errno);
res = false;
}
else
{
WriteTrace(TracePath, TraceDebug, "opened \"%s\"",lpcszTargetFile);
}
}
if (res)
{
WriteTrace(TracePath, TraceDebug, "copying data");
while (!feof(infile))
{
char buffer[1024];
size_t bytes = fread(buffer, 1, sizeof(buffer), infile);
if (ferror(infile))
{
WriteTrace(TracePath, TraceWarning, "failed to read from %s", m_strPath.c_str());
res = false;
break;
}
if (!feof(infile))
{
size_t written = fwrite(buffer, 1, sizeof(buffer), outfile);
}
if (ferror(outfile))
{
WriteTrace(TracePath, TraceWarning, "failed to write to %s, ferror(outfile) = %X", lpcszTargetFile, ferror(outfile));
res = false;
break;
}
}
}
struct stat ts;
if (res)
{
if (fstat(fileno(infile), &ts) != 0)
{
WriteTrace(TracePath, TraceWarning, "fstat failed on %s, ferror(infile) = %X", m_strPath.c_str(), ferror(infile));
res = false;
}
}
if (res)
{
if (fchmod(fileno(outfile),ts.st_mode) != 0)
{
WriteTrace(TracePath, TraceWarning, "fchmod failed on %s, errno = %X", lpcszTargetFile, errno);
res = false;
}
}
if (infile != NULL)
{
fclose(infile);
}
if (outfile != NULL)
{
fclose(outfile);
}
WriteTrace(TracePath, TraceDebug, "Done, res: %s",res ? "true" : "false");
return res;
#endif
}
@ -1231,7 +1326,7 @@ bool CPath::FindNext()
}
#else
dirent* pEntry;
while ( pEntry = readdir ((DIR*)m_OpenedDir))
while (pEntry = readdir((DIR*)m_OpenedDir))
{
uint32_t dwFileAttributes = pEntry->d_type == DT_DIR ? FIND_ATTRIBUTE_SUBDIR : FIND_ATTRIBUTE_FILES;
@ -1270,7 +1365,7 @@ bool CPath::FindNext()
UpDirectory();
}
SetNameExtension(pEntry->d_name);
WriteTrace(TracePath, TraceVerbose, "m_strPath: %s pEntry->d_name: %s", m_strPath.c_str(),pEntry->d_name);
WriteTrace(TracePath, TraceVerbose, "m_strPath: %s pEntry->d_name: %s", m_strPath.c_str(), pEntry->d_name);
}
if ((FIND_ATTRIBUTE_SUBDIR & dwFileAttributes) == FIND_ATTRIBUTE_SUBDIR)
{
@ -1309,24 +1404,34 @@ bool CPath::ChangeDirectory()
//-------------------------------------------------------------
bool CPath::DirectoryCreate(bool bCreateIntermediates /*= TRUE*/)
{
WriteTrace(TracePath, TraceDebug, "m_strPath = %s bCreateIntermediates = %s",m_strPath.c_str(),bCreateIntermediates ? "true" : "false");
std::string PathText;
bool bSuccess;
if (DirectoryExists())
{
WriteTrace(TracePath, TraceDebug, "Directory already exists, res = true");
return true;
}
#ifdef _WIN32
GetDriveDirectory(PathText);
StripTrailingBackslash(PathText);
WriteTrace(TracePath, TraceDebug, "Create %s",PathText.c_str());
bSuccess = ::CreateDirectory(PathText.c_str(), NULL) != 0;
#else
GetDirectory(PathText);
StripTrailingBackslash(PathText);
if (DirectoryExists())
WriteTrace(TracePath, TraceDebug, "Create %s",PathText.c_str());
bSuccess = mkdir(PathText.c_str(), S_IRWXU) == 0;
if (!bSuccess)
{
return true;
WriteTrace(TracePath, TraceWarning, "failed to create \"%s\" errno: %d",PathText.c_str(), errno);
}
bSuccess = mkdir(PathText.c_str(), 0700) == 0;
#endif
if (!bSuccess && bCreateIntermediates)
{
WriteTrace(TracePath, TraceDebug, "failed creating intermediates");
std::string::size_type nDelimiter = PathText.rfind(DIRECTORY_DELIMITER);
if (nDelimiter == std::string::npos)
{
@ -1338,6 +1443,7 @@ bool CPath::DirectoryCreate(bool bCreateIntermediates /*= TRUE*/)
return SubPath.DirectoryCreate() ? DirectoryCreate(false) : false;
}
WriteTrace(TracePath, TraceDebug, "res = %s",bSuccess ? "true" : "false");
return bSuccess;
}