Skip to content

Commit d83e45d

Browse files
committed
fix: when obtaining locks, use mode 666 on Linux by default.
Doing so helps with using `sudo` and others.
1 parent 45ef4ff commit d83e45d

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

gix-lock/src/acquire.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ impl File {
6060
/// If `boundary_directory` is given, non-existing directories will be created automatically and removed in the case of
6161
/// a rollback. Otherwise the containing directory is expected to exist, even though the resource doesn't have to.
6262
///
63+
/// Note that permissions will be set to `0o666`, which usually results in `0o644` after passing a default umask, on Unix systems.
64+
///
6365
/// ### Warning of potential resource leak
6466
///
6567
/// Please note that the underlying file will remain if destructors don't run, as is the case when interrupting the application.
@@ -71,7 +73,11 @@ impl File {
7173
boundary_directory: Option<PathBuf>,
7274
) -> Result<File, Error> {
7375
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
74-
gix_tempfile::writable_at(p, d, c)
76+
if let Some(permissions) = default_permissions() {
77+
gix_tempfile::writable_at_with_permissions(p, d, c, permissions)
78+
} else {
79+
gix_tempfile::writable_at(p, d, c)
80+
}
7581
})?;
7682
Ok(File {
7783
inner: handle,
@@ -87,6 +93,8 @@ impl Marker {
8793
/// If `boundary_directory` is given, non-existing directories will be created automatically and removed in the case of
8894
/// a rollback.
8995
///
96+
/// Note that permissions will be set to `0o666`, which usually results in `0o644` after passing a default umask, on Unix systems.
97+
///
9098
/// ### Warning of potential resource leak
9199
///
92100
/// Please note that the underlying file will remain if destructors don't run, as is the case when interrupting the application.
@@ -98,7 +106,11 @@ impl Marker {
98106
boundary_directory: Option<PathBuf>,
99107
) -> Result<Marker, Error> {
100108
let (lock_path, handle) = lock_with_mode(at_path.as_ref(), mode, boundary_directory, &|p, d, c| {
101-
gix_tempfile::mark_at(p, d, c)
109+
if let Some(permissions) = default_permissions() {
110+
gix_tempfile::mark_at_with_permissions(p, d, c, permissions)
111+
} else {
112+
gix_tempfile::mark_at(p, d, c)
113+
}
102114
})?;
103115
Ok(Marker {
104116
created_from_file: false,
@@ -169,6 +181,18 @@ fn add_lock_suffix(resource_path: &Path) -> PathBuf {
169181
))
170182
}
171183

184+
fn default_permissions() -> Option<std::fs::Permissions> {
185+
#[cfg(unix)]
186+
{
187+
use std::os::unix::fs::PermissionsExt;
188+
Some(std::fs::Permissions::from_mode(0o666))
189+
}
190+
#[cfg(not(unix))]
191+
{
192+
None
193+
}
194+
}
195+
172196
#[cfg(test)]
173197
mod tests {
174198
use super::*;

gix-lock/tests/lock/file.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ mod acquire {
105105
assert_eq!(file.lock_path(), resource_lock);
106106
assert_eq!(file.resource_path(), resource);
107107
assert!(resource_lock.is_file());
108+
#[cfg(unix)]
109+
{
110+
use std::os::unix::fs::PermissionsExt;
111+
let perms = resource_lock.metadata()?.permissions();
112+
assert_ne!(
113+
perms.mode() & !0o170000,
114+
0o600,
115+
"mode is more permissive now, even after passing the umask"
116+
);
117+
}
108118
file.with_mut(|out| out.write_all(b"hello world"))?;
109119
assert_eq!(file.commit()?.0, resource, "returned and computed resource path match");
110120
assert_eq!(

gix-lock/tests/lock/marker.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ mod commit {
7171
let dir = tempfile::tempdir()?;
7272
let resource = dir.path().join("the-resource");
7373
let mark = gix_lock::Marker::acquire_to_hold_resource(resource, Fail::Immediately, None)?;
74+
#[cfg(unix)]
75+
{
76+
use std::os::unix::fs::PermissionsExt;
77+
let perms = mark.lock_path().metadata()?.permissions();
78+
assert_ne!(
79+
perms.mode() & !0o170000,
80+
0o600,
81+
"mode is more permissive now, even after passing the umask"
82+
);
83+
}
7484
let err = mark.commit().expect_err("should always fail");
7585
assert_eq!(err.error.kind(), std::io::ErrorKind::Other);
7686
assert_eq!(

0 commit comments

Comments
 (0)