98 expandglobs: bool = False |
95 expandglobs: bool = False |
99 |
96 |
100 umask: int = os.umask(0) |
97 umask: int = os.umask(0) |
101 os.umask(umask) |
98 os.umask(umask) |
102 |
99 |
103 posixfile = open |
100 posixfile = pycompat.open |
104 |
101 |
105 |
102 |
106 def split(p: bytes) -> Tuple[bytes, bytes]: |
103 def split(p: bytes) -> Tuple[bytes, bytes]: |
107 """Same as posixpath.split, but faster |
104 """Same as posixpath.split, but faster |
108 |
105 |
172 st = os.lstat(f) |
169 st = os.lstat(f) |
173 s = st.st_mode |
170 s = st.st_mode |
174 if l: |
171 if l: |
175 if not stat.S_ISLNK(s): |
172 if not stat.S_ISLNK(s): |
176 # switch file to link |
173 # switch file to link |
177 with open(f, b'rb') as fp: |
174 with open(f, 'rb') as fp: |
178 data = fp.read() |
175 data = fp.read() |
179 unlink(f) |
176 unlink(f) |
180 try: |
177 try: |
181 os.symlink(data, f) |
178 os.symlink(data, f) |
182 except OSError: |
179 except OSError: |
183 # failed to make a link, rewrite file |
180 # failed to make a link, rewrite file |
184 with open(f, b"wb") as fp: |
181 with open(f, "wb") as fp: |
185 fp.write(data) |
182 fp.write(data) |
186 |
183 |
187 # no chmod needed at this point |
184 # no chmod needed at this point |
188 return |
185 return |
189 if stat.S_ISLNK(s): |
186 if stat.S_ISLNK(s): |
190 # switch link to file |
187 # switch link to file |
191 data = os.readlink(f) |
188 data = os.readlink(f) |
192 unlink(f) |
189 unlink(f) |
193 with open(f, b"wb") as fp: |
190 with open(f, "wb") as fp: |
194 fp.write(data) |
191 fp.write(data) |
195 s = 0o666 & ~umask # avoid restatting for chmod |
192 s = 0o666 & ~umask # avoid restatting for chmod |
196 |
193 |
197 sx = s & 0o100 |
194 sx = s & 0o100 |
198 if st.st_nlink > 1 and bool(x) != bool(sx): |
195 if st.st_nlink > 1 and bool(x) != bool(sx): |
199 # the file is a hardlink, break it |
196 # the file is a hardlink, break it |
200 with open(f, b"rb") as fp: |
197 with open(f, "rb") as fp: |
201 data = fp.read() |
198 data = fp.read() |
202 unlink(f) |
199 unlink(f) |
203 with open(f, b"wb") as fp: |
200 with open(f, "wb") as fp: |
204 fp.write(data) |
201 fp.write(data) |
205 |
202 |
206 if x and not sx: |
203 if x and not sx: |
207 # Turn on +x for every +r bit when making a file executable |
204 # Turn on +x for every +r bit when making a file executable |
208 # and obey umask. |
205 # and obey umask. |
280 if m & EXECFLAGS != 0: |
277 if m & EXECFLAGS != 0: |
281 # ensure checknoexec exists, check it isn't exec |
278 # ensure checknoexec exists, check it isn't exec |
282 try: |
279 try: |
283 m = os.stat(checknoexec).st_mode |
280 m = os.stat(checknoexec).st_mode |
284 except FileNotFoundError: |
281 except FileNotFoundError: |
285 open(checknoexec, b'w').close() # might fail |
282 open(checknoexec, 'w').close() # might fail |
286 m = os.stat(checknoexec).st_mode |
283 m = os.stat(checknoexec).st_mode |
287 if m & EXECFLAGS == 0: |
284 if m & EXECFLAGS == 0: |
288 # check-exec is exec and check-no-exec is not exec |
285 # check-exec is exec and check-no-exec is not exec |
289 return True |
286 return True |
290 # checknoexec exists but is exec - delete it |
287 # checknoexec exists but is exec - delete it |
347 # create a fixed file to link to; doesn't matter if it |
344 # create a fixed file to link to; doesn't matter if it |
348 # already exists. |
345 # already exists. |
349 target = b'checklink-target' |
346 target = b'checklink-target' |
350 try: |
347 try: |
351 fullpath = os.path.join(cachedir, target) |
348 fullpath = os.path.join(cachedir, target) |
352 open(fullpath, b'w').close() |
349 open(fullpath, 'w').close() |
353 except PermissionError: |
350 except PermissionError: |
354 # If we can't write to cachedir, just pretend |
351 # If we can't write to cachedir, just pretend |
355 # that the fs is readonly and by association |
352 # that the fs is readonly and by association |
356 # that the fs won't support symlinks. This |
353 # that the fs won't support symlinks. This |
357 # seems like the least dangerous way to avoid |
354 # seems like the least dangerous way to avoid |