1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "ProcessUtils.h"
7 #include "nsObjCExceptions.h"
8 #include "nsCocoaUtils.h"
10 #include "mozilla/Sprintf.h"
12 #define UNDOCUMENTED_SESSION_CONSTANT ((int)-2)
17 static void* sApplicationASN = NULL;
18 static void* sApplicationInfoItem = NULL;
20 void SetThisProcessName(const char* aProcessName) {
21 NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
22 nsAutoreleasePool localPool;
24 if (!aProcessName || strcmp(aProcessName, "") == 0) {
28 NSString* currentName = [[[NSBundle mainBundle] localizedInfoDictionary]
29 objectForKey:(NSString*)kCFBundleNameKey];
31 char formattedName[1024];
32 SprintfLiteral(formattedName, "%s %s", [currentName UTF8String],
35 aProcessName = formattedName;
37 // This function is based on Chrome/Webkit's and relies on potentially
39 typedef CFTypeRef (*LSGetASNType)();
40 typedef OSStatus (*LSSetInformationItemType)(int, CFTypeRef, CFStringRef,
41 CFStringRef, CFDictionaryRef*);
43 CFBundleRef launchServices =
44 ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
45 if (!launchServices) {
47 "Failed to set process name: Could not open LaunchServices bundle");
51 if (!sApplicationASN) {
52 sApplicationASN = ::CFBundleGetFunctionPointerForName(
53 launchServices, CFSTR("_LSGetCurrentApplicationASN"));
54 if (!sApplicationASN) {
55 NS_WARNING("Failed to set process name: Could not get function pointer "
56 "for LaunchServices");
61 LSGetASNType getASNFunc = reinterpret_cast<LSGetASNType>(sApplicationASN);
63 if (!sApplicationInfoItem) {
64 sApplicationInfoItem = ::CFBundleGetFunctionPointerForName(
65 launchServices, CFSTR("_LSSetApplicationInformationItem"));
68 LSSetInformationItemType setInformationItemFunc =
69 reinterpret_cast<LSSetInformationItemType>(sApplicationInfoItem);
71 void* displayNameKeyAddr = ::CFBundleGetDataPointerForName(
72 launchServices, CFSTR("_kLSDisplayNameKey"));
74 CFStringRef displayNameKey = nil;
75 if (displayNameKeyAddr) {
77 reinterpret_cast<CFStringRef>(*(CFStringRef*)displayNameKeyAddr);
80 // We need this to ensure we have a connection to the Process Manager, not
81 // doing so will silently fail and process name wont be updated.
82 ProcessSerialNumber psn;
83 if (::GetCurrentProcess(&psn) != noErr) {
87 CFTypeRef currentAsn = getASNFunc ? getASNFunc() : nullptr;
89 if (!getASNFunc || !setInformationItemFunc || !displayNameKey ||
91 NS_WARNING("Failed to set process name: Accessing launchServices failed");
95 CFStringRef processName =
96 ::CFStringCreateWithCString(nil, aProcessName, kCFStringEncodingASCII);
98 NS_WARNING("Failed to set process name: Could not create CFStringRef");
102 OSErr err = setInformationItemFunc(UNDOCUMENTED_SESSION_CONSTANT, currentAsn,
103 displayNameKey, processName,
104 nil); // Optional out param
105 ::CFRelease(processName);
107 NS_WARNING("Failed to set process name: LSSetInformationItemType err");
112 NS_OBJC_END_TRY_ABORT_BLOCK;
116 } // namespace mozilla