comparison mercurial/win32.py @ 17006:6fc7fd72ba3e

win32.py: let samefile and samedevice work on directories too
author Adrian Buehlmann <adrian@cadifra.com>
date Thu, 14 Jun 2012 11:03:20 +0200
parents 80142f385af9
children e780fb37168b
comparison
equal deleted inserted replaced
17005:50f434510da6 17006:6fc7fd72ba3e
56 _FILE_SHARE_READ = 0x00000001 56 _FILE_SHARE_READ = 0x00000001
57 _FILE_SHARE_WRITE = 0x00000002 57 _FILE_SHARE_WRITE = 0x00000002
58 _FILE_SHARE_DELETE = 0x00000004 58 _FILE_SHARE_DELETE = 0x00000004
59 59
60 _OPEN_EXISTING = 3 60 _OPEN_EXISTING = 3
61
62 _FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
61 63
62 # SetFileAttributes 64 # SetFileAttributes
63 _FILE_ATTRIBUTE_NORMAL = 0x80 65 _FILE_ATTRIBUTE_NORMAL = 0x80
64 _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000 66 _FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x2000
65 67
190 raise OSError(err.errno, '%s: %s' % (name, err.strerror)) 192 raise OSError(err.errno, '%s: %s' % (name, err.strerror))
191 193
192 def _getfileinfo(name): 194 def _getfileinfo(name):
193 fh = _kernel32.CreateFileA(name, 0, 195 fh = _kernel32.CreateFileA(name, 0,
194 _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE, 196 _FILE_SHARE_READ | _FILE_SHARE_WRITE | _FILE_SHARE_DELETE,
195 None, _OPEN_EXISTING, 0, None) 197 None, _OPEN_EXISTING, _FILE_FLAG_BACKUP_SEMANTICS, None)
196 if fh == _INVALID_HANDLE_VALUE: 198 if fh == _INVALID_HANDLE_VALUE:
197 _raiseoserror(name) 199 _raiseoserror(name)
198 try: 200 try:
199 fi = _BY_HANDLE_FILE_INFORMATION() 201 fi = _BY_HANDLE_FILE_INFORMATION()
200 if not _kernel32.GetFileInformationByHandle(fh, ctypes.byref(fi)): 202 if not _kernel32.GetFileInformationByHandle(fh, ctypes.byref(fi)):
212 214
213 def nlinks(name): 215 def nlinks(name):
214 '''return number of hardlinks for the given file''' 216 '''return number of hardlinks for the given file'''
215 return _getfileinfo(name).nNumberOfLinks 217 return _getfileinfo(name).nNumberOfLinks
216 218
217 def samefile(fpath1, fpath2): 219 def samefile(path1, path2):
218 '''Returns whether fpath1 and fpath2 refer to the same file. This is only 220 '''Returns whether path1 and path2 refer to the same file or directory.'''
219 guaranteed to work for files, not directories.''' 221 res1 = _getfileinfo(path1)
220 res1 = _getfileinfo(fpath1) 222 res2 = _getfileinfo(path2)
221 res2 = _getfileinfo(fpath2)
222 return (res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber 223 return (res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
223 and res1.nFileIndexHigh == res2.nFileIndexHigh 224 and res1.nFileIndexHigh == res2.nFileIndexHigh
224 and res1.nFileIndexLow == res2.nFileIndexLow) 225 and res1.nFileIndexLow == res2.nFileIndexLow)
225 226
226 def samedevice(fpath1, fpath2): 227 def samedevice(path1, path2):
227 '''Returns whether fpath1 and fpath2 are on the same device. This is only 228 '''Returns whether path1 and path2 are on the same device.'''
228 guaranteed to work for files, not directories.''' 229 res1 = _getfileinfo(path1)
229 res1 = _getfileinfo(fpath1) 230 res2 = _getfileinfo(path2)
230 res2 = _getfileinfo(fpath2)
231 return res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber 231 return res1.dwVolumeSerialNumber == res2.dwVolumeSerialNumber
232 232
233 def testpid(pid): 233 def testpid(pid):
234 '''return True if pid is still running or unable to 234 '''return True if pid is still running or unable to
235 determine, False otherwise''' 235 determine, False otherwise'''