getconfig: handle recursive PermissionDenied
authorZac Medico <zmedico@gentoo.org>
Wed, 27 Mar 2013 15:02:12 +0000 (08:02 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 27 Mar 2013 15:02:12 +0000 (08:02 -0700)
pym/portage/util/__init__.py

index 59d4fa4c46f931c60134fceba6159acaeee03991..7c16b7bae67a60a18e5e425cc873a04cbe345d7f 100644 (file)
@@ -564,6 +564,18 @@ _invalid_var_name_re = re.compile(r'^\d|\W')
 def getconfig(mycfg, tolerant=False, allow_sourcing=False, expand=True,
        recursive=False):
 
+       is_dir = False
+       if recursive:
+               try:
+                       is_dir = stat.S_ISDIR(os.stat(mycfg).st_mode)
+               except OSError as e:
+                       if e.errno == PermissionDenied.errno:
+                               raise PermissionDenied(mycfg)
+                       elif e.errno in (errno.ENOENT, errno.ESTALE, errno.EISDIR):
+                               return None
+                       else:
+                               raise
+
        if isinstance(expand, dict):
                # Some existing variable definitions have been
                # passed in, for use in substitutions.
@@ -573,11 +585,15 @@ def getconfig(mycfg, tolerant=False, allow_sourcing=False, expand=True,
                expand_map = {}
        mykeys = {}
 
-       if recursive and os.path.isdir(mycfg):
-               # Use source commands so that syntax error messages
+       if recursive and is_dir:
+               # Emulate source commands so that syntax error messages
                # can display real file names and line numbers.
+               def onerror(e):
+                       if e.errno == PermissionDenied.errno:
+                               raise PermissionDenied(mycfg)
+
                recursive_files = []
-               for parent, dirs, files in os.walk(mycfg):
+               for parent, dirs, files in os.walk(mycfg, onerror=onerror):
                        try:
                                parent = _unicode_decode(parent,
                                        encoding=_encodings['fs'], errors='strict')