diff options
author | Zac Medico <zmedico@gentoo.org> | 2019-11-09 11:56:54 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2019-11-09 12:42:26 -0800 |
commit | c6d2f47243bcedd4f491db5cbe316c2a261e4da3 (patch) | |
tree | 1d5d32ac30a13077b0c81cceca3e0449d8cd25c1 | |
parent | repoman: Update for a repoman-2.3.18 release (diff) | |
download | gentoo-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.py | 4 | ||||
-rw-r--r-- | lib/portage/util/_async/FileCopier.py | 16 |
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)) |