mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Fix linux compiler errors
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -2365,6 +2365,7 @@ dependencies = [
|
||||
"ureq",
|
||||
"url",
|
||||
"uuid",
|
||||
"wait-timeout",
|
||||
"waitpid-any",
|
||||
"windows",
|
||||
"xml",
|
||||
|
||||
@@ -10,7 +10,7 @@ pub fn apply_package_impl<'a>(locator: &VelopackLocator, pkg: &PathBuf, _runhook
|
||||
let mut bundle = bundle::load_bundle_from_file(pkg)?;
|
||||
let manifest = bundle.read_manifest()?;
|
||||
let temp_path = locator.get_temp_dir_rand16().to_string_lossy().to_string();
|
||||
let root_path_string = locator.get_root_dir_as_string();
|
||||
let root_path = locator.get_root_dir().to_string_lossy().to_string();
|
||||
let script_path = format!("/var/tmp/velopack_update_{}.sh", manifest.id);
|
||||
let new_locator = locator.clone_self_with_new_manifest(&manifest);
|
||||
|
||||
@@ -21,22 +21,22 @@ pub fn apply_package_impl<'a>(locator: &VelopackLocator, pkg: &PathBuf, _runhook
|
||||
info!("Chmod as executable");
|
||||
std::fs::set_permissions(&temp_path, fs::Permissions::from_mode(0o755))?;
|
||||
|
||||
info!("Moving temp file to target: {}", &root_path_string);
|
||||
info!("Moving temp file to target: {}", &root_path);
|
||||
// we use mv instead of fs::rename / fs::copy because rename fails cross-device
|
||||
// and copy fails if the process is running (presumably because rust opens the file for writing)
|
||||
// while mv works in both cases.
|
||||
let mv_args = vec!["-f", &temp_path, &root_path_string];
|
||||
let mv_args = vec!["-f", &temp_path, &root_path];
|
||||
let mv_output = Command::new("mv").args(mv_args).output()?;
|
||||
|
||||
if mv_output.status.success() {
|
||||
info!("AppImage moved successfully to: {}", &root_path_string);
|
||||
info!("AppImage moved successfully to: {}", &root_path);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// if the operation failed, let's try again elevated with pkexec
|
||||
error!("An error occurred ({:?}), will attempt to elevate permissions and try again...", mv_output);
|
||||
dialogs::ask_user_to_elevate(&manifest.title, &manifest.version.to_string())?;
|
||||
let script = format!("#!/bin/sh\nmv -f '{}' '{}'", temp_path, &root_path_string);
|
||||
let script = format!("#!/bin/sh\nmv -f '{}' '{}'", temp_path, &root_path);
|
||||
info!("Writing script for elevation: \n{}", script);
|
||||
fs::write(&script_path, script)?;
|
||||
std::fs::set_permissions(&script_path, <std::fs::Permissions as std::os::unix::fs::PermissionsExt>::from_mode(0o755))?;
|
||||
@@ -44,7 +44,7 @@ pub fn apply_package_impl<'a>(locator: &VelopackLocator, pkg: &PathBuf, _runhook
|
||||
info!("Attempting to elevate: pkexec {:?}", args);
|
||||
let elev_output = Command::new("pkexec").args(args).output()?;
|
||||
if elev_output.status.success() {
|
||||
info!("AppImage moved (elevated) to {}", &root_path_string);
|
||||
info!("AppImage moved (elevated) to {}", &root_path);
|
||||
return Ok(());
|
||||
} else {
|
||||
bail!("pkexec failed with status: {:?}", elev_output);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use std::{process::Command as Process, time::Duration};
|
||||
use std::{ffi::OsString, process::Command as Process, time::Duration};
|
||||
use velopack::locator::VelopackLocator;
|
||||
|
||||
pub fn wait_for_pid_to_exit(pid: u32, ms_to_wait: u32) -> Result<()> {
|
||||
@@ -23,7 +23,7 @@ pub fn wait_for_parent_to_exit(ms_to_wait: u32) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn start_package(locator: &VelopackLocator, exe_args: Option<Vec<&str>>, set_env: Option<&str>) -> Result<()> {
|
||||
pub fn start_package(locator: &VelopackLocator, exe_args: Option<Vec<OsString>>, set_env: Option<&str>) -> Result<()> {
|
||||
let root_dir = locator.get_root_dir();
|
||||
let mut cmd = Process::new(root_dir);
|
||||
if let Some(args) = exe_args {
|
||||
@@ -34,4 +34,4 @@ pub fn start_package(locator: &VelopackLocator, exe_args: Option<Vec<&str>>, set
|
||||
}
|
||||
cmd.spawn().map_err(|z| anyhow!("Failed to start_package ({}).", z))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,13 +7,13 @@ use std::{fs, path::Path, path::PathBuf};
|
||||
use tempfile::tempdir;
|
||||
|
||||
use velopack_bins::*;
|
||||
use velopack_bins::windows::known_path;
|
||||
use velopack::bundle::load_bundle_from_file;
|
||||
use velopack::locator::{auto_locate_app_manifest, LocationContext};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
pub fn test_install_apply_uninstall() {
|
||||
use velopack_bins::windows::known_path;
|
||||
|
||||
dialogs::set_silent(true);
|
||||
|
||||
|
||||
@@ -77,4 +77,5 @@ windows = { workspace = true, features = [
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc.workspace = true
|
||||
wait-timeout.workspace = true
|
||||
waitpid-any.workspace = true
|
||||
|
||||
@@ -133,7 +133,9 @@ pub mod locator;
|
||||
/// Sources are abstractions for custom update sources (eg. url, local file, github releases, etc).
|
||||
pub mod sources;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
maybe_pub!(wide_strings);
|
||||
|
||||
maybe_pub!(download, bundle, constants, lockfile, logging, misc);
|
||||
maybe_pub_os!(process, "process_win.rs", "process_unix.rs");
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ pub fn auto_locate_app_manifest(context: LocationContext) -> Result<VelopackLoca
|
||||
let metadata_path = contents_dir.join("sq.version");
|
||||
|
||||
if !update_exe_path.exists() {
|
||||
return Err(Error::MissingUpdateExe);
|
||||
return Err(Error::NotInstalled("Update.exe does not exist in the expected path".to_owned()));
|
||||
}
|
||||
|
||||
let appimage_path = match std::env::var("APPIMAGE") {
|
||||
|
||||
@@ -56,7 +56,7 @@ pub fn calculate_sha1_sha256<P: AsRef<Path>>(file: P) -> Result<(String, String)
|
||||
if bytes_read == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
sha256.update(&buffer[..bytes_read]);
|
||||
sha1.update(&buffer[..bytes_read]);
|
||||
}
|
||||
@@ -67,6 +67,7 @@ pub fn calculate_sha1_sha256<P: AsRef<Path>>(file: P) -> Result<(String, String)
|
||||
Ok((sha1_hash, sha256_hash))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn is_directory_writable<P1: AsRef<Path>>(path: P1) -> bool {
|
||||
use std::os::windows::fs::OpenOptionsExt;
|
||||
let path = path.as_ref();
|
||||
|
||||
@@ -1,44 +1,20 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::{OsStr, OsString},
|
||||
ffi::OsString,
|
||||
io::{Error as IoError, ErrorKind as IoErrorKind, Result as IoResult},
|
||||
os::{raw::c_void, windows::ffi::OsStrExt},
|
||||
path::Path,
|
||||
process::{Child, Command},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::process;
|
||||
|
||||
pub fn is_current_process_elevated() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn string_to_u16<P: AsRef<str>>(input: P) -> Vec<u16> {
|
||||
let input = input.as_ref();
|
||||
input.encode_utf16().chain(Some(0)).collect::<Vec<u16>>()
|
||||
}
|
||||
|
||||
pub fn run_process_as_admin(
|
||||
exe_path: String,
|
||||
args: Vec<String>,
|
||||
work_dir: Option<String>,
|
||||
show_window: bool,
|
||||
) -> IoResult<SafeProcessHandle> {
|
||||
|
||||
// let mut cmd = Command::new(exe_path).args(args);
|
||||
|
||||
// if let Some(dir) = work_dir {
|
||||
// cmd.current_dir(dir);
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn run_process(
|
||||
exe_path: String,
|
||||
args: Vec<String>,
|
||||
work_dir: Option<String>,
|
||||
pub fn run_process<P1: AsRef<Path>, P2: AsRef<Path>>(
|
||||
exe_path: P1,
|
||||
args: Vec<OsString>,
|
||||
work_dir: Option<P2>,
|
||||
_show_window: bool,
|
||||
set_env: Option<HashMap<String, String>>,
|
||||
) -> IoResult<Child> {
|
||||
let exe_path = exe_path.as_ref();
|
||||
let mut cmd = Command::new(exe_path);
|
||||
cmd.args(args);
|
||||
if let Some(dir) = work_dir {
|
||||
@@ -52,33 +28,60 @@ pub fn run_process(
|
||||
cmd.spawn()
|
||||
}
|
||||
|
||||
pub fn wait_for_process_exit_with_timeout(process: Child, dur: Duration) -> IoResult<Option<u32>> {
|
||||
let mut status = process.wait_timeout(dur)?;
|
||||
if status.is_none() {
|
||||
return Err(IoError::new(IoErrorKind::TimedOut, "Process timed out"));
|
||||
}
|
||||
Ok(status.unwrap().code())
|
||||
#[derive(Debug)]
|
||||
pub enum WaitResult {
|
||||
WaitTimeout,
|
||||
ExitCode(u32),
|
||||
NoWaitRequired,
|
||||
}
|
||||
|
||||
pub fn wait_for_pid_to_exit(pid: u32, dur: Duration) -> IoResult<()> {
|
||||
info!("Waiting {}ms for process ({}) to exit.", ms_to_wait, pid);
|
||||
let mut handle = waitpid_any::WaitHandle::open(pid.try_into()?)?;
|
||||
let result = handle.wait_timeout(Duration::from_millis(ms_to_wait as u64))?;
|
||||
if result.is_some() {
|
||||
info!("Parent process exited.");
|
||||
Ok(())
|
||||
impl WaitResult {
|
||||
pub fn code(&self) -> Option<u32> {
|
||||
match self {
|
||||
WaitResult::WaitTimeout => None,
|
||||
WaitResult::ExitCode(c) => Some(*c),
|
||||
WaitResult::NoWaitRequired => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait_for_process_exit_with_timeout(process: &mut Child, dur: Option<Duration>) -> IoResult<WaitResult> {
|
||||
if let Some(dur) = dur {
|
||||
let status = wait_timeout::ChildExt::wait_timeout(process, dur)?;
|
||||
match status {
|
||||
Some(status) => Ok(WaitResult::ExitCode(status.code().unwrap_or(0) as u32)),
|
||||
None => Ok(WaitResult::WaitTimeout),
|
||||
}
|
||||
} else {
|
||||
bail!("Parent process timed out.");
|
||||
let code = process.wait()?;
|
||||
Ok(WaitResult::ExitCode(code.code().unwrap_or(0) as u32))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait_for_parent_to_exit(dur: Duration) -> IoResult<()> {
|
||||
pub fn wait_for_pid_to_exit(pid: u32, dur: Option<Duration>) -> IoResult<WaitResult> {
|
||||
info!("Waiting {:?} for process ({}) to exit.", dur, pid);
|
||||
let mut handle = waitpid_any::WaitHandle::open(pid as i32)?;
|
||||
if let Some(dur) = dur {
|
||||
let result = handle.wait_timeout(dur)?;
|
||||
if result.is_some() {
|
||||
info!("Parent process exited.");
|
||||
Ok(WaitResult::ExitCode(0))
|
||||
} else {
|
||||
Err(IoError::new(IoErrorKind::TimedOut, "Parent process timed out."))
|
||||
}
|
||||
} else {
|
||||
handle.wait()?;
|
||||
Ok(WaitResult::ExitCode(0))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait_for_parent_to_exit(dur: Option<Duration>) -> IoResult<WaitResult> {
|
||||
let id = std::os::unix::process::parent_id();
|
||||
info!("Attempting to wait for parent process ({}) to exit.", id);
|
||||
if id > 1 {
|
||||
wait_for_pid_to_exit(id, ms_to_wait)?;
|
||||
return Ok(wait_for_pid_to_exit(id, dur)?);
|
||||
}
|
||||
Ok(())
|
||||
Ok(WaitResult::NoWaitRequired)
|
||||
}
|
||||
|
||||
pub fn kill_process(mut process: Child) -> IoResult<()> {
|
||||
|
||||
@@ -17,7 +17,7 @@ rust-version.workspace = true
|
||||
path = "src/lib.rs"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
anyhow.workspace = true
|
||||
velopack.workspace = true
|
||||
velopack_bins.workspace = true
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#![cfg(windows)]
|
||||
|
||||
mod msi;
|
||||
use msi::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user