Skip to content

Commit

Permalink
use faccess for readonly detection
Browse files Browse the repository at this point in the history
  • Loading branch information
kirawi committed Jan 8, 2024
1 parent 070d44f commit 9972882
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 29 deletions.
28 changes: 3 additions & 25 deletions helix-view/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use helix_core::{
};

use crate::editor::Config;
use crate::faccess::readonly;
use crate::faccess::{copy_metadata, readonly};
use crate::{DocumentId, Editor, Theme, View, ViewId};

/// 8kB of buffer space for encoding and decoding `Rope`s.
Expand Down Expand Up @@ -844,23 +844,6 @@ impl Document {
impl Future<Output = Result<DocumentSavedEvent, anyhow::Error>> + 'static + Send,
anyhow::Error,
> {
#[cfg(unix)]
async fn chown(path: &Path, other: &Path) -> anyhow::Result<()> {
use std::os::unix::ffi::OsStrExt;
use std::os::unix::fs::MetadataExt;
let meta = tokio::fs::metadata(path).await?;

// From https://github.com/uutils/coreutils/blob/2c73e978ba882c9cd56f0f16fae6f8dcce1c9850/src/uucore/src/lib/features/perms.rs#L46-L61
let uid = meta.uid();
let gid = meta.gid();
let s = std::ffi::CString::new(other.as_os_str().as_bytes())?;
let ret = unsafe { libc::chown(s.as_ptr(), uid, gid) };
if ret != 0 {
return Err(anyhow::anyhow!(tokio::io::Error::last_os_error()));
}
Ok(())
}

log::debug!(
"submitting save of doc '{:?}'",
self.path().map(|path| path.to_string_lossy())
Expand Down Expand Up @@ -931,6 +914,7 @@ impl Document {
{
let path = path.clone();
tokio::task::spawn_blocking(move || -> anyhow::Result<()> {
copy_metadata(&path, &tmp_path)?;
tmp_path.persist(path)?;
Ok(())
})
Expand Down Expand Up @@ -995,18 +979,12 @@ impl Document {
}
}

#[cfg(unix)]
// Detect if the file is readonly and change the readonly field if necessary (unix only)
pub fn detect_readonly(&mut self) {
use rustix::fs::{access, Access};
// Allows setting the flag for files the user cannot modify, like root files
self.readonly = match &self.path {
None => false,
Some(p) => match access(p, Access::WRITE_OK) {
Ok(_) => false,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => false,
Err(_) => true,
},
Some(p) => readonly(p),
};
}

Expand Down
12 changes: 9 additions & 3 deletions helix-view/src/faccess.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Forked from https://github.com/Freaky/faccess
//! Licensed under MIT
//! From https://github.com/Freaky/faccess

use std::io;
use std::path::Path;
Expand All @@ -8,6 +7,7 @@ use filetime::FileTime;

use bitflags::bitflags;

// Licensed under MIT from faccess
bitflags! {
/// Access mode flags for `access` function to test for.
pub struct AccessMode: u8 {
Expand Down Expand Up @@ -80,6 +80,7 @@ mod imp {
}
}

// Licensed under MIT from faccess except for `chown` and `copy_metadata`
#[cfg(windows)]
mod imp {
use windows::core::PCWSTR;
Expand Down Expand Up @@ -410,6 +411,7 @@ mod imp {
}
}

// Licensed under MIT from faccess
#[cfg(not(any(unix, windows)))]
mod imp {
use super::*;
Expand Down Expand Up @@ -440,7 +442,11 @@ mod imp {
}

pub fn readonly(p: &Path) -> bool {
imp::access(p, AccessMode::READ).is_ok() && imp::access(p, AccessMode::WRITE).is_err()
match imp::access(p, AccessMode::WRITE) {
Ok(_) => false,
Err(err) if err.kind() == std::io::ErrorKind::NotFound => false,
Err(_) => true,
}
}

pub fn copy_metadata(from: &Path, to: &Path) -> std::io::Result<()> {
Expand Down
1 change: 0 additions & 1 deletion helix-view/src/file.rs

This file was deleted.

0 comments on commit 9972882

Please sign in to comment.