Add support for long paths

* Add more file i/o wrappers in platform_utils to allow using
  long paths (length > MAX_PATH) on Windows.

* Paths using the long path syntax ("\\?\" prefix) should never
  escape the platform_utils API surface area, so that this
  specific syntax is not visible to the rest of the repo code base.

* Forward many calls from os.xxx to platform_utils.xxx in various place
  to ensure long paths support, specifically when repo decides to delete
  obsolete directories.

* There are more places that need to be converted to support long paths,
  this commit is an initial effort to unblock a few common use cases.

* Also, fix remove function to handle directory symlinks

Change-Id: If82ccc408e516e96ff7260be25f8fd2fe3f9571a
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 943a026..f6bd983 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -474,8 +474,8 @@
     # so rmtree works.
     try:
       platform_utils.rmtree(os.path.join(path, '.git'))
-    except OSError:
-      print('Failed to remove %s' % os.path.join(path, '.git'), file=sys.stderr)
+    except OSError as e:
+      print('Failed to remove %s (%s)' % (os.path.join(path, '.git'), str(e)), file=sys.stderr)
       print('error: Failed to delete obsolete path %s' % path, file=sys.stderr)
       print('       remove manually, then run sync again', file=sys.stderr)
       return -1
@@ -484,12 +484,12 @@
     # another git project
     dirs_to_remove = []
     failed = False
-    for root, dirs, files in os.walk(path):
+    for root, dirs, files in platform_utils.walk(path):
       for f in files:
         try:
           platform_utils.remove(os.path.join(root, f))
-        except OSError:
-          print('Failed to remove %s' % os.path.join(root, f), file=sys.stderr)
+        except OSError as e:
+          print('Failed to remove %s (%s)' % (os.path.join(root, f), str(e)), file=sys.stderr)
           failed = True
       dirs[:] = [d for d in dirs
                  if not os.path.lexists(os.path.join(root, d, '.git'))]
@@ -499,14 +499,14 @@
       if platform_utils.islink(d):
         try:
           platform_utils.remove(d)
-        except OSError:
-          print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr)
+        except OSError as e:
+          print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
           failed = True
-      elif len(os.listdir(d)) == 0:
+      elif len(platform_utils.listdir(d)) == 0:
         try:
-          os.rmdir(d)
-        except OSError:
-          print('Failed to remove %s' % os.path.join(root, d), file=sys.stderr)
+          platform_utils.rmdir(d)
+        except OSError as e:
+          print('Failed to remove %s (%s)' % (os.path.join(root, d), str(e)), file=sys.stderr)
           failed = True
           continue
     if failed:
@@ -517,8 +517,8 @@
     # Try deleting parent dirs if they are empty
     project_dir = path
     while project_dir != self.manifest.topdir:
-      if len(os.listdir(project_dir)) == 0:
-        os.rmdir(project_dir)
+      if len(platform_utils.listdir(project_dir)) == 0:
+        platform_utils.rmdir(project_dir)
       else:
         break
       project_dir = os.path.dirname(project_dir)