Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 600626

Summary: sys-apps/portage: apply_recursive_permissions function could use os.fwalk to avoid "OSError: [Errno 63] File name too long"
Product: Portage Development Reporter: Zac Medico <zmedico>
Component: CoreAssignee: Portage team <dev-portage>
Status: CONFIRMED ---    
Severity: normal CC: kingjon3377
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: All   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=600576
https://bugs.gentoo.org/show_bug.cgi?id=598806
Whiteboard:
Package list:
Runtime testing required: ---

Description Zac Medico gentoo-dev 2016-11-23 21:35:12 UTC
As reported in bug 600576, it's possible for apply_recursive_permissions to raise "OSError: [Errno 63] File name too long" if extremely long paths are nested within a directory structure.

It seems that portage can be fixed to handle this by making the apply_recursive_permissions function use os.fwalk and similar functions that use file descriptors instead of paths. I've tested with python-3.5.2, and os.fwalk successfully traversed all of /var/tmp/portage/app-arch/libarchive-3.2.2/temp. It worked with a string argument, but failed with a bytes argument as reported in http://bugs.python.org/issue28682:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.5/os.py", line 519, in fwalk
    yield from _fwalk(topfd, top, topdown, onerror, follow_symlinks)
  File "/usr/lib64/python3.5/os.py", line 562, in _fwalk
    dirpath = path.join(toppath, name)
  File "/usr/lib64/python3.5/posixpath.py", line 89, in join
    genericpath._check_arg_types('join', a, *p)
  File "/usr/lib64/python3.5/genericpath.py", line 145, in _check_arg_types
    raise TypeError("Can't mix strings and bytes in path components") from None
TypeError: Can't mix strings and bytes in path components

If we can't use a bytes argument, then it's going to fail if any of the paths aren't encoded with the encoding that python expects.