dovecot-2.0: Fixed Linux proctitle hack and enabled it by defaul...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Oct 27 01:53:55 EET 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/affb52c62add
changeset: 10188:affb52c62add
user: Timo Sirainen <tss at iki.fi>
date: Mon Oct 26 18:52:10 2009 -0400
description:
Fixed Linux proctitle hack and enabled it by default now.
diffstat:
5 files changed, 71 insertions(+), 44 deletions(-)
configure.in | 3 +
src/lib-master/master-service.c | 3 -
src/lib/process-title.c | 103 ++++++++++++++++++++++++---------------
src/lib/process-title.h | 2
src/util/rawlog.c | 4 -
diffs (219 lines):
diff -r 34aa0445aa14 -r affb52c62add configure.in
--- a/configure.in Mon Oct 26 18:04:13 2009 -0400
+++ b/configure.in Mon Oct 26 18:52:10 2009 -0400
@@ -587,6 +587,9 @@ case "$host_os" in
LDFLAGS="$LDFLAGS -Wl,+b,:"
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)
;;
*)
;;
diff -r 34aa0445aa14 -r affb52c62add src/lib-master/master-service.c
--- 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, en
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 @@ master_service_init(const char *name, en
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;
diff -r 34aa0445aa14 -r affb52c62add src/lib/process-title.c
--- 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,9 +1,4 @@
/* 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"
@@ -11,41 +6,50 @@
#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;
+ char *last;
+ unsigned int i;
+ bool clear_env;
- /* copy environment elsewhere */
- for (i = 0; envp[i] != NULL; i++)
- ;
+ /* 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;
+ }
- if ((p = malloc((i + 1) * sizeof(char *))) == NULL)
- i_fatal_status(FATAL_OUTOFMEM, "malloc() failed: %m");
- environ = p;
+ process_title = argv[0];
+ process_title_len = last - argv[0];
- for (i = 0; envp[i] != NULL; i++) {
- if ((environ[i] = strdup(envp[i])) == NULL)
- i_fatal_status(FATAL_OUTOFMEM, "strdup() failed: %m");
+ /* 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;
}
- environ[i] = NULL;
-
- /* 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]);
}
static char **argv_dup(char *old_argv[])
@@ -56,6 +60,8 @@ static char **argv_dup(char *old_argv[])
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 @@ static char **argv_dup(char *old_argv[])
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 @@ void process_title_set(const char *title
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
}
diff -r 34aa0445aa14 -r affb52c62add src/lib/process-title.h
--- 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);
diff -r 34aa0445aa14 -r affb52c62add src/util/rawlog.c
--- 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 @@ static void rawlog_open(enum rawlog_flag
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 @@ int main(int argc, char *argv[], char *e
lib_init();
i_set_failure_internal();
- process_title_init(&argv, envp);
+ process_title_init(&argv);
argc--;
argv++;
More information about the dovecot-cvs
mailing list