mercurial/posix.py
changeset 30446 b324b4e431e5
parent 30445 1ce4c2062ab0
child 30447 0d87b1caed92
equal deleted inserted replaced
30445:1ce4c2062ab0 30446:b324b4e431e5
   159     # with exec bit on.
   159     # with exec bit on.
   160 
   160 
   161     try:
   161     try:
   162         EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
   162         EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
   163         cachedir = os.path.join(path, '.hg', 'cache')
   163         cachedir = os.path.join(path, '.hg', 'cache')
   164         if not os.path.isdir(cachedir):
   164         if os.path.isdir(cachedir):
   165             cachedir = path
   165             checkisexec = os.path.join(cachedir, 'checkisexec')
   166         fh, fn = tempfile.mkstemp(dir=cachedir, prefix='hg-checkexec-')
   166             checknoexec = os.path.join(cachedir, 'checknoexec')
       
   167 
       
   168             try:
       
   169                 m = os.stat(checkisexec).st_mode
       
   170             except OSError as e:
       
   171                 if e.errno != errno.ENOENT:
       
   172                     raise
       
   173                 # checkisexec does not exist - fall through ...
       
   174             else:
       
   175                 # checkisexec exists, check if it actually is exec
       
   176                 if m & EXECFLAGS != 0:
       
   177                     # ensure checkisexec exists, check it isn't exec
       
   178                     try:
       
   179                         m = os.stat(checknoexec).st_mode
       
   180                     except OSError as e:
       
   181                         if e.errno != errno.ENOENT:
       
   182                             raise
       
   183                         file(checknoexec, 'w').close() # might fail
       
   184                         m = os.stat(checknoexec).st_mode
       
   185                     if m & EXECFLAGS == 0:
       
   186                         # check-exec is exec and check-no-exec is not exec
       
   187                         return True
       
   188                     # checknoexec exists but is exec - delete it
       
   189                     os.unlink(checknoexec)
       
   190                 # checkisexec exists but is not exec - delete it
       
   191                 os.unlink(checkisexec)
       
   192 
       
   193             # check using one file, leave it as checkisexec
       
   194             checkdir = cachedir
       
   195         else:
       
   196             # check directly in path and don't leave checkisexec behind
       
   197             checkdir = path
       
   198             checkisexec = None
       
   199         fh, fn = tempfile.mkstemp(dir=checkdir, prefix='hg-checkexec-')
   167         try:
   200         try:
   168             os.close(fh)
   201             os.close(fh)
   169             m = os.stat(fn).st_mode
   202             m = os.stat(fn).st_mode
   170             if m & EXECFLAGS:
   203             if m & EXECFLAGS == 0:
   171                 return False
   204                 os.chmod(fn, m & 0o777 | EXECFLAGS)
   172             os.chmod(fn, m & 0o777 | EXECFLAGS)
   205                 if os.stat(fn).st_mode & EXECFLAGS != 0:
   173             return os.stat(fn).st_mode & EXECFLAGS
   206                     if checkisexec is not None:
       
   207                         os.rename(fn, checkisexec)
       
   208                         fn = None
       
   209                     return True
   174         finally:
   210         finally:
   175             os.unlink(fn)
   211             if fn is not None:
       
   212                 os.unlink(fn)
   176     except (IOError, OSError):
   213     except (IOError, OSError):
   177         # we don't care, the user probably won't be able to commit anyway
   214         # we don't care, the user probably won't be able to commit anyway
   178         return False
   215         return False
   179 
   216 
   180 def checklink(path):
   217 def checklink(path):