annotate mercurial/windows.py @ 13579:3cbb3c57a50e

transplant: added 'HGREVISION' variable to the environment passed to the 'filter' command Sometimes it is necessary to know the original revision ID in order to correctly rewrite the patch or commit message when transplanting. This patch follows the pattern set by the existing 'HGUSER' environment variable, and adds a test that covers both HGUSER and HGREVISION.
author Luke Plant <L.Plant.98@cantab.net>
date Fri, 11 Mar 2011 15:48:44 +0000
parents 67743d5f49b6
children 930efdc6bfa4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
1 # windows.py - Windows utility function implementations for Mercurial
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
2 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
4 #
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9594
diff changeset
6 # GNU General Public License version 2 or any later version.
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
7914
48661519913f windows: add various missing import
Steve Borho <steve@borho.org>
parents: 7913
diff changeset
8 from i18n import _
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8226
diff changeset
9 import osutil, error
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
10 import errno, msvcrt, os, re, sys, random, subprocess
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
11
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 nulldev = 'NUL:'
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
13 umask = 002
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
15 # wrap osutil.posixfile to provide friendlier exceptions
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
16 def posixfile(name, mode='r', buffering=-1):
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
17 try:
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
18 return osutil.posixfile(name, mode, buffering)
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
19 except WindowsError, err:
9448
bc6b0fef9495 windows: provide filename in IOError exceptions
Steve Borho <steve@borho.org>
parents: 9174
diff changeset
20 raise IOError(err.errno, '%s: %s' % (name, err.strerror))
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
21 posixfile.__doc__ = osutil.posixfile.__doc__
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
22
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8761
diff changeset
23 class winstdout(object):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
24 '''stdout on windows misbehaves if sent through a pipe'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
25
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
26 def __init__(self, fp):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
27 self.fp = fp
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
28
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 def __getattr__(self, key):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
30 return getattr(self.fp, key)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
31
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
32 def close(self):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
33 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
34 self.fp.close()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
35 except: pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
36
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
37 def write(self, s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
38 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
39 # This is workaround for "Not enough space" error on
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
40 # writing large size of data to console.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
41 limit = 16000
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
42 l = len(s)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
43 start = 0
10394
4612cded5176 fix coding style (reported by pylint)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
44 self.softspace = 0
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
45 while start < l:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
46 end = start + limit
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 self.fp.write(s[start:end])
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 start = end
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
49 except IOError, inst:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
50 if inst.errno != 0:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
51 raise
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52 self.close()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 raise IOError(errno.EPIPE, 'Broken pipe')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 def flush(self):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57 return self.fp.flush()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58 except IOError, inst:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
59 if inst.errno != errno.EINVAL:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
60 raise
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
61 self.close()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 raise IOError(errno.EPIPE, 'Broken pipe')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64 sys.stdout = winstdout(sys.stdout)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 def _is_win_9x():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 '''return true if run on windows 95, 98 or me.'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 return sys.getwindowsversion()[3] == 1
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 except AttributeError:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 return 'command' in os.environ.get('comspec', '')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 def openhardlinks():
13375
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
74 return not _is_win_9x()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75
13377
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
76 _HKEY_LOCAL_MACHINE = 0x80000002L
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
77
13378
244772f67ac1 windows: eliminate system_rcpath_win32()
Adrian Buehlmann <adrian@cadifra.com>
parents: 13377
diff changeset
78 def system_rcpath():
13377
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
79 '''return default os-specific hgrc search path'''
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
80 rcpath = []
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
81 filename = executable_path()
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
82 # Use mercurial.ini found in directory with hg.exe
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
83 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
84 if os.path.isfile(progrc):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
85 rcpath.append(progrc)
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
86 return rcpath
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
87 # Use hgrc.d found in directory with hg.exe
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
88 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
89 if os.path.isdir(progrcd):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
90 for f, kind in osutil.listdir(progrcd):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
91 if f.endswith('.rc'):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
92 rcpath.append(os.path.join(progrcd, f))
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
93 return rcpath
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
94 # else look for a system rcpath in the registry
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
95 value = lookup_reg('SOFTWARE\\Mercurial', None, _HKEY_LOCAL_MACHINE)
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
96 if not isinstance(value, str) or not value:
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
97 return rcpath
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
98 value = value.replace('/', os.sep)
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
99 for p in value.split(os.pathsep):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
100 if p.lower().endswith('mercurial.ini'):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
101 rcpath.append(p)
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
102 elif os.path.isdir(p):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
103 for f, kind in osutil.listdir(p):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
104 if f.endswith('.rc'):
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
105 rcpath.append(os.path.join(p, f))
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
106 return rcpath
4ac565a30e84 win32: move system_rcpath_win32() to windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 13375
diff changeset
107
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 def user_rcpath():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 '''return os-specific hgrc search path to the user dir'''
13379
67743d5f49b6 eliminate win32.user_rcpath_win32()
Adrian Buehlmann <adrian@cadifra.com>
parents: 13378
diff changeset
110 home = os.path.expanduser('~')
67743d5f49b6 eliminate win32.user_rcpath_win32()
Adrian Buehlmann <adrian@cadifra.com>
parents: 13378
diff changeset
111 path = [os.path.join(home, 'mercurial.ini'),
67743d5f49b6 eliminate win32.user_rcpath_win32()
Adrian Buehlmann <adrian@cadifra.com>
parents: 13378
diff changeset
112 os.path.join(home, '.hgrc')]
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 userprofile = os.environ.get('USERPROFILE')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 if userprofile:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115 path.append(os.path.join(userprofile, 'mercurial.ini'))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 path.append(os.path.join(userprofile, '.hgrc'))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 def parse_patch_output(output_line):
8761
0289f384e1e5 Generally replace "file name" with "filename" in help and comments.
timeless <timeless@gmail.com>
parents: 8657
diff changeset
120 """parses the output produced by patch and returns the filename"""
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121 pf = output_line[14:]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 if pf[0] == '`':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
123 pf = pf[1:-1] # Remove the quotes
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124 return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 def sshargs(sshcmd, host, user, port):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127 '''Build argument list for ssh or Plink'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
128 pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129 args = user and ("%s@%s" % (user, host)) or host
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130 return port and ("%s %s %s" % (args, pflag, port)) or args
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
132 def set_flags(f, l, x):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
133 pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
134
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
135 def set_binary(fd):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
136 # When run without console, pipes may expose invalid
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
137 # fileno(), usually set to -1.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
138 if hasattr(fd, 'fileno') and fd.fileno() >= 0:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
139 msvcrt.setmode(fd.fileno(), os.O_BINARY)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
140
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
141 def pconvert(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
142 return '/'.join(path.split(os.sep))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
143
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
144 def localpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
145 return path.replace('/', '\\')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
146
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
147 def normpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
148 return pconvert(os.path.normpath(path))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
149
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
150 def realpath(path):
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
151 '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
152 Returns the true, canonical file system path equivalent to the given
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
153 path.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
154 '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
155 # TODO: There may be a more clever way to do this that also handles other,
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
156 # less common file systems.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
157 return os.path.normpath(os.path.normcase(os.path.realpath(path)))
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
158
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159 def samestat(s1, s2):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
160 return False
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
161
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
162 # A sequence of backslashes is special iff it precedes a double quote:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
163 # - if there's an even number of backslashes, the double quote is not
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164 # quoted (i.e. it ends the quoted region)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
165 # - if there's an odd number of backslashes, the double quote is quoted
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
166 # - in both cases, every pair of backslashes is unquoted into a single
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
167 # backslash
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
168 # (See http://msdn2.microsoft.com/en-us/library/a1y7w461.aspx )
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
169 # So, to quote a string, we must surround it in double quotes, double
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 # the number of backslashes that preceed double quotes and add another
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
171 # backslash before every double quote (being careful with the double
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
172 # quote we've appended to the end)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173 _quotere = None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
174 def shellquote(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
175 global _quotere
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
176 if _quotere is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
177 _quotere = re.compile(r'(\\*)("|\\$)')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
178 return '"%s"' % _quotere.sub(r'\1\1\\\2', s)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
179
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
180 def quotecommand(cmd):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
181 """Build a command string suitable for os.popen* calls."""
13188
6c9345f9edca util: concentrate quoting knowledge to windows.py quotecommand()
Steve Borho <steve@borho.org>
parents: 12689
diff changeset
182 if sys.version_info < (2, 7, 1):
6c9345f9edca util: concentrate quoting knowledge to windows.py quotecommand()
Steve Borho <steve@borho.org>
parents: 12689
diff changeset
183 # Python versions since 2.7.1 do this extra quoting themselves
6c9345f9edca util: concentrate quoting knowledge to windows.py quotecommand()
Steve Borho <steve@borho.org>
parents: 12689
diff changeset
184 return '"' + cmd + '"'
6c9345f9edca util: concentrate quoting knowledge to windows.py quotecommand()
Steve Borho <steve@borho.org>
parents: 12689
diff changeset
185 return cmd
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
186
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
187 def popen(command, mode='r'):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
188 # Work around "popen spawned process may not write to stdout
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
189 # under windows"
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
190 # http://bugs.python.org/issue1366
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
191 command += " 2> %s" % nulldev
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
192 return os.popen(quotecommand(command), mode)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
193
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
194 def explain_exit(code):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
195 return _("exited with status %d") % code, code
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
196
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
197 # if you change this stub into a real check, please try to implement the
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
198 # username and groupname functions above, too.
8657
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
199 def isowner(st):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
200 return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
201
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
202 def find_exe(command):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
203 '''Find executable for command searching like cmd.exe does.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
204 If command is a basename then PATH is searched for command.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
205 PATH isn't searched if command is an absolute or relative path.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
206 An extension from PATHEXT is found and added if not present.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
207 If command isn't found None is returned.'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
208 pathext = os.environ.get('PATHEXT', '.COM;.EXE;.BAT;.CMD')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
209 pathexts = [ext for ext in pathext.lower().split(os.pathsep)]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
210 if os.path.splitext(command)[1].lower() in pathexts:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
211 pathexts = ['']
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 def findexisting(pathcommand):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 'Will append extension (if needed) and return existing file'
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215 for ext in pathexts:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 executable = pathcommand + ext
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 if os.path.exists(executable):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
218 return executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
219 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221 if os.sep in command:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 return findexisting(command)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
224 for path in os.environ.get('PATH', '').split(os.pathsep):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
225 executable = findexisting(os.path.join(path, command))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
226 if executable is not None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 return executable
10156
c31ac3f7fd8f windows: expand environment vars in find_exe
Steve Borho <steve@borho.org>
parents: 9594
diff changeset
228 return findexisting(os.path.expanduser(os.path.expandvars(command)))
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
229
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
230 def statfiles(files):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
231 '''Stat each file in files and yield stat or None if file does not exist.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
232 Cluster and cache stat per directory to minimize number of OS stat calls.'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
233 ncase = os.path.normcase
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
234 dircache = {} # dirname -> filename -> status | None if file does not exist
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
235 for nf in files:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
236 nf = ncase(nf)
9099
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
237 dir, base = os.path.split(nf)
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
238 if not dir:
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
239 dir = '.'
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
240 cache = dircache.get(dir, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
241 if cache is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
242 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
243 dmap = dict([(ncase(n), s)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
244 for n, k, s in osutil.listdir(dir, True)])
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
245 except OSError, err:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
246 # handle directory not found in Python version prior to 2.5
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
247 # Python <= 2.4 returns native Windows code 3 in errno
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
248 # Python >= 2.5 returns ENOENT and adds winerror field
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
249 # EINVAL is raised if dir is not a directory.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
250 if err.errno not in (3, errno.ENOENT, errno.EINVAL,
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
251 errno.ENOTDIR):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
252 raise
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
253 dmap = {}
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
254 cache = dircache.setdefault(dir, dmap)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
255 yield cache.get(base, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
256
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
257 def username(uid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
258 """Return the name of the user with the given uid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
259
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
260 If uid is None, return the name of the current user."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
261 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
262
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
263 def groupname(gid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
264 """Return the name of the group with the given gid.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
265
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
266 If gid is None, return the name of the current group."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
267 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
268
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
269 def _removedirs(name):
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
270 """special version of os.removedirs that does not remove symlinked
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
271 directories or junction points if they actually contain files"""
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
272 if osutil.listdir(name):
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
273 return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
274 os.rmdir(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
275 head, tail = os.path.split(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
276 if not tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
277 head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
278 while head and tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
279 try:
9572
1f665246dab3 windows: fix unlink() not dropping empty tree (issue1861)
Patrick Mezard <pmezard@gmail.com>
parents: 9448
diff changeset
280 if osutil.listdir(head):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
281 return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
282 os.rmdir(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
283 except:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
284 break
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
285 head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
286
13235
6bf39d88c857 rename util.unlink to unlinkpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 13206
diff changeset
287 def unlinkpath(f):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
288 """unlink and remove the directory if it is empty"""
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
289 os.unlink(f)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
290 # try removing directories that might now be empty
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
291 try:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
292 _removedirs(os.path.dirname(f))
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
293 except OSError:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
294 pass
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
295
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
296 def unlink(f):
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
297 '''try to implement POSIX' unlink semantics on Windows'''
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
298
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
299 # POSIX allows to unlink and rename open files. Windows has serious
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
300 # problems with doing that:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
301 # - Calling os.unlink (or os.rename) on a file f fails if f or any
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
302 # hardlinked copy of f has been opened with Python's open(). There is no
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
303 # way such a file can be deleted or renamed on Windows (other than
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
304 # scheduling the delete or rename for the next reboot).
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
305 # - Calling os.unlink on a file that has been opened with Mercurial's
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
306 # posixfile (or comparable methods) will delay the actual deletion of
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
307 # the file for as long as the file is held open. The filename is blocked
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
308 # during that time and cannot be used for recreating a new file under
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
309 # that same name ("zombie file"). Directories containing such zombie files
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
310 # cannot be removed or moved.
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
311 # A file that has been opened with posixfile can be renamed, so we rename
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
312 # f to a random temporary name before calling os.unlink on it. This allows
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
313 # callers to recreate f immediately while having other readers do their
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
314 # implicit zombie filename blocking on a temporary name.
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
315
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
316 for tries in xrange(10):
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
317 temp = '%s-%08x' % (f, random.randint(0, 0xffffffff))
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
318 try:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
319 os.rename(f, temp) # raises OSError EEXIST if temp exists
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
320 break
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
321 except OSError, e:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
322 if e.errno != errno.EEXIST:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
323 raise
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
324 else:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
325 raise IOError, (errno.EEXIST, "No usable temporary filename found")
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
326
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
327 try:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
328 os.unlink(temp)
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
329 except:
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
330 # Some very rude AV-scanners on Windows may cause this unlink to fail.
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
331 # Not aborting here just leaks the temp file, whereas aborting at this
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
332 # point may leave serious inconsistencies. Ideally, we would notify
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
333 # the user in this case here.
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
334 pass
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
335
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
336 def rename(src, dst):
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
337 '''atomically rename file src to dst, replacing dst if it exists'''
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
338 try:
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
339 os.rename(src, dst)
13278
e9a52ed28157 windows.rename: check OSError for EEXIST
Adrian Buehlmann <adrian@cadifra.com>
parents: 13235
diff changeset
340 except OSError, e:
e9a52ed28157 windows.rename: check OSError for EEXIST
Adrian Buehlmann <adrian@cadifra.com>
parents: 13235
diff changeset
341 if e.errno != errno.EEXIST:
e9a52ed28157 windows.rename: check OSError for EEXIST
Adrian Buehlmann <adrian@cadifra.com>
parents: 13235
diff changeset
342 raise
13280
6052bbc7aabd reintroduces util.unlink, for POSIX and Windows.
Adrian Buehlmann <adrian@cadifra.com>
parents: 13278
diff changeset
343 unlink(dst)
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
344 os.rename(src, dst)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
345
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
346 def gethgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
347 return [sys.executable] + sys.argv[:1]
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
348
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12063
diff changeset
349 def termwidth():
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
350 # cmd.exe does not handle CR like a unix console, the CR is
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
351 # counted in the line length. On 80 columns consoles, if 80
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
352 # characters are written, the following CR won't apply on the
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
353 # current line but on the new one. Keep room for it.
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
354 return 79
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
355
11138
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
356 def groupmembers(name):
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
357 # Don't support groups on Windows for now
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
358 raise KeyError()
99eee847beaa acl: grp module is not available on windows
Patrick Mezard <pmezard@gmail.com>
parents: 11010
diff changeset
359
13375
f1fa8f481c7c port win32.py to using the Python ctypes library
Adrian Buehlmann <adrian@cadifra.com>
parents: 13280
diff changeset
360 from win32 import *
8614
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8559
diff changeset
361
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8559
diff changeset
362 expandglobs = True