fs_template._ensure_dirs: handle EEXIST (529120)

There was a race inside fs_template._ensure_dirs which could cause it to
raise EEXIST if a concurrent process created the directory after
os.path.exists returned False. Fix it by using the util.ensure_dirs
function, which already handles EEXIST.

(Cherry picked from 9f6967dbc38ea55c0de5fbf5ad663ca676c54743)

Change-Id: Ic681cebf6b700916316a364096e9bd4d82238de1
X-Gentoo-Bug: 529120
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=529120
Acked-by: Alexander Berntsen <bernalex@gentoo.org>
Reviewed-on: https://chromium-review.googlesource.com/271333
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Bertrand Simonnet <bsimonnet@chromium.org>
diff --git a/pym/portage/cache/fs_template.py b/pym/portage/cache/fs_template.py
index de4fe4b..fa44abc 100644
--- a/pym/portage/cache/fs_template.py
+++ b/pym/portage/cache/fs_template.py
@@ -10,7 +10,7 @@
 from portage.proxy.lazyimport import lazyimport
 lazyimport(globals(),
 	'portage.exception:PortageException',
-	'portage.util:apply_permissions',
+	'portage.util:apply_permissions,ensure_dirs',
 )
 del lazyimport
 
@@ -61,20 +61,15 @@
 
 		for dir in path.lstrip(os.path.sep).rstrip(os.path.sep).split(os.path.sep):
 			base = os.path.join(base,dir)
-			if not os.path.exists(base):
-				if self._perms != -1:
-					um = os.umask(0)
-				try:
-					perms = self._perms
-					if perms == -1:
-						perms = 0
-					perms |= 0o755
-					os.mkdir(base, perms)
-					if self._gid != -1:
-						os.chown(base, -1, self._gid)
-				finally:
-					if self._perms != -1:
-						os.umask(um)
+			if ensure_dirs(base):
+				# We only call apply_permissions if ensure_dirs created
+				# a new directory, so as not to interfere with
+				# permissions of existing directories.
+				mode = self._perms
+				if mode == -1:
+					mode = 0
+				mode |= 0o755
+				apply_permissions(base, mode=mode, gid=self._gid)
 
 	def _prune_empty_dirs(self):
 		all_dirs = []