comparison mercurial/windows.py @ 13375:f1fa8f481c7c

port win32.py to using the Python ctypes library The pywin32 package is no longer needed. ctypes is now required for running Mercurial on Windows. ctypes is included in Python since version 2.5. For Python 2.4, ctypes is available as an extra installer package for Windows. Moved spawndetached() from windows.py to win32.py and fixed it, using ctypes as well. spawndetached was defunct with Python 2.6.6 because Python removed their undocumented subprocess.CreateProcess. This fixes 'hg serve -d' on Windows.
author Adrian Buehlmann <adrian@cadifra.com>
date Mon, 14 Feb 2011 11:12:26 +0100
parents 6052bbc7aabd
children 4ac565a30e84
comparison
equal deleted inserted replaced
13374:1c613c1ae43d 13375:f1fa8f481c7c
69 return sys.getwindowsversion()[3] == 1 69 return sys.getwindowsversion()[3] == 1
70 except AttributeError: 70 except AttributeError:
71 return 'command' in os.environ.get('comspec', '') 71 return 'command' in os.environ.get('comspec', '')
72 72
73 def openhardlinks(): 73 def openhardlinks():
74 return not _is_win_9x() and "win32api" in globals() 74 return not _is_win_9x()
75 75
76 def system_rcpath(): 76 def system_rcpath():
77 try: 77 try:
78 return system_rcpath_win32() 78 return system_rcpath_win32()
79 except: 79 except:
103 def sshargs(sshcmd, host, user, port): 103 def sshargs(sshcmd, host, user, port):
104 '''Build argument list for ssh or Plink''' 104 '''Build argument list for ssh or Plink'''
105 pflag = 'plink' in sshcmd.lower() and '-P' or '-p' 105 pflag = 'plink' in sshcmd.lower() and '-P' or '-p'
106 args = user and ("%s@%s" % (user, host)) or host 106 args = user and ("%s@%s" % (user, host)) or host
107 return port and ("%s %s %s" % (args, pflag, port)) or args 107 return port and ("%s %s %s" % (args, pflag, port)) or args
108
109 def testpid(pid):
110 '''return False if pid dead, True if running or not known'''
111 return True
112 108
113 def set_flags(f, l, x): 109 def set_flags(f, l, x):
114 pass 110 pass
115 111
116 def set_binary(fd): 112 def set_binary(fd):
205 for path in os.environ.get('PATH', '').split(os.pathsep): 201 for path in os.environ.get('PATH', '').split(os.pathsep):
206 executable = findexisting(os.path.join(path, command)) 202 executable = findexisting(os.path.join(path, command))
207 if executable is not None: 203 if executable is not None:
208 return executable 204 return executable
209 return findexisting(os.path.expanduser(os.path.expandvars(command))) 205 return findexisting(os.path.expanduser(os.path.expandvars(command)))
210
211 def set_signal_handler():
212 try:
213 set_signal_handler_win32()
214 except NameError:
215 pass
216 206
217 def statfiles(files): 207 def statfiles(files):
218 '''Stat each file in files and yield stat or None if file does not exist. 208 '''Stat each file in files and yield stat or None if file does not exist.
219 Cluster and cache stat per directory to minimize number of OS stat calls.''' 209 Cluster and cache stat per directory to minimize number of OS stat calls.'''
220 ncase = os.path.normcase 210 ncase = os.path.normcase
239 raise 229 raise
240 dmap = {} 230 dmap = {}
241 cache = dircache.setdefault(dir, dmap) 231 cache = dircache.setdefault(dir, dmap)
242 yield cache.get(base, None) 232 yield cache.get(base, None)
243 233
244 def getuser():
245 '''return name of current user'''
246 raise error.Abort(_('user name not available - set USERNAME '
247 'environment variable'))
248
249 def username(uid=None): 234 def username(uid=None):
250 """Return the name of the user with the given uid. 235 """Return the name of the user with the given uid.
251 236
252 If uid is None, return the name of the current user.""" 237 If uid is None, return the name of the current user."""
253 return None 238 return None
333 if e.errno != errno.EEXIST: 318 if e.errno != errno.EEXIST:
334 raise 319 raise
335 unlink(dst) 320 unlink(dst)
336 os.rename(src, dst) 321 os.rename(src, dst)
337 322
338 def spawndetached(args):
339 # No standard library function really spawns a fully detached
340 # process under win32 because they allocate pipes or other objects
341 # to handle standard streams communications. Passing these objects
342 # to the child process requires handle inheritance to be enabled
343 # which makes really detached processes impossible.
344 class STARTUPINFO:
345 dwFlags = subprocess.STARTF_USESHOWWINDOW
346 hStdInput = None
347 hStdOutput = None
348 hStdError = None
349 wShowWindow = subprocess.SW_HIDE
350
351 args = subprocess.list2cmdline(args)
352 # Not running the command in shell mode makes python26 hang when
353 # writing to hgweb output socket.
354 comspec = os.environ.get("COMSPEC", "cmd.exe")
355 args = comspec + " /c " + args
356 hp, ht, pid, tid = subprocess.CreateProcess(
357 None, args,
358 # no special security
359 None, None,
360 # Do not inherit handles
361 0,
362 # DETACHED_PROCESS
363 0x00000008,
364 os.environ,
365 os.getcwd(),
366 STARTUPINFO())
367 return pid
368
369 def gethgcmd(): 323 def gethgcmd():
370 return [sys.executable] + sys.argv[:1] 324 return [sys.executable] + sys.argv[:1]
371 325
372 def termwidth(): 326 def termwidth():
373 # cmd.exe does not handle CR like a unix console, the CR is 327 # cmd.exe does not handle CR like a unix console, the CR is
378 332
379 def groupmembers(name): 333 def groupmembers(name):
380 # Don't support groups on Windows for now 334 # Don't support groups on Windows for now
381 raise KeyError() 335 raise KeyError()
382 336
383 try: 337 from win32 import *
384 # override functions with win32 versions if possible
385 from win32 import *
386 except ImportError:
387 pass
388 338
389 expandglobs = True 339 expandglobs = True