fix symlink item fs size computation

a symlink has a 'source' attribute, so it was confused with a hardlink
slave here. see also issue #2343.

also, a symlink's fs size is defined as the length of the target path.
This commit is contained in:
Thomas Waldmann 2017-03-26 16:05:22 +02:00
parent 4fe9d067da
commit 90dd0e8eca
3 changed files with 9 additions and 2 deletions

View File

@ -1,3 +1,4 @@
import stat
from collections import namedtuple
from .constants import ITEM_KEYS
@ -193,6 +194,10 @@ class Item(PropDict):
raise AttributeError
size = getattr(self, attr)
except AttributeError:
if stat.S_ISLNK(self.mode):
# get out of here quickly. symlinks have no own chunks, their fs size is the length of the target name.
# also, there is the dual-use issue of .source (#2343), so don't confuse it with a hardlink slave.
return len(self.source)
# no precomputed (c)size value available, compute it:
try:
chunks = getattr(self, 'chunks')

View File

@ -1748,6 +1748,8 @@ class ArchiverTestCase(ArchiverTestCaseBase):
out_fn = os.path.join(mountpoint, 'input', 'link1')
sti = os.stat(in_fn, follow_symlinks=False)
sto = os.stat(out_fn, follow_symlinks=False)
assert sti.st_size == len('somewhere')
assert sto.st_size == len('somewhere')
assert stat.S_ISLNK(sti.st_mode)
assert stat.S_ISLNK(sto.st_mode)
assert os.readlink(in_fn) == os.readlink(out_fn)

View File

@ -149,7 +149,7 @@ def test_unknown_property():
def test_item_file_size():
item = Item(chunks=[
item = Item(mode=0o100666, chunks=[
ChunkListEntry(csize=1, size=1000, id=None),
ChunkListEntry(csize=1, size=2000, id=None),
])
@ -157,5 +157,5 @@ def test_item_file_size():
def test_item_file_size_no_chunks():
item = Item()
item = Item(mode=0o100666)
assert item.get_size() == 0