aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2019-11-09 11:56:54 -0800
committerZac Medico <zmedico@gentoo.org>2019-11-09 12:42:26 -0800
commitc6d2f47243bcedd4f491db5cbe316c2a261e4da3 (patch)
tree1d5d32ac30a13077b0c81cceca3e0449d8cd25c1
parentrepoman: Update for a repoman-2.3.18 release (diff)
downloadgentoo-portage-c6d2f47243bcedd4f491db5cbe316c2a261e4da3.tar.xz
gentoo-portage-c6d2f47243bcedd4f491db5cbe316c2a261e4da3.zip
FileCopier: native zero-copy and sparse file support
Use native copyfile for zero-copy and sparse file support, and copy permission bits like shutil.copy. Signed-off-by: Zac Medico <zmedico@gentoo.org>
-rw-r--r--lib/portage/tests/util/test_file_copier.py4
-rw-r--r--lib/portage/util/_async/FileCopier.py16
2 files changed, 17 insertions, 3 deletions
diff --git a/lib/portage/tests/util/test_file_copier.py b/lib/portage/tests/util/test_file_copier.py
index 01dfba494..3f1ec6b78 100644
--- a/lib/portage/tests/util/test_file_copier.py
+++ b/lib/portage/tests/util/test_file_copier.py
@@ -4,6 +4,7 @@
import errno
import os
import shutil
+import stat
import tempfile
from portage.tests import TestCase
@@ -22,8 +23,10 @@ class FileCopierTestCase(TestCase):
src_path = os.path.join(tempdir, 'src')
dest_path = os.path.join(tempdir, 'dest')
content = b'foo'
+ file_mode = 0o600
with open(src_path, 'wb') as f:
f.write(content)
+ os.chmod(src_path, file_mode)
copier = FileCopier(src_path=src_path, dest_path=dest_path, scheduler=loop)
copier.start()
loop.run_until_complete(copier.async_wait())
@@ -31,6 +34,7 @@ class FileCopierTestCase(TestCase):
copier.future.result()
with open(dest_path, 'rb') as f:
self.assertEqual(f.read(), content)
+ self.assertEqual(file_mode, stat.S_IMODE(os.stat(dest_path).st_mode))
# failure due to nonexistent src_path
src_path = os.path.join(tempdir, 'does-not-exist')
diff --git a/lib/portage/util/_async/FileCopier.py b/lib/portage/util/_async/FileCopier.py
index 3a0be4b63..d9077411d 100644
--- a/lib/portage/util/_async/FileCopier.py
+++ b/lib/portage/util/_async/FileCopier.py
@@ -1,7 +1,11 @@
# Copyright 2013-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from portage import shutil
+import os as _os
+
+from portage import _encodings, _unicode_encode
+from portage.util import apply_stat_permissions
+from portage.util.file_copy import copyfile
from portage.util.futures import asyncio
from portage.util.futures.executor.fork import ForkExecutor
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
@@ -14,6 +18,12 @@ class FileCopier(AsyncTaskFuture):
__slots__ = ('src_path', 'dest_path')
def _start(self):
- self.future = asyncio.ensure_future(self.scheduler.run_in_executor(ForkExecutor(loop=self.scheduler),
- shutil.copy, self.src_path, self.dest_path))
+ self.future = asyncio.ensure_future(self.scheduler.run_in_executor(
+ ForkExecutor(loop=self.scheduler), self._run))
super(FileCopier, self)._start()
+
+ def _run(self):
+ src_path = _unicode_encode(self.src_path, encoding=_encodings['fs'], errors='strict')
+ dest_path = _unicode_encode(self.dest_path, encoding=_encodings['fs'], errors='strict')
+ copyfile(src_path, dest_path)
+ apply_stat_permissions(dest_path, _os.stat(src_path))