darwin-proctitle.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
  2. * Permission is hereby granted, free of charge, to any person obtaining a copy
  3. * of this software and associated documentation files (the "Software"), to
  4. * deal in the Software without restriction, including without limitation the
  5. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  6. * sell copies of the Software, and to permit persons to whom the Software is
  7. * furnished to do so, subject to the following conditions:
  8. *
  9. * The above copyright notice and this permission notice shall be included in
  10. * all copies or substantial portions of the Software.
  11. *
  12. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  18. * IN THE SOFTWARE.
  19. */
  20. #include "uv.h"
  21. #include "internal.h"
  22. #include <dlfcn.h>
  23. #include <errno.h>
  24. #include <pthread.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <TargetConditionals.h>
  28. #if !TARGET_OS_IPHONE
  29. # include <CoreFoundation/CoreFoundation.h>
  30. # include <ApplicationServices/ApplicationServices.h>
  31. #endif
  32. static int uv__pthread_setname_np(const char* name) {
  33. char namebuf[64]; /* MAXTHREADNAMESIZE */
  34. int err;
  35. strncpy(namebuf, name, sizeof(namebuf) - 1);
  36. namebuf[sizeof(namebuf) - 1] = '\0';
  37. err = pthread_setname_np(namebuf);
  38. if (err)
  39. return UV__ERR(err);
  40. return 0;
  41. }
  42. int uv__set_process_title(const char* title) {
  43. #if TARGET_OS_IPHONE
  44. return uv__pthread_setname_np(title);
  45. #else
  46. CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
  47. const char*,
  48. CFStringEncoding);
  49. CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
  50. void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
  51. void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
  52. CFTypeRef (*pLSGetCurrentApplicationASN)(void);
  53. OSStatus (*pLSSetApplicationInformationItem)(int,
  54. CFTypeRef,
  55. CFStringRef,
  56. CFStringRef,
  57. CFDictionaryRef*);
  58. void* application_services_handle;
  59. void* core_foundation_handle;
  60. CFBundleRef launch_services_bundle;
  61. CFStringRef* display_name_key;
  62. CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
  63. CFBundleRef (*pCFBundleGetMainBundle)(void);
  64. CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
  65. void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
  66. void*);
  67. CFTypeRef asn;
  68. int err;
  69. err = UV_ENOENT;
  70. application_services_handle = dlopen("/System/Library/Frameworks/"
  71. "ApplicationServices.framework/"
  72. "Versions/A/ApplicationServices",
  73. RTLD_LAZY | RTLD_LOCAL);
  74. core_foundation_handle = dlopen("/System/Library/Frameworks/"
  75. "CoreFoundation.framework/"
  76. "Versions/A/CoreFoundation",
  77. RTLD_LAZY | RTLD_LOCAL);
  78. if (application_services_handle == NULL || core_foundation_handle == NULL)
  79. goto out;
  80. *(void **)(&pCFStringCreateWithCString) =
  81. dlsym(core_foundation_handle, "CFStringCreateWithCString");
  82. *(void **)(&pCFBundleGetBundleWithIdentifier) =
  83. dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
  84. *(void **)(&pCFBundleGetDataPointerForName) =
  85. dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
  86. *(void **)(&pCFBundleGetFunctionPointerForName) =
  87. dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
  88. if (pCFStringCreateWithCString == NULL ||
  89. pCFBundleGetBundleWithIdentifier == NULL ||
  90. pCFBundleGetDataPointerForName == NULL ||
  91. pCFBundleGetFunctionPointerForName == NULL) {
  92. goto out;
  93. }
  94. #define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
  95. launch_services_bundle =
  96. pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices"));
  97. if (launch_services_bundle == NULL)
  98. goto out;
  99. *(void **)(&pLSGetCurrentApplicationASN) =
  100. pCFBundleGetFunctionPointerForName(launch_services_bundle,
  101. S("_LSGetCurrentApplicationASN"));
  102. if (pLSGetCurrentApplicationASN == NULL)
  103. goto out;
  104. *(void **)(&pLSSetApplicationInformationItem) =
  105. pCFBundleGetFunctionPointerForName(launch_services_bundle,
  106. S("_LSSetApplicationInformationItem"));
  107. if (pLSSetApplicationInformationItem == NULL)
  108. goto out;
  109. display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle,
  110. S("_kLSDisplayNameKey"));
  111. if (display_name_key == NULL || *display_name_key == NULL)
  112. goto out;
  113. *(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle,
  114. "CFBundleGetInfoDictionary");
  115. *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
  116. "CFBundleGetMainBundle");
  117. if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
  118. goto out;
  119. *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
  120. launch_services_bundle,
  121. S("_LSApplicationCheckIn"));
  122. if (pLSApplicationCheckIn == NULL)
  123. goto out;
  124. *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
  125. pCFBundleGetFunctionPointerForName(
  126. launch_services_bundle,
  127. S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
  128. if (pLSSetApplicationLaunchServicesServerConnectionStatus == NULL)
  129. goto out;
  130. pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL);
  131. /* Check into process manager?! */
  132. pLSApplicationCheckIn(-2,
  133. pCFBundleGetInfoDictionary(pCFBundleGetMainBundle()));
  134. asn = pLSGetCurrentApplicationASN();
  135. err = UV_EBUSY;
  136. if (asn == NULL)
  137. goto out;
  138. err = UV_EINVAL;
  139. if (pLSSetApplicationInformationItem(-2, /* Magic value. */
  140. asn,
  141. *display_name_key,
  142. S(title),
  143. NULL) != noErr) {
  144. goto out;
  145. }
  146. uv__pthread_setname_np(title); /* Don't care if it fails. */
  147. err = 0;
  148. out:
  149. if (core_foundation_handle != NULL)
  150. dlclose(core_foundation_handle);
  151. if (application_services_handle != NULL)
  152. dlclose(application_services_handle);
  153. return err;
  154. #endif /* !TARGET_OS_IPHONE */
  155. }