commit 7a356c7: [Minor] Try better to set proctitle on darwin
Vsevolod Stakhov
vsevolod at highsecure.ru
Sun Jul 14 08:56:04 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-07-14 09:54:20 +0100
URL: https://github.com/rspamd/rspamd/commit/7a356c782ee05cf9b942e92e381f453d205a9cc1 (HEAD -> master)
[Minor] Try better to set proctitle on darwin
---
src/libutil/util.c | 340 ++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 274 insertions(+), 66 deletions(-)
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 1f83194ad..86358e46e 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -785,102 +785,221 @@ rspamd_pass_signal (GHashTable * workers, gint signo)
#ifndef HAVE_SETPROCTITLE
-#if !defined(DARWIN) && !defined(SOLARIS) && !defined(__APPLE__)
+#ifdef LINUX
static gchar *title_buffer = 0;
static size_t title_buffer_size = 0;
static gchar *title_progname, *title_progname_full;
#endif
-gint
-setproctitle (const gchar *fmt, ...)
+#ifdef LINUX
+static void
+rspamd_title_dtor (gpointer d)
{
-#if defined(DARWIN) || defined(SOLARIS) || defined(__APPLE__)
- GString *dest;
- va_list ap;
+ gchar **env = (gchar **)d;
+ guint i;
- dest = g_string_new ("");
- va_start (ap, fmt);
- rspamd_vprintf_gstring (dest, fmt, ap);
- va_end (ap);
+ for (i = 0; env[i] != NULL; i++) {
+ g_free (env[i]);
+ }
- g_set_prgname (dest->str);
- g_string_free (dest, TRUE);
+ g_free (env);
+}
+#endif
- return 0;
-#else
- if (!title_buffer || !title_buffer_size) {
- errno = ENOMEM;
- return -1;
+#ifdef __APPLE__
+
+/* Code is based on darwin-proctitle.c used almost everywhere */
+
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <dlfcn.h>
+#include <TargetConditionals.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+/* Darwin is just brain damaged */
+static int (*dynamic_pthread_setname_np)(const char* name);
+static CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
+ const char*,
+ CFStringEncoding);
+static CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef);
+static void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef);
+static void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef);
+static CFTypeRef (*pLSGetCurrentApplicationASN)(void);
+static OSStatus (*pLSSetApplicationInformationItem)(int,
+ CFTypeRef,
+ CFStringRef,
+ CFStringRef,
+ CFDictionaryRef*);
+static CFBundleRef launch_services_bundle;
+static CFStringRef* display_name_key;
+static CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef);
+static CFBundleRef (*pCFBundleGetMainBundle)(void);
+static CFBundleRef hi_services_bundle;
+static OSStatus (*pSetApplicationIsDaemon)(int);
+static CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef);
+static void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t,
+ void*);
+#define APPLE_S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8)
+/* Dlfunc handles */
+struct rspamd_osx_handles {
+ gpointer application_services_handle;
+ gpointer core_foundation_handle;
+};
+
+static
+void rspamd_darwin_title_dtor (void *ud)
+{
+ struct rspamd_osx_handles *hdls = (struct rspamd_osx_handles *)ud;
+
+ if (hdls->core_foundation_handle != NULL) {
+ dlclose (hdls->core_foundation_handle);
}
- memset (title_buffer, '\0', title_buffer_size);
+ if (hdls->application_services_handle != NULL) {
+ dlclose (hdls->application_services_handle);
+ }
+}
- ssize_t written;
+static void
+rspamd_darwin_init_title (struct rspamd_main *rspamd_main)
+{
+ struct rspamd_osx_handles *hdls;
+ /* Assumed that pthreads are already linked */
+ *(void **)(&dynamic_pthread_setname_np) =
+ dlsym (RTLD_DEFAULT, "pthread_setname_np");
+
+ hdls = rspamd_mempool_alloc0 (rspamd_main->server_pool, sizeof (*hdls));
+
+ hdls->application_services_handle = dlopen("/System/Library/Frameworks/"
+ "ApplicationServices.framework/"
+ "Versions/A/ApplicationServices",
+ RTLD_LAZY | RTLD_LOCAL);
+ hdls->core_foundation_handle = dlopen("/System/Library/Frameworks/"
+ "CoreFoundation.framework/"
+ "Versions/A/CoreFoundation",
+ RTLD_LAZY | RTLD_LOCAL);
+
+ if (hdls->application_services_handle == NULL ||
+ hdls->core_foundation_handle == NULL) {
+ goto out;
+ }
- if (fmt) {
- ssize_t written2;
- va_list ap;
+ /* Fill procedures via dlsym */
+ *(void **)(&pCFStringCreateWithCString) =
+ dlsym (hdls->core_foundation_handle, "CFStringCreateWithCString");
+ *(void **)(&pCFBundleGetBundleWithIdentifier) =
+ dlsym (hdls->core_foundation_handle, "CFBundleGetBundleWithIdentifier");
+ *(void **)(&pCFBundleGetDataPointerForName) =
+ dlsym (hdls->core_foundation_handle, "CFBundleGetDataPointerForName");
+ *(void **)(&pCFBundleGetFunctionPointerForName) =
+ dlsym (hdls->core_foundation_handle, "CFBundleGetFunctionPointerForName");
+
+ if (pCFStringCreateWithCString == NULL ||
+ pCFBundleGetBundleWithIdentifier == NULL ||
+ pCFBundleGetDataPointerForName == NULL ||
+ pCFBundleGetFunctionPointerForName == NULL) {
+ goto out;
+ }
- written = snprintf (title_buffer,
- title_buffer_size,
- "%s: ",
- title_progname);
- if (written < 0 || (size_t) written >= title_buffer_size)
- return -1;
+ launch_services_bundle =
+ pCFBundleGetBundleWithIdentifier(APPLE_S("com.apple.LaunchServices"));
- va_start (ap, fmt);
- written2 = vsnprintf (title_buffer + written,
- title_buffer_size - written,
- fmt,
- ap);
- va_end (ap);
- if (written2 < 0 || (size_t) written2 >= title_buffer_size - written)
- return -1;
+ if (launch_services_bundle == NULL) {
+ goto out;
}
- else {
- written = snprintf (title_buffer,
- title_buffer_size,
- "%s",
- title_progname);
- if (written < 0 || (size_t) written >= title_buffer_size)
- return -1;
+
+ *(void **)(&pLSGetCurrentApplicationASN) =
+ pCFBundleGetFunctionPointerForName(launch_services_bundle,
+ APPLE_S("_LSGetCurrentApplicationASN"));
+
+ if (pLSGetCurrentApplicationASN == NULL) {
+ goto out;
}
- written = strlen (title_buffer);
- memset (title_buffer + written, '\0', title_buffer_size - written);
+ *(void **)(&pLSSetApplicationInformationItem) =
+ pCFBundleGetFunctionPointerForName(launch_services_bundle,
+ APPLE_S("_LSSetApplicationInformationItem"));
- return 0;
-#endif
-}
+ if (pLSSetApplicationInformationItem == NULL) {
+ goto out;
+ }
-#if !(defined(DARWIN) || defined(SOLARIS) || defined(__APPLE__))
-static void
-rspamd_title_dtor (gpointer d)
-{
- gchar **env = (gchar **)d;
- guint i;
+ display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle,
+ APPLE_S("_kLSDisplayNameKey"));
- for (i = 0; env[i] != NULL; i++) {
- g_free (env[i]);
+ if (display_name_key == NULL || *display_name_key == NULL) {
+ goto out;
}
- g_free (env);
+ *(void **)(&pCFBundleGetInfoDictionary) = dlsym (hdls->core_foundation_handle,
+ "CFBundleGetInfoDictionary");
+ *(void **)(&pCFBundleGetMainBundle) = dlsym (hdls->core_foundation_handle,
+ "CFBundleGetMainBundle");
+
+ if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) {
+ goto out;
+ }
+
+ /* Black 10.9 magic, to remove (Not responding) mark in Activity Monitor */
+ hi_services_bundle =
+ pCFBundleGetBundleWithIdentifier(APPLE_S("com.apple.HIServices"));
+
+ if (hi_services_bundle == NULL) {
+ goto out;
+ }
+
+ *(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
+ hi_services_bundle,
+ APPLE_S("SetApplicationIsDaemon"));
+ *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
+ launch_services_bundle,
+ APPLE_S("_LSApplicationCheckIn"));
+ *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
+ pCFBundleGetFunctionPointerForName(
+ launch_services_bundle,
+ APPLE_S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
+
+ if (pSetApplicationIsDaemon == NULL ||
+ pLSApplicationCheckIn == NULL ||
+ pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) {
+ goto out;
+ }
+
+ rspamd_mempool_add_destructor (rspamd_main->server_pool,
+ rspamd_darwin_title_dtor, hdls);
+
+ return;
+
+out:
+ rspamd_darwin_title_dtor (hdls);
}
-#endif
-/*
- It has to be _init function, because __attribute__((constructor))
- functions gets called without arguments.
- */
+#endif
gint
init_title (struct rspamd_main *rspamd_main,
gint argc, gchar *argv[], gchar *envp[])
{
-#if defined(DARWIN) || defined(SOLARIS) || defined(__APPLE__)
- /* XXX: try to handle these OSes too */
- return 0;
-#else
+#ifdef LINUX
gchar *begin_of_buffer = 0, *end_of_buffer = 0;
gint i;
@@ -936,10 +1055,99 @@ init_title (struct rspamd_main *rspamd_main,
rspamd_mempool_add_destructor (rspamd_main->server_pool,
rspamd_title_dtor, new_environ);
+#elif defined(__APPLE__)
+ rspamd_darwin_init_title (rspamd_main);
+#endif
return 0;
+}
+
+gint
+setproctitle (const gchar *fmt, ...)
+{
+#if defined(LINUX)
+ if (!title_buffer || !title_buffer_size) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ memset (title_buffer, '\0', title_buffer_size);
+
+ ssize_t written;
+
+ if (fmt) {
+ ssize_t written2;
+ va_list ap;
+
+ written = rspamd_snprintf (title_buffer,
+ title_buffer_size,
+ "%s: ",
+ title_progname);
+ if (written < 0 || (size_t) written >= title_buffer_size)
+ return -1;
+
+ va_start (ap, fmt);
+ written2 = rspamd_vsnprintf (title_buffer + written,
+ title_buffer_size - written,
+ fmt,
+ ap);
+ va_end (ap);
+ if (written2 < 0 || (size_t) written2 >= title_buffer_size - written)
+ return -1;
+ }
+ else {
+ written = rspamd_snprintf (title_buffer,
+ title_buffer_size,
+ "%s",
+ title_progname);
+ if (written < 0 || (size_t) written >= title_buffer_size)
+ return -1;
+ }
+
+ written = strlen (title_buffer);
+ memset (title_buffer + written, '\0', title_buffer_size - written);
+#elif defined(__APPLE__)
+ static gchar titlebuf[128];
+
+ va_list ap;
+ int r;
+ va_start (ap, fmt);
+ r = rspamd_snprintf (titlebuf, sizeof (titlebuf), "rspamd: ");
+ rspamd_vsnprintf (titlebuf + r, sizeof (titlebuf) - r, fmt, ap);
+ va_end (ap);
+
+ if (pSetApplicationIsDaemon != NULL && pSetApplicationIsDaemon (1) != noErr) {
+ CFTypeRef asn;
+ pLSSetApplicationLaunchServicesServerConnectionStatus (0, NULL);
+ pLSApplicationCheckIn (/* Magic value */ -2,
+ pCFBundleGetInfoDictionary (pCFBundleGetMainBundle()));
+ asn = pLSGetCurrentApplicationASN ();
+ pLSSetApplicationInformationItem (/* Magic value */ -2, asn,
+ *display_name_key, APPLE_S (titlebuf), NULL);
+ }
+
+ if (dynamic_pthread_setname_np != NULL) {
+ char namebuf[64]; /* MAXTHREADNAMESIZE */
+ rspamd_strlcpy (namebuf, titlebuf, sizeof(namebuf));
+ dynamic_pthread_setname_np (namebuf);
+ }
+#else
+ /* Last resort (usually broken, but eh...) */
+ GString *dest;
+ va_list ap;
+
+ dest = g_string_new ("");
+ va_start (ap, fmt);
+ rspamd_vprintf_gstring (dest, fmt, ap);
+ va_end (ap);
+
+ g_set_prgname (dest->str);
+ g_string_free (dest, TRUE);
+
#endif
+ return 0;
}
+
#endif
#ifndef HAVE_PIDFILE
More information about the Commits
mailing list