summaryrefslogtreecommitdiffstats
path: root/ipc/glue/ProcessUtils_mac.mm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /ipc/glue/ProcessUtils_mac.mm
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/glue/ProcessUtils_mac.mm')
-rw-r--r--ipc/glue/ProcessUtils_mac.mm109
1 files changed, 109 insertions, 0 deletions
diff --git a/ipc/glue/ProcessUtils_mac.mm b/ipc/glue/ProcessUtils_mac.mm
new file mode 100644
index 0000000000..0f1d8ecbba
--- /dev/null
+++ b/ipc/glue/ProcessUtils_mac.mm
@@ -0,0 +1,109 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ProcessUtils.h"
+
+#include "nsObjCExceptions.h"
+#include "nsCocoaUtils.h"
+#include "nsString.h"
+#include "mozilla/Sprintf.h"
+
+#define UNDOCUMENTED_SESSION_CONSTANT ((int)-2)
+
+namespace mozilla {
+namespace ipc {
+
+static void* sApplicationASN = NULL;
+static void* sApplicationInfoItem = NULL;
+
+void SetThisProcessName(const char* aProcessName) {
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
+ nsAutoreleasePool localPool;
+
+ if (!aProcessName || strcmp(aProcessName, "") == 0) {
+ return;
+ }
+
+ NSString* currentName =
+ [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
+
+ char formattedName[1024];
+ SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName);
+
+ aProcessName = formattedName;
+
+ // This function is based on Chrome/Webkit's and relies on potentially dangerous SPI.
+ typedef CFTypeRef (*LSGetASNType)();
+ typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef, CFStringRef,
+ CFDictionaryRef*);
+
+ CFBundleRef launchServices = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
+ if (!launchServices) {
+ NS_WARNING("Failed to set process name: Could not open LaunchServices bundle");
+ return;
+ }
+
+ if (!sApplicationASN) {
+ sApplicationASN =
+ ::CFBundleGetFunctionPointerForName(launchServices, CFSTR("_LSGetCurrentApplicationASN"));
+ if (!sApplicationASN) {
+ NS_WARNING("Failed to set process name: Could not get function pointer "
+ "for LaunchServices");
+ return;
+ }
+ }
+
+ LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>(sApplicationASN);
+
+ if (!sApplicationInfoItem) {
+ sApplicationInfoItem = ::CFBundleGetFunctionPointerForName(
+ launchServices, CFSTR("_LSSetApplicationInformationItem"));
+ }
+
+ LSSetInformationItemType setInformationItemFunc =
+ reinterpret_cast<LSSetInformationItemType>(sApplicationInfoItem);
+
+ void* displayNameKeyAddr =
+ ::CFBundleGetDataPointerForName(launchServices, CFSTR("_kLSDisplayNameKey"));
+
+ CFStringRef displayNameKey = nil;
+ if (displayNameKeyAddr) {
+ displayNameKey = reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
+ }
+
+ // We need this to ensure we have a connection to the Process Manager, not
+ // doing so will silently fail and process name wont be updated.
+ ProcessSerialNumber psn;
+ if (::GetCurrentProcess(&psn) != noErr) {
+ return;
+ }
+
+ CFTypeRef currentAsn = getASNFunc ? getASNFunc() : nullptr;
+
+ if (!getASNFunc || !setInformationItemFunc || !displayNameKey || !currentAsn) {
+ NS_WARNING("Failed to set process name: Accessing launchServices failed");
+ return;
+ }
+
+ CFStringRef processName = ::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII);
+ if (!processName) {
+ NS_WARNING("Failed to set process name: Could not create CFStringRef");
+ return;
+ }
+
+ OSErr err =
+ setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn, displayNameKey, processName,
+ nil); // Optional out param
+ ::CFRelease(processName);
+ if (err != noErr) {
+ NS_WARNING("Failed to set process name: LSSetInformationItemType err");
+ return;
+ }
+
+ return;
+ NS_OBJC_END_TRY_ABORT_BLOCK;
+}
+
+} // namespace ipc
+} // namespace mozilla