Fix file copy on unix systems
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user