Preserve Windows readonly file modes
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
This commit is contained in:
+57
-3
@@ -3811,7 +3811,19 @@ fn mode_for(path: &Path, preserve: bool) -> Result<Option<u32>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(windows)]
|
||||||
|
fn mode_for(path: &Path, preserve: bool) -> Result<Option<u32>> {
|
||||||
|
if !preserve {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let metadata = fs::metadata(path)?;
|
||||||
|
Ok(Some(windows_mode_from_readonly(
|
||||||
|
metadata.is_dir(),
|
||||||
|
metadata.permissions().readonly(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(unix, windows)))]
|
||||||
fn mode_for(_path: &Path, _preserve: bool) -> Result<Option<u32>> {
|
fn mode_for(_path: &Path, _preserve: bool) -> Result<Option<u32>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
@@ -3830,11 +3842,40 @@ fn set_local_mode(path: &Path, mode: Option<u32>, preserve: bool) -> Result<()>
|
|||||||
fs::set_permissions(path, permissions).with_context(|| format!("chmod {}", path.display()))
|
fs::set_permissions(path, permissions).with_context(|| format!("chmod {}", path.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(windows)]
|
||||||
|
fn set_local_mode(path: &Path, mode: Option<u32>, preserve: bool) -> Result<()> {
|
||||||
|
if !preserve {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let Some(mode) = mode else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let mut permissions = fs::metadata(path)?.permissions();
|
||||||
|
permissions.set_readonly(windows_readonly_from_mode(mode));
|
||||||
|
fs::set_permissions(path, permissions)
|
||||||
|
.with_context(|| format!("set readonly mode {}", path.display()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(unix, windows)))]
|
||||||
fn set_local_mode(_path: &Path, _mode: Option<u32>, _preserve: bool) -> Result<()> {
|
fn set_local_mode(_path: &Path, _mode: Option<u32>, _preserve: bool) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(any(test, windows)), allow(dead_code))]
|
||||||
|
fn windows_mode_from_readonly(is_dir: bool, readonly: bool) -> u32 {
|
||||||
|
match (is_dir, readonly) {
|
||||||
|
(true, true) => 0o555,
|
||||||
|
(true, false) => 0o777,
|
||||||
|
(false, true) => 0o444,
|
||||||
|
(false, false) => 0o666,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(not(any(test, windows)), allow(dead_code))]
|
||||||
|
fn windows_readonly_from_mode(mode: u32) -> bool {
|
||||||
|
mode & 0o222 == 0
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_local_forwards(raw: &[String]) -> Result<Vec<LocalForward>> {
|
fn parse_local_forwards(raw: &[String]) -> Result<Vec<LocalForward>> {
|
||||||
raw.iter().map(|value| parse_local_forward(value)).collect()
|
raw.iter().map(|value| parse_local_forward(value)).collect()
|
||||||
}
|
}
|
||||||
@@ -10100,7 +10141,7 @@ mod tests {
|
|||||||
toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script,
|
toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script,
|
||||||
update_binary_version_for_installer, update_installer_url, update_version_status,
|
update_binary_version_for_installer, update_installer_url, update_version_status,
|
||||||
upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline,
|
upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline,
|
||||||
windows_update_script,
|
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script,
|
||||||
};
|
};
|
||||||
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
||||||
use dosh::native::EnvVar;
|
use dosh::native::EnvVar;
|
||||||
@@ -10186,6 +10227,19 @@ mod tests {
|
|||||||
assert!(local_symlink_target_is_dir(&link, "missing-dir\\"));
|
assert!(local_symlink_target_is_dir(&link, "missing-dir\\"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_mode_mapping_preserves_readonly_semantics() {
|
||||||
|
assert_eq!(windows_mode_from_readonly(false, true), 0o444);
|
||||||
|
assert_eq!(windows_mode_from_readonly(false, false), 0o666);
|
||||||
|
assert_eq!(windows_mode_from_readonly(true, true), 0o555);
|
||||||
|
assert_eq!(windows_mode_from_readonly(true, false), 0o777);
|
||||||
|
|
||||||
|
assert!(windows_readonly_from_mode(0o444));
|
||||||
|
assert!(windows_readonly_from_mode(0o555));
|
||||||
|
assert!(!windows_readonly_from_mode(0o644));
|
||||||
|
assert!(!windows_readonly_from_mode(0o755));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cleanup_stream_state_removes_all_per_stream_state_only_for_target() {
|
fn cleanup_stream_state_removes_all_per_stream_state_only_for_target() {
|
||||||
let stream_id = 42;
|
let stream_id = 42;
|
||||||
|
|||||||
Reference in New Issue
Block a user