annotate mercurial/windows.py @ 11010:18e81d42ee5c stable

util: fix default termwidth() under Windows sys.stdout.write('-'*80 + '\n') or sys.stdout.write('-'*80 + '\r') do not work on Windows as they do on unix. On a 80 columns Windows console, the extra CR or LF are interpreted as if belonging to the next line, so the first command displays 2 lines (only one on unix) and the second one leave the line visible and move back to the following line. To avoid this, we sacrifice one column under Windows.
author Patrick Mezard <pmezard@gmail.com>
date Mon, 26 Apr 2010 22:30:40 +0200
parents 4612cded5176
children 99eee847beaa
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():
8559
4429751f5da7 windows: make openhardlinks work
Henrik Stuart <hg@hstuart.dk>
parents: 8421
diff changeset
74 return not _is_win_9x() and "win32api" in globals()
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 def system_rcpath():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 return system_rcpath_win32()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 except:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 return [r'c:\mercurial\mercurial.ini']
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 def user_rcpath():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 '''return os-specific hgrc search path to the user dir'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 path = user_rcpath_win32()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
86 except:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 home = os.path.expanduser('~')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 path = [os.path.join(home, 'mercurial.ini'),
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 os.path.join(home, '.hgrc')]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 userprofile = os.environ.get('USERPROFILE')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91 if userprofile:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 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
93 path.append(os.path.join(userprofile, '.hgrc'))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 return path
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
96 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
97 """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
98 pf = output_line[14:]
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99 if pf[0] == '`':
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 pf = pf[1:-1] # Remove the quotes
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 return pf
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 def sshargs(sshcmd, host, user, port):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 '''Build argument list for ssh or Plink'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 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
106 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
107 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
108
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 def testpid(pid):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110 '''return False if pid dead, True if running or not known'''
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
111 return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 def set_flags(f, l, x):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 def set_binary(fd):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 # 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
118 # fileno(), usually set to -1.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 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
120 msvcrt.setmode(fd.fileno(), os.O_BINARY)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 def pconvert(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
123 return '/'.join(path.split(os.sep))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125 def localpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 return path.replace('/', '\\')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
128 def normpath(path):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129 return pconvert(os.path.normpath(path))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
130
9238
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
131 def realpath(path):
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
132 '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
133 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
134 path.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
135 '''
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
136 # 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
137 # less common file systems.
40196d036a71 util: add realpath() for getting the 'true' path.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 9174
diff changeset
138 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
139
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
140 def samestat(s1, s2):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
141 return False
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
142
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
143 # 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
144 # - 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
145 # 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
146 # - 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
147 # - 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
148 # backslash
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
149 # (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
150 # 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
151 # 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
152 # 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
153 # quote we've appended to the end)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
154 _quotere = None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
155 def shellquote(s):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
156 global _quotere
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
157 if _quotere is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
158 _quotere = re.compile(r'(\\*)("|\\$)')
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159 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
160
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
161 def quotecommand(cmd):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
162 """Build a command string suitable for os.popen* calls."""
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
163 # The extra quotes are needed because popen* runs the command
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164 # through the current COMSPEC. cmd.exe suppress enclosing quotes.
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
165 return '"' + cmd + '"'
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
166
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
167 def popen(command, mode='r'):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
168 # 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
169 # under windows"
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 # http://bugs.python.org/issue1366
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
171 command += " 2> %s" % nulldev
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
172 return os.popen(quotecommand(command), mode)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
173
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
174 def explain_exit(code):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
175 return _("exited with status %d") % code, code
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
176
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
177 # 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
178 # username and groupname functions above, too.
8657
3fa92c618624 posix: do not use fstat in isowner
Martin Geisler <mg@lazybytes.net>
parents: 8614
diff changeset
179 def isowner(st):
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
180 return True
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
181
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
182 def find_exe(command):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
183 '''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
184 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
185 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
186 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
187 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
188 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
189 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
190 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
191 pathexts = ['']
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
192
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
193 def findexisting(pathcommand):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
194 '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
195 for ext in pathexts:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
196 executable = pathcommand + ext
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
197 if os.path.exists(executable):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
198 return executable
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
199 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
200
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
201 if os.sep in command:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
202 return findexisting(command)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
203
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
204 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
205 executable = findexisting(os.path.join(path, command))
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
206 if executable is not None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
207 return executable
10156
c31ac3f7fd8f windows: expand environment vars in find_exe
Steve Borho <steve@borho.org>
parents: 9594
diff changeset
208 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
209
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
210 def set_signal_handler():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
211 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 set_signal_handler_win32()
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 except NameError:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 pass
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 def statfiles(files):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 '''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
218 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
219 ncase = os.path.normcase
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 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
221 for nf in files:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 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
223 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
224 if not dir:
3d456bf32f18 Use os.path.split() for MBCS with win32mbcs extension.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 8951
diff changeset
225 dir = '.'
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
226 cache = dircache.get(dir, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 if cache is None:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
228 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
229 dmap = dict([(ncase(n), s)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
230 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
231 except OSError, err:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
232 # 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
233 # 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
234 # 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
235 # 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
236 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
237 errno.ENOTDIR):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
238 raise
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
239 dmap = {}
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
240 cache = dircache.setdefault(dir, dmap)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
241 yield cache.get(base, None)
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
242
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
243 def getuser():
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
244 '''return name of current user'''
7949
443c0c8636ac windows: get Abort from error
Matt Mackall <mpm@selenic.com>
parents: 7934
diff changeset
245 raise error.Abort(_('user name not available - set USERNAME '
7934
ec4784bb7d75 windows: break import cycle with util
Martin Geisler <mg@daimi.au.dk>
parents: 7933
diff changeset
246 'environment variable'))
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
247
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
248 def username(uid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
249 """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
250
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
251 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
252 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
253
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
254 def groupname(gid=None):
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
255 """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
256
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
257 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
258 return None
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
259
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
260 def _removedirs(name):
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
261 """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
262 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
263 if osutil.listdir(name):
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
264 return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
265 os.rmdir(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
266 head, tail = os.path.split(name)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
267 if not tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
268 head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
269 while head and tail:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
270 try:
9572
1f665246dab3 windows: fix unlink() not dropping empty tree (issue1861)
Patrick Mezard <pmezard@gmail.com>
parents: 9448
diff changeset
271 if osutil.listdir(head):
8364
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
272 return
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
273 os.rmdir(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
274 except:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
275 break
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
276 head, tail = os.path.split(head)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
277
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
278 def unlink(f):
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
279 """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
280 os.unlink(f)
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
281 # 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
282 try:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
283 _removedirs(os.path.dirname(f))
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
284 except OSError:
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
285 pass
fa901423ac23 windows: avoid deleting non-empty reparse points
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 8330
diff changeset
286
9549
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
287 def rename(src, dst):
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
288 '''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
289 try:
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
290 os.rename(src, dst)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
291 except OSError, err: # FIXME: check err (EEXIST ?)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
292
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
293 # On windows, rename to existing file is not allowed, so we
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
294 # must delete destination first. But if a file is open, unlink
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
295 # schedules it for delete but does not delete it. Rename
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
296 # happens immediately even for open files, so we rename
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
297 # destination to a temporary name, then delete that. Then
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
298 # rename is safe to do.
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
299 # The temporary name is chosen at random to avoid the situation
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
300 # where a file is left lying around from a previous aborted run.
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
301 # The usual race condition this introduces can't be avoided as
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
302 # we need the name to rename into, and not the file itself. Due
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
303 # to the nature of the operation however, any races will at worst
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
304 # lead to the rename failing and the current operation aborting.
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
305
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
306 def tempname(prefix):
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
307 for tries in xrange(10):
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
308 temp = '%s-%08x' % (prefix, random.randint(0, 0xffffffff))
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
309 if not os.path.exists(temp):
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
310 return temp
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
311 raise IOError, (errno.EEXIST, "No usable temporary filename found")
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
312
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
313 temp = tempname(dst)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
314 os.rename(dst, temp)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
315 try:
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
316 os.unlink(temp)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
317 except:
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
318 # Some rude AV-scanners on Windows may cause the unlink to
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
319 # fail. Not aborting here just leaks the temp file, whereas
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
320 # aborting at this point may leave serious inconsistencies.
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
321 # Ideally, we would notify the user here.
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
322 pass
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
323 os.rename(src, dst)
8b8920209317 util: move rename into posix.py and windows.py
Adrian Buehlmann <adrian@cadifra.com>
parents: 9449
diff changeset
324
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
325 def spawndetached(args):
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
326 # No standard library function really spawns a fully detached
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
327 # process under win32 because they allocate pipes or other objects
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
328 # to handle standard streams communications. Passing these objects
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
329 # to the child process requires handle inheritance to be enabled
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
330 # which makes really detached processes impossible.
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
331 class STARTUPINFO:
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
332 dwFlags = subprocess.STARTF_USESHOWWINDOW
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
333 hStdInput = None
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
334 hStdOutput = None
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
335 hStdError = None
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
336 wShowWindow = subprocess.SW_HIDE
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
337
10237
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
338 args = subprocess.list2cmdline(args)
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
339 # Not running the command in shell mode makes python26 hang when
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
340 # writing to hgweb output socket.
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
341 comspec = os.environ.get("COMSPEC", "cmd.exe")
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
342 args = comspec + " /c " + args
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
343 hp, ht, pid, tid = subprocess.CreateProcess(
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
344 None, args,
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
345 # no special security
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
346 None, None,
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
347 # Do not inherit handles
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
348 0,
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
349 # DETACHED_PROCESS
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
350 0x00000008,
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
351 os.environ,
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
352 os.getcwd(),
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
353 STARTUPINFO())
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
354 return pid
2f7a38f336f4 serve: add and use portable spawnvp replacement
Patrick Mezard <pmezard@gmail.com>
parents: 10156
diff changeset
355
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
356 def gethgcmd():
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
357 return [sys.executable] + sys.argv[:1]
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10237
diff changeset
358
11010
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
359 def termwidth_():
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
360 # 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
361 # 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
362 # 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
363 # 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
364 return 79
18e81d42ee5c util: fix default termwidth() under Windows
Patrick Mezard <pmezard@gmail.com>
parents: 10394
diff changeset
365
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
366 try:
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
367 # override functions with win32 versions if possible
7932
96501a4abbec windows: fix import of win32.py (was util_win32.py)
Sune Foldager <cryo@cyanite.org>
parents: 7914
diff changeset
368 from win32 import *
7890
e710f0f592b2 util: split out posix, windows, and win32 modules
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
369 except ImportError:
8421
b6d0fa8c7685 posixfile: remove posixfile_nt and fix import bug in windows.py
Sune Foldager <cryo@cyanite.org>
parents: 8364
diff changeset
370 pass
8614
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8559
diff changeset
371
573734e7e6d0 cmdutils: Take over glob expansion duties from util
Matt Mackall <mpm@selenic.com>
parents: 8559
diff changeset
372 expandglobs = True