Skip to content

Commit

Permalink
0.4.3: Text wrap, replace plist with IOKit call
Browse files Browse the repository at this point in the history
  • Loading branch information
Randomblock1 committed Feb 26, 2023
1 parent 4a0349a commit 904ff0f
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 119 deletions.
96 changes: 20 additions & 76 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "caffeinate2"
version = "0.4.2"
version = "0.4.3"
edition = "2021"
authors = ["Randomblock1 <randomblock1@pm.me>"]
description = "Caffeinate MacOS utility with more options. Temporarily prevent your system from sleeping."
Expand All @@ -14,11 +14,10 @@ categories = ["command-line-utilities"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "4.1.6", features = ["derive"] }
clap = { version = "4.1.6", features = ["derive", "wrap_help"] }
core-foundation = "0.9.3"
libloading = "0.7.4"
nix = "0.26.2"
plist = "1.4.1"
regex = { version = "1.7.1", default-features = false, features = ["std", "unicode-perl"] }
signal-hook = "0.3.15"
time = { version = "0.3.20", features = ["macros", "local-offset"] }
time = { version = "0.3.20", features = ["macros", "formatting", "local-offset"] }
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ This project is licensed under the MIT License - see [the license file](LICENSE.
## TODO

- [ ] Treat timeout like a timeout, and not a timer.
- [ ] Figure out if I can get commands to support color (for example, `caffeinate2 brew` is uncolored)
- [ ] Figure out how to fake a tty (for example, `caffeinate2 brew list` is uncolored)
- [ ] Print sleep types better
- [ ] Get system sleep status without reading a plist
- [ ] Get PID info by using Grand Central Dispatch instead of a weird `lsof` hack
- [x] Get system sleep status without reading a plist
- [x] Get PID info by using Grand Central Dispatch instead of a weird `lsof` hack - POSTPONED because it's a mess and it currently Just Works™️
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fn release_assertions(iokit: &power_management::IOKit, assertions: &Vec<u32>) {
for assertion in assertions {
iokit.release_assertion(*assertion);
}
if power_management::IOKit::get_sleep_disabled() {
if power_management::IOKit::get_sleep_disabled(iokit) {
iokit.set_sleep_disabled(false).unwrap_or_else(|_| {
eprintln!("Error: Insufficient privileges to disable sleep. Try running with sudo.");
process::exit(1);
Expand Down
57 changes: 22 additions & 35 deletions src/power_management.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use core_foundation::base::TCFType;
use core_foundation::base::{TCFType, TCFTypeRef};
use core_foundation::boolean::CFBoolean;
use core_foundation::dictionary::{CFDictionaryGetValueIfPresent, CFDictionaryRef};
use core_foundation::number::CFBooleanRef;
use core_foundation::string::{CFString, CFStringRef};
use libloading::{Library, Symbol};
use std::mem::MaybeUninit;
Expand Down Expand Up @@ -28,6 +30,13 @@ impl IOKit {
}
}

fn iopm_copy_power_settings(&self) -> CFDictionaryRef {
let iokit = &self.library;
let iopm_copy_power_settings: Symbol<unsafe extern "C" fn() -> CFDictionaryRef> =
unsafe { iokit.get(b"IOPMCopySystemPowerSettings") }.unwrap();
unsafe { iopm_copy_power_settings() }
}

pub fn create_assertion(&self, assertion_type: &str, state: bool) -> u32 {
let iokit = &self.library;
let iopmassertion_create_with_name: Symbol<
Expand Down Expand Up @@ -182,43 +191,21 @@ impl IOKit {
}
}

pub fn get_sleep_disabled() -> bool {
const PATH: &str = "/Library/Preferences/com.apple.PowerManagement.plist";
pub fn get_sleep_disabled(&self) -> bool {
let mut ptr: *const std::os::raw::c_void = std::ptr::null();

// Open the file
let value: plist::Value = match plist::from_file(PATH) {
Ok(v) => v,
Err(e) => {
panic!("Failed to open {}: {}", PATH, e);
}
let result = unsafe {
CFDictionaryGetValueIfPresent(
self.iopm_copy_power_settings(),
CFString::new("SleepDisabled").as_CFTypeRef().as_void_ptr(),
&mut ptr,
)
};

// Get the "SystemPowerSettings" dictionary from the root dictionary
let system_power_settings = value
.as_dictionary()
.and_then(|dict| dict.get("SystemPowerSettings"))
.and_then(|dict| dict.as_dictionary())
.unwrap_or_else(|| {
panic!("Failed to get SystemPowerSettings dictionary from {}", PATH);
});

// Get the "SleepDisabled" key from the "SystemPowerSettings" dictionary
let sleep_disabled = system_power_settings
.get("SleepDisabled")
.and_then(|val| val.as_boolean())
.unwrap_or_else(|| {
panic!("Failed to get SleepDisabled value from {}", PATH);
});
if result == 0 {
panic!("Failed to get SleepDisabled value!");
}

#[cfg(debug_assertions)]
println!(
"System sleep is currently {}",
if sleep_disabled {
"disabled"
} else {
"enabled"
}
);
sleep_disabled
ptr as CFBooleanRef == unsafe { core_foundation::number::kCFBooleanTrue }
}
}

0 comments on commit 904ff0f

Please sign in to comment.