dovecot-2.0-sslstream: Fixed Linux proctitle hack and enabled it...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:55:41 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/affb52c62add
changeset: 10189: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