Use rd on Windows in rmdir
This is needed because the current implementation commonly fails on Windows due to "directory not empty" errors. Using rd is more reliable.
Review URL: https://chromiumcodereview.appspot.com/13581005
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@194932 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gclient_utils.py b/gclient_utils.py
index 0eeb185..52bc6cd 100644
--- a/gclient_utils.py
+++ b/gclient_utils.py
@@ -5,12 +5,12 @@
"""Generic utils."""
import codecs
-import errno
import logging
import os
import Queue
import re
import stat
+import subprocess
import sys
import tempfile
import threading
@@ -125,34 +125,24 @@
raise Error('Called rmtree(%s) in non-directory' % path)
if sys.platform == 'win32':
- # Some people don't have the APIs installed. In that case we'll do without.
- win32api = None
- win32con = None
- try:
- # Unable to import 'XX'
- # pylint: disable=F0401
- import win32api, win32con
- except ImportError:
- pass
- else:
- # On POSIX systems, we need the x-bit set on the directory to access it,
- # the r-bit to see its contents, and the w-bit to remove files from it.
- # The actual modes of the files within the directory is irrelevant.
- os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
+ # Give up and use cmd.exe's rd command.
+ path = os.path.normcase(path)
+ for _ in xrange(3):
+ exitcode = subprocess.call(['cmd.exe', '/c', 'rd', '/q', '/s', path])
+ if exitcode == 0:
+ return
+ else:
+ print >> sys.stderr, 'rd exited with code %d' % exitcode
+ time.sleep(3)
+ raise Exception('Failed to remove path %s' % path)
+
+ # On POSIX systems, we need the x-bit set on the directory to access it,
+ # the r-bit to see its contents, and the w-bit to remove files from it.
+ # The actual modes of the files within the directory is irrelevant.
+ os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
def remove(func, subpath):
- if sys.platform == 'win32':
- os.chmod(subpath, stat.S_IWRITE)
- if win32api and win32con:
- win32api.SetFileAttributes(subpath, win32con.FILE_ATTRIBUTE_NORMAL)
- try:
- func(subpath)
- except OSError, e:
- if e.errno != errno.EACCES or sys.platform != 'win32':
- raise
- # Failed to delete, try again after a 100ms sleep.
- time.sleep(0.1)
- func(subpath)
+ func(subpath)
for fn in os.listdir(path):
# If fullpath is a symbolic link that points to a directory, isdir will