Fix file copy on unix systems

This commit is contained in:
Wojtek Figat
2021-02-28 17:02:02 +01:00
parent b3fdc9eddd
commit 51e62c7e9d
2 changed files with 50 additions and 62 deletions

View File

@@ -317,64 +317,58 @@ bool AndroidFileSystem::CopyFile(const StringView& dst, const StringView& src)
{ {
const StringAsANSI<> srcANSI(*src, src.Length()); const StringAsANSI<> srcANSI(*src, src.Length());
const StringAsANSI<> dstANSI(*dst, dst.Length()); const StringAsANSI<> dstANSI(*dst, dst.Length());
const char* from = srcANSI.Get();
const char* to = dstANSI.Get();
int fd_to, fd_from; int srcFile, dstFile;
char buf[4096]; char buffer[4096];
ssize_t nread; ssize_t readSize;
int saved_errno; int cachedError;
fd_from = open(from, O_RDONLY); srcFile = open(srcANSI.Get(), O_RDONLY);
if (fd_from < 0) if (srcFile < 0)
return true; return true;
dstFile = open(dstANSI.Get(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666); if (dstFile < 0)
if (fd_to < 0)
goto out_error; goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0) while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0)
{ {
char* out_ptr = buf; char* ptr = buffer;
ssize_t nwritten; ssize_t writeSize;
do do
{ {
nwritten = write(fd_to, out_ptr, nread); writeSize = write(dstFile, ptr, readSize);
if (writeSize >= 0)
if (nwritten >= 0)
{ {
nread -= nwritten; readSize -= writeSize;
out_ptr += nwritten; ptr += writeSize;
} }
else if (errno != EINTR) else if (errno != EINTR)
{ {
goto out_error; goto out_error;
} }
} while (nread > 0); } while (readSize > 0);
} }
if (nread == 0) if (readSize == 0)
{ {
if (close(fd_to) < 0) if (close(dstFile) < 0)
{ {
fd_to = -1; dstFile = -1;
goto out_error; goto out_error;
} }
close(fd_from); close(srcFile);
// Success // Success
return false; return false;
} }
out_error: out_error:
saved_errno = errno; cachedError = errno;
close(srcFile);
close(fd_from); if (dstFile >= 0)
if (fd_to >= 0) close(dstFile);
close(fd_to); errno = cachedError;
errno = saved_errno;
return true; return true;
} }

View File

@@ -318,64 +318,58 @@ bool LinuxFileSystem::CopyFile(const StringView& dst, const StringView& src)
{ {
const StringAsANSI<> srcANSI(*src, src.Length()); const StringAsANSI<> srcANSI(*src, src.Length());
const StringAsANSI<> dstANSI(*dst, dst.Length()); const StringAsANSI<> dstANSI(*dst, dst.Length());
const char* from = srcANSI.Get();
const char* to = dstANSI.Get();
int fd_to, fd_from; int srcFile, dstFile;
char buf[4096]; char buffer[4096];
ssize_t nread; ssize_t readSize;
int saved_errno; int cachedError;
fd_from = open(from, O_RDONLY); srcFile = open(srcANSI.Get(), O_RDONLY);
if (fd_from < 0) if (srcFile < 0)
return true; return true;
dstFile = open(dstANSI.Get(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
fd_to = open(to, O_WRONLY | O_CREAT | O_EXCL, 0666); if (dstFile < 0)
if (fd_to < 0)
goto out_error; goto out_error;
while (nread = read(fd_from, buf, sizeof buf), nread > 0) while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0)
{ {
char* out_ptr = buf; char* ptr = buffer;
ssize_t nwritten; ssize_t writeSize;
do do
{ {
nwritten = write(fd_to, out_ptr, nread); writeSize = write(dstFile, ptr, readSize);
if (writeSize >= 0)
if (nwritten >= 0)
{ {
nread -= nwritten; readSize -= writeSize;
out_ptr += nwritten; ptr += writeSize;
} }
else if (errno != EINTR) else if (errno != EINTR)
{ {
goto out_error; goto out_error;
} }
} while (nread > 0); } while (readSize > 0);
} }
if (nread == 0) if (readSize == 0)
{ {
if (close(fd_to) < 0) if (close(dstFile) < 0)
{ {
fd_to = -1; dstFile = -1;
goto out_error; goto out_error;
} }
close(fd_from); close(srcFile);
// Success // Success
return false; return false;
} }
out_error: out_error:
saved_errno = errno; cachedError = errno;
close(srcFile);
close(fd_from); if (dstFile >= 0)
if (fd_to >= 0) close(dstFile);
close(fd_to); errno = cachedError;
errno = saved_errno;
return true; return true;
} }