Skip to content

Commit

Permalink
fix: 🐛 compile on linux
Browse files Browse the repository at this point in the history
  • Loading branch information
wjian23 committed Jan 22, 2024
1 parent 585fc69 commit 8f8eacf
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 117 deletions.
3 changes: 2 additions & 1 deletion gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ uuid.workspace = true
reqwest.workspace = true
reqwest-eventsource.workspace = true
once_cell.workspace = true
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }

ahash = "0.8.3"
tiny_http = "0.12"
url = "2.4.1"
base64 = "0.21.5"
url-escape = "0.1.1"
rand = "0.8.5"
tokio = { version = "1.20.0", features = ["macros", "rt-multi-thread"] }
fs4 = "0.7.0"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["namedpipeapi"] }
Expand Down
31 changes: 31 additions & 0 deletions gui/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,34 @@ pub use macos::{app_init_hook, app_run_before_hook, has_permission, permission_p
mod windows;
#[cfg(target_os = "windows")]
pub use windows::{app_init_hook, app_run_before_hook, has_permission, permission_prompt};

#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "linux")]
pub use linux::{app_init_hook, app_run_before_hook, has_permission, permission_prompt};

fn singleton_guard() -> bool {
use fs4::FileExt;
use once_cell::sync::Lazy;
use polestar_core::project_home_path;
use ribir::prelude::log::warn;
use std::fs::OpenOptions;

static GUARD_FILE: Lazy<(Result<std::fs::File, std::io::Error>, bool)> = Lazy::new(|| {
let mut options = OpenOptions::new();
let file_path = format!("{}/{}", project_home_path().display(), "/singleton_guard");
let file = options.create(true).write(true).open(file_path);
let singleton = match file {
Ok(ref f) => {
let lock = f.try_lock_exclusive();
lock.is_ok()
}
Err(ref e) => {
warn!("Failed to open singleton_guard file: {}", e);
false
}
};
(file, singleton)
});
GUARD_FILE.1
}
17 changes: 17 additions & 0 deletions gui/src/platform/linux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#[cfg(target_os = "linux")]
pub fn app_init_hook() -> bool { super::singleton_guard() }

#[cfg(target_os = "linux")]
pub fn app_run_before_hook() {}

#[cfg(target_os = "linux")]
pub fn permission_prompt() -> bool {
// mock for linux, wait for implementation
true
}

#[cfg(target_os = "linux")]
pub fn has_permission() -> bool {
// mock for linux, wait for implementation
true
}
117 changes: 1 addition & 116 deletions gui/src/platform/windows.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[cfg(target_os = "windows")]
pub fn app_init_hook() -> bool { windows_singleton_guard() }
pub fn app_init_hook() -> bool { super::singleton_guard() }

#[cfg(target_os = "windows")]
pub fn app_run_before_hook() {}
Expand All @@ -15,118 +15,3 @@ pub fn has_permission() -> bool {
// mock for windows, wait for windows implementation
true
}

#[cfg(windows)]
fn windows_singleton_guard() -> bool {
use bytes::BytesMut;
use ribir::prelude::{App, AppEvent};
use std::ffi::OsString;
use std::os::windows::ffi::OsStrExt;
use winapi::{
shared::{minwindef::LPVOID, winerror::ERROR_ALREADY_EXISTS},
um::{
errhandlingapi::GetLastError,
fileapi::{CreateFileW, ReadFile, WriteFile, OPEN_EXISTING},
namedpipeapi::{ConnectNamedPipe, CreateNamedPipeW, DisconnectNamedPipe},
synchapi::{CreateMutexW, ReleaseMutex},
winbase::{
PIPE_ACCESS_DUPLEX, PIPE_READMODE_MESSAGE, PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES,
PIPE_WAIT,
},
winnt::GENERIC_WRITE,
},
};

let mutex_name: Vec<_> = OsString::from("PoleStarChat_Mutex")
.as_os_str()
.encode_wide()
.chain(Some(0))
.collect();

let buffer_size = 1024_u32;
let is_singleton = unsafe {
let h_mutex = CreateMutexW(std::ptr::null_mut(), 1, mutex_name.as_ptr());
let err = GetLastError();
if err == ERROR_ALREADY_EXISTS && !h_mutex.is_null() {
ReleaseMutex(h_mutex);
}
!h_mutex.is_null() && err == 0
};
if is_singleton {
let event_sender = App::event_sender();
std::thread::spawn(move || {
let pipe_name: Vec<_> = OsString::from("\\\\.\\pipe\\polestar_chat")
.as_os_str()
.encode_wide()
.chain(Some(0))
.collect();
let h_pipe = unsafe {
CreateNamedPipeW(
pipe_name.as_ptr(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
buffer_size,
buffer_size,
0,
std::ptr::null_mut(),
)
};

loop {
unsafe { ConnectNamedPipe(h_pipe, std::ptr::null_mut()) };
let len = 1024_u32;
let mut readed = 0_u32;
let mut bytes = BytesMut::with_capacity(len as usize);
if (unsafe {
ReadFile(
h_pipe,
bytes.as_mut_ptr() as LPVOID,
len,
&mut readed,
std::ptr::null_mut(),
)
} != 0)
&& readed != 0
{
unsafe {
bytes.set_len(readed as usize);
}
let msg = String::from_utf8_lossy(&bytes).to_string();
event_sender.send(AppEvent::OpenUrl(msg.clone()));
}
unsafe { DisconnectNamedPipe(h_pipe) };
}
});
}
let matches = clap::Command::new("PolestarChat")
.arg(clap::arg!(--"oauth" <URL>).value_parser(clap::value_parser!(String)))
.get_matches();
if let Some(oauth_url) = matches.get_one::<String>("oauth") {
unsafe {
let pipe_name: Vec<_> = OsString::from("\\\\.\\pipe\\polestar_chat")
.as_os_str()
.encode_wide()
.chain(Some(0))
.collect();
let h_pipe = CreateFileW(
pipe_name.as_ptr(),
GENERIC_WRITE,
0,
std::ptr::null_mut(),
OPEN_EXISTING,
0,
std::ptr::null_mut(),
);
WriteFile(
h_pipe,
oauth_url.as_bytes().as_ptr() as LPVOID,
oauth_url.len() as u32,
std::ptr::null_mut(),
std::ptr::null_mut(),
);
};
}
println!("is_singleton: {}", is_singleton);
is_singleton
}

0 comments on commit 8f8eacf

Please sign in to comment.