From 3c154878d34ee3b0eb9941684a94652e31db61d9 Mon Sep 17 00:00:00 2001 From: Mars Date: Sat, 10 May 2025 14:02:49 -0400 Subject: [PATCH] fixies --- src/os/linux.cpp | 4 +- src/os/macos.cpp | 12 ++--- src/os/macos/bridge.hpp | 7 +-- src/os/macos/bridge.mm | 98 +++++++++++++++++++++++++++-------------- 4 files changed, 79 insertions(+), 42 deletions(-) diff --git a/src/os/linux.cpp b/src/os/linux.cpp index aa02ef9..627aae3 100644 --- a/src/os/linux.cpp +++ b/src/os/linux.cpp @@ -142,7 +142,7 @@ namespace { if (getsockopt(fileDescriptor, SOL_SOCKET, SO_PEERCRED, &cred, &len) == -1) return Err(DracError("Failed to get socket credentials (SO_PEERCRED)")); - Array exeLinkPathBuf; + Array exeLinkPathBuf {}; auto [out, size] = std::format_to_n(exeLinkPathBuf.data(), exeLinkPathBuf.size() - 1, "/proc/{}/exe", cred.pid); @@ -153,7 +153,7 @@ namespace { const char* exeLinkPath = exeLinkPathBuf.data(); - Array exeRealPathBuf; // NOLINT(misc-include-cleaner) - PATH_MAX is in + Array exeRealPathBuf {}; // NOLINT(misc-include-cleaner) - PATH_MAX is in const isize bytesRead = readlink(exeLinkPath, exeRealPathBuf.data(), exeRealPathBuf.size() - 1); diff --git a/src/os/macos.cpp b/src/os/macos.cpp index b37c593..c2e9cfc 100644 --- a/src/os/macos.cpp +++ b/src/os/macos.cpp @@ -1,9 +1,9 @@ #ifdef __APPLE__ // clang-format off -#include -#include -#include +#include // std::flat_map +#include // statvfs +#include // {CTL_KERN, KERN_PROC, KERN_PROC_ALL, kinfo_proc, sysctl, sysctlbyname} #include "src/core/package.hpp" #include "src/util/defs.hpp" @@ -292,8 +292,10 @@ namespace os { if (statvfs("/", &vfs) != 0) return Err(DracError("Failed to get disk usage")); - return DiskSpace { .usedBytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize, - .totalBytes = vfs.f_blocks * vfs.f_frsize }; + return DiskSpace { + .usedBytes = (vfs.f_blocks - vfs.f_bfree) * vfs.f_frsize, + .totalBytes = vfs.f_blocks * vfs.f_frsize, + }; } fn GetShell() -> Result { diff --git a/src/os/macos/bridge.hpp b/src/os/macos/bridge.hpp index 14d2e2f..e6a4432 100644 --- a/src/os/macos/bridge.hpp +++ b/src/os/macos/bridge.hpp @@ -7,15 +7,16 @@ #include "src/util/error.hpp" #include "src/util/types.hpp" // clang-format on + using util::error::DracError; using util::types::MediaInfo, util::types::String, util::types::Result; #ifdef __OBJC__ - #import + #import // Foundation @interface Bridge : NSObject -+ (void)fetchCurrentPlayingMetadata:(void (^)(Result))completion; -+ (Result)macOSVersion; ++ (void)fetchCurrentPlayingMetadata:(void (^_Nonnull)(NSDictionary* __nullable, NSError* __nullable))completion; ++ (NSString* __nullable)macOSVersion; @end #else extern "C++" { diff --git a/src/os/macos/bridge.mm b/src/os/macos/bridge.mm index 51b3452..55a2054 100644 --- a/src/os/macos/bridge.mm +++ b/src/os/macos/bridge.mm @@ -4,30 +4,34 @@ #import "bridge.hpp" #import +#import + #include #include #include -#import #include #include #include "src/util/error.hpp" // clang-format on -using util::error::DracErrorCode; -using util::types::Err, util::types::Option, util::types::None; +using util::error::DracError, util::error::DracErrorCode; +using util::types::Err, util::types::Option, util::types::None, util::types::Result; using MRMediaRemoteGetNowPlayingInfoFunction = void (*)(dispatch_queue_t queue, void (^handler)(NSDictionary* information)); @implementation Bridge -+ (void)fetchCurrentPlayingMetadata:(void (^)(std::expected))completion { ++ (void)fetchCurrentPlayingMetadata:(void (^)(NSDictionary* __nullable, NSError* __nullable))completion { CFURLRef urlRef = CFURLCreateWithFileSystemPath( - kCFAllocatorDefault, CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"), kCFURLPOSIXPathStyle, false + kCFAllocatorDefault, + CFSTR("/System/Library/PrivateFrameworks/MediaRemote.framework"), + kCFURLPOSIXPathStyle, + false ); if (!urlRef) { - completion(std::unexpected("Failed to create CFURL for MediaRemote framework")); + completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to create CFURL for MediaRemote framework" }]); return; } @@ -36,7 +40,7 @@ using MRMediaRemoteGetNowPlayingInfoFunction = CFRelease(urlRef); if (!bundleRef) { - completion(std::unexpected("Failed to create bundle for MediaRemote framework")); + completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to create bundle for MediaRemote framework" }]); return; } @@ -46,7 +50,7 @@ using MRMediaRemoteGetNowPlayingInfoFunction = if (!mrMediaRemoteGetNowPlayingInfo) { CFRelease(bundleRef); - completion(std::unexpected("Failed to get MRMediaRemoteGetNowPlayingInfo function pointer")); + completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@{ NSLocalizedDescriptionKey : @"Failed to get MRMediaRemoteGetNowPlayingInfo function pointer" }]); return; } @@ -58,34 +62,54 @@ using MRMediaRemoteGetNowPlayingInfoFunction = mrMediaRemoteGetNowPlayingInfo( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(NSDictionary* information) { - completion( - information ? std::expected(information) - : std::unexpected("No now playing information") - ); + if (!information) { + completion(nil, [NSError errorWithDomain:@"com.draconis.error" code:1 userInfo:@ { NSLocalizedDescriptionKey : @"No now playing information" }]); + return; + } + + completion(information, nil); } ); } -+ (Result)macOSVersion { - NSProcessInfo* processInfo = [NSProcessInfo processInfo]; - NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion]; ++ (NSString*)macOSVersion { + NSProcessInfo* processInfo = [NSProcessInfo processInfo]; + if (!processInfo) + return nil; + + NSOperatingSystemVersion osVersion = [processInfo operatingSystemVersion]; + if (osVersion.majorVersion == 0) + return nil; NSString* versionNumber = nil; - if (osVersion.patchVersion == 0) { - versionNumber = [NSString stringWithFormat:@"%ld.%ld", osVersion.majorVersion, osVersion.minorVersion]; - } else { - versionNumber = [NSString - stringWithFormat:@"%ld.%ld.%ld", osVersion.majorVersion, osVersion.minorVersion, osVersion.patchVersion]; - } + if (osVersion.patchVersion == 0) + versionNumber = [NSString stringWithFormat:@"%ld.%ld", + osVersion.majorVersion, + osVersion.minorVersion]; + else + versionNumber = [NSString stringWithFormat:@"%ld.%ld.%ld", + osVersion.majorVersion, + osVersion.minorVersion, + osVersion.patchVersion]; + + if (!versionNumber) + return nil; NSDictionary* versionNames = - @{ @11 : @"Big Sur", @12 : @"Monterey", @13 : @"Ventura", @14 : @"Sonoma", @15 : @"Sequoia" }; + @{ + @11 : @"Big Sur", + @12 : @"Monterey", + @13 : @"Ventura", + @14 : @"Sonoma", + @15 : @"Sequoia" + }; NSNumber* majorVersion = @(osVersion.majorVersion); NSString* versionName = versionNames[majorVersion] ? versionNames[majorVersion] : @"Unknown"; NSString* fullVersion = [NSString stringWithFormat:@"macOS %@ %@", versionNumber, versionName]; - return String([fullVersion UTF8String]); + + return fullVersion ? fullVersion : nil; } @end @@ -96,25 +120,29 @@ extern "C++" { const dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - [Bridge fetchCurrentPlayingMetadata:^(std::expected metadataResult) { - if (!metadataResult) { - result = Err(DracError(DracErrorCode::InternalError, metadataResult.error())); + [Bridge fetchCurrentPlayingMetadata:^(NSDictionary* __nullable information, NSError* __nullable error) { + if (error) { + result = Err(DracError(DracErrorCode::InternalError, [error.localizedDescription UTF8String])); dispatch_semaphore_signal(semaphore); return; } - const NSDictionary* const metadata = *metadataResult; - if (!metadata) { + if (!information) { result = Err(DracError(DracErrorCode::InternalError, "No metadata")); dispatch_semaphore_signal(semaphore); return; } - const NSString* const title = metadata[@"kMRMediaRemoteNowPlayingInfoTitle"]; - const NSString* const artist = metadata[@"kMRMediaRemoteNowPlayingInfoArtist"]; + const NSString* const title = information[@"kMRMediaRemoteNowPlayingInfoTitle"]; + const NSString* const artist = information[@"kMRMediaRemoteNowPlayingInfoArtist"]; result = MediaInfo( - title ? Option(String([title UTF8String])) : None, artist ? Option(String([artist UTF8String])) : None + title + ? Option(String([title UTF8String])) + : None, + artist + ? Option(String([artist UTF8String])) + : None ); dispatch_semaphore_signal(semaphore); @@ -124,7 +152,13 @@ extern "C++" { return result; } - fn GetMacOSVersion() -> Result { return [Bridge macOSVersion]; } + fn GetMacOSVersion() -> Result { + NSString* version = [Bridge macOSVersion]; + + return version + ? Result(String([version UTF8String])) + : Err(DracError(DracErrorCode::InternalError, "Failed to get macOS version")); + } // NOLINTEND(misc-use-internal-linkage) }