Mercurial > dovecot > core-2.2
changeset 10188:affb52c62add HEAD
Fixed Linux proctitle hack and enabled it by default now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 26 Oct 2009 18:52:10 -0400 |
parents | 34aa0445aa14 |
children | 582659cebfdf |
files | configure.in src/lib-master/master-service.c src/lib/process-title.c src/lib/process-title.h src/util/rawlog.c |
diffstat | 5 files changed, 72 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Mon Oct 26 18:04:13 2009 -0400 +++ b/configure.in Mon Oct 26 18:52:10 2009 -0400 @@ -588,6 +588,9 @@ LIBS="-lxnet $LIBS" AC_DEFINE(PREAD_BROKEN,, Defint if pread/pwrite implementation is broken) ;; + linux*) + AC_DEFINE(PROCTITLE_HACK,, Define if process title can be changed by modifying argv) + ;; *) ;; esac
--- a/src/lib-master/master-service.c Mon Oct 26 18:04:13 2009 -0400 +++ b/src/lib-master/master-service.c Mon Oct 26 18:52:10 2009 -0400 @@ -85,7 +85,6 @@ master_service_init(const char *name, enum master_service_flags flags, int *argc, char **argv[], const char *getopt_str) { - extern char **environ; struct master_service *service; const char *str; @@ -112,7 +111,7 @@ if (getenv(MASTER_UID_ENV) == NULL) flags |= MASTER_SERVICE_FLAG_STANDALONE; - process_title_init(argv, environ); + process_title_init(argv); service = i_new(struct master_service, 1); service->argc = *argc;
--- a/src/lib/process-title.c Mon Oct 26 18:04:13 2009 -0400 +++ b/src/lib/process-title.c Mon Oct 26 18:52:10 2009 -0400 @@ -1,51 +1,55 @@ /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */ -/* - LINUX_PROCTITLE_HACK code from: - http://lightconsulting.com/~thalakan/process-title-notes.html -*/ - #include "lib.h" #include "process-title.h" #include <stdlib.h> /* NetBSD, OpenBSD */ #include <unistd.h> /* FreeBSD */ -/* NOTE: This really is a horrible hack, I don't recommend using it for - anything else than debugging. */ -/*#define LINUX_PROCTITLE_HACK*/ - static char *process_name = NULL; -#ifdef LINUX_PROCTITLE_HACK +#ifdef HAVE_SETPROCTITLE +# undef PROCTITLE_HACK +#endif + +#ifdef PROCTITLE_HACK + +#define PROCTITLE_CLEAR_CHAR 0xab + static char *process_title; -static size_t process_title_len; +static size_t process_title_len, process_title_clean_pos; -static void linux_proctitle_init(char *argv[], char *envp[]) +static void proctitle_hack_init(char *argv[], char *env[]) { - extern char **environ; - char **p; - int i; - - /* copy environment elsewhere */ - for (i = 0; envp[i] != NULL; i++) - ; + char *last; + unsigned int i; + bool clear_env; - if ((p = malloc((i + 1) * sizeof(char *))) == NULL) - i_fatal_status(FATAL_OUTOFMEM, "malloc() failed: %m"); - environ = p; - - for (i = 0; envp[i] != NULL; i++) { - if ((environ[i] = strdup(envp[i])) == NULL) - i_fatal_status(FATAL_OUTOFMEM, "strdup() failed: %m"); + /* find the last argv or environment string. it should always be the + last string in environ, but don't rely on it. this is what openssh + does, so hopefully it's safe enough. */ + last = argv[0] + strlen(argv[0]) + 1; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i] == last) + last = argv[i] + strlen(argv[i]) + 1; + } + clear_env = last == env[0]; + for (i = 0; env[i] != NULL; i++) { + if (env[i] == last) + last = env[i] + strlen(env[i]) + 1; } - environ[i] = NULL; + + process_title = argv[0]; + process_title_len = last - argv[0]; - /* memory is allocated so that argv[] comes first, environment next. - Calculate the max. size for process name with by checking the - address for last environment and it's length. */ - process_title = argv[0]; - process_title_len = (size_t) (envp[i-1] - argv[0]) + strlen(envp[i-1]); + /* if there are problems with this approach, try to make sure we + notice it */ + if (clear_env) { + memset(env[0], PROCTITLE_CLEAR_CHAR, last - env[0]); + process_title_clean_pos = env[0] - process_title; + } else { + process_title_clean_pos = 0; + } } static char **argv_dup(char *old_argv[]) @@ -56,6 +60,8 @@ for (count = 0; old_argv[count] != NULL; count++) ; new_argv = malloc(sizeof(char *) * (count + 1)); + if (new_argv == NULL) + i_fatal_status(FATAL_OUTOFMEM, "malloc() failed: %m"); for (i = 0; i < count; i++) { new_argv[i] = strdup(old_argv[i]); if (new_argv[i] == NULL) @@ -65,18 +71,37 @@ return new_argv; } -static void linux_proctitle_set(const char *title) +static void proctitle_hack_set(const char *title) { - i_strocpy(process_title, title, process_title_len); + size_t len = strlen(title); + + if (len >= process_title_len) + len = process_title_len - 1; + + memcpy(process_title, title, len); + process_title[len++] = '\0'; + + if (len < process_title_clean_pos) { + memset(process_title + len, PROCTITLE_CLEAR_CHAR, + process_title_clean_pos - len); + process_title_clean_pos = len; + } else if (process_title_clean_pos != 0) { + process_title_clean_pos = len; + } } #endif -void process_title_init(char **argv[], char *envp[] ATTR_UNUSED) +void process_title_init(char **argv[]) { -#ifdef LINUX_PROCTITLE_HACK - *argv = argv_dup(*argv); - linux_proctitle_init(*argv, envp); +#ifdef PROCTITLE_HACK + extern char **environ; + char **orig_argv = *argv; + char **orig_environ = environ; + + *argv = argv_dup(orig_argv); + environ = argv_dup(orig_environ); + proctitle_hack_init(orig_argv, orig_environ); #endif process_name = (*argv)[0]; } @@ -90,7 +115,7 @@ setproctitle(NULL); else setproctitle("%s", title); -#elif defined(LINUX_PROCTITLE_HACK) - linux_proctitle_set(t_strconcat(process_name, " ", title, NULL)); +#elif defined(PROCTITLE_HACK) + proctitle_hack_set(t_strconcat(process_name, " ", title, NULL)); #endif }
--- a/src/lib/process-title.h Mon Oct 26 18:04:13 2009 -0400 +++ b/src/lib/process-title.h Mon Oct 26 18:52:10 2009 -0400 @@ -2,7 +2,7 @@ #define PROCESS_TITLE_H /* Initialize title changing. */ -void process_title_init(char **argv[], char *envp[]); +void process_title_init(char **argv[]); /* Change the process title if possible. */ void process_title_set(const char *title);
--- a/src/util/rawlog.c Mon Oct 26 18:04:13 2009 -0400 +++ b/src/util/rawlog.c Mon Oct 26 18:52:10 2009 -0400 @@ -339,7 +339,7 @@ exit(0); } -int main(int argc, char *argv[], char *envp[]) +int main(int argc, char *argv[]) { char *executable, *p; enum rawlog_flags flags; @@ -348,7 +348,7 @@ lib_init(); i_set_failure_internal(); - process_title_init(&argv, envp); + process_title_init(&argv); argc--; argv++;