Show More
@@ -284,7 +284,7 b' def checkexec(path: bytes) -> bool:' | |||||
284 | else: |
|
284 | else: | |
285 | # checkisexec exists, check if it actually is exec |
|
285 | # checkisexec exists, check if it actually is exec | |
286 | if m & EXECFLAGS != 0: |
|
286 | if m & EXECFLAGS != 0: | |
287 |
# ensure check |
|
287 | # ensure checknoexec exists, check it isn't exec | |
288 | try: |
|
288 | try: | |
289 | m = os.stat(checknoexec).st_mode |
|
289 | m = os.stat(checknoexec).st_mode | |
290 | except FileNotFoundError: |
|
290 | except FileNotFoundError: |
@@ -3,8 +3,6 b' use std::io;' | |||||
3 | use std::os::unix::fs::{MetadataExt, PermissionsExt}; |
|
3 | use std::os::unix::fs::{MetadataExt, PermissionsExt}; | |
4 | use std::path::Path; |
|
4 | use std::path::Path; | |
5 |
|
5 | |||
6 | // This is a rust rewrite of [checkexec] function from [posix.py] |
|
|||
7 |
|
||||
8 | const EXECFLAGS: u32 = 0o111; |
|
6 | const EXECFLAGS: u32 = 0o111; | |
9 |
|
7 | |||
10 | fn is_executable(path: impl AsRef<Path>) -> Result<bool, io::Error> { |
|
8 | fn is_executable(path: impl AsRef<Path>) -> Result<bool, io::Error> { | |
@@ -47,6 +45,9 b' fn check_exec_impl(path: impl AsRef<Path' | |||||
47 | let storedir = basedir.join("store"); |
|
45 | let storedir = basedir.join("store"); | |
48 |
|
46 | |||
49 | if !cachedir.exists() { |
|
47 | if !cachedir.exists() { | |
|
48 | // we want to create the 'cache' directory, not the '.hg' one. | |||
|
49 | // Automatically creating '.hg' directory could silently spawn | |||
|
50 | // invalid Mercurial repositories. That seems like a bad idea. | |||
50 | fs::create_dir(&cachedir) |
|
51 | fs::create_dir(&cachedir) | |
51 | .and_then(|()| { |
|
52 | .and_then(|()| { | |
52 | if storedir.exists() { |
|
53 | if storedir.exists() { | |
@@ -63,6 +64,9 b' fn check_exec_impl(path: impl AsRef<Path' | |||||
63 | let checkisexec = cachedir.join("checkisexec"); |
|
64 | let checkisexec = cachedir.join("checkisexec"); | |
64 | let checknoexec = cachedir.join("checknoexec"); |
|
65 | let checknoexec = cachedir.join("checknoexec"); | |
65 | if cachedir.is_dir() { |
|
66 | if cachedir.is_dir() { | |
|
67 | // Check if both files already exist in cache and have correct | |||
|
68 | // permissions. if so, we assume that permissions work. | |||
|
69 | // If not, we delete the files and try again. | |||
66 | match is_executable(&checkisexec) { |
|
70 | match is_executable(&checkisexec) { | |
67 | Err(e) if e.kind() == io::ErrorKind::NotFound => (), |
|
71 | Err(e) if e.kind() == io::ErrorKind::NotFound => (), | |
68 | Err(e) => return Err(e), |
|
72 | Err(e) => return Err(e), | |
@@ -88,6 +92,8 b' fn check_exec_impl(path: impl AsRef<Path' | |||||
88 | checkdir = &cachedir; |
|
92 | checkdir = &cachedir; | |
89 | leave_file = true; |
|
93 | leave_file = true; | |
90 | } else { |
|
94 | } else { | |
|
95 | // no cache directory (probably because .hg doesn't exist): | |||
|
96 | // check directly in `path` and don't leave the temp file behind | |||
91 | checkdir = path.as_ref(); |
|
97 | checkdir = path.as_ref(); | |
92 | leave_file = false; |
|
98 | leave_file = false; | |
93 | }; |
|
99 | }; | |
@@ -106,6 +112,8 b' fn check_exec_impl(path: impl AsRef<Path' | |||||
106 | Ok(false) |
|
112 | Ok(false) | |
107 | } |
|
113 | } | |
108 |
|
114 | |||
|
115 | /// This function is a rust rewrite of [checkexec] function from [posix.py] | |||
|
116 | /// Returns true if the filesystem supports execute permissions. | |||
109 | pub fn check_exec(path: impl AsRef<Path>) -> bool { |
|
117 | pub fn check_exec(path: impl AsRef<Path>) -> bool { | |
110 | check_exec_impl(path).unwrap_or(false) |
|
118 | check_exec_impl(path).unwrap_or(false) | |
111 | } |
|
119 | } |
General Comments 0
You need to be logged in to leave comments.
Login now