From 5dcd0f6ff8458786206bace673263bcc04b53edf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 30 Oct 2005 21:22:05 +0000 Subject: make use of setproctitle() to change the process title of the daemon processes. This is especially useful to distuingish the main daemon and the chroot() helper process. git-svn-id: file:///home/lennart/svn/public/avahi/trunk@908 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-daemon/Makefile.am | 3 +- avahi-daemon/chroot.c | 5 ++- avahi-daemon/chroot.h | 2 +- avahi-daemon/main.c | 68 +++++++++++++++++++---------- avahi-daemon/setproctitle.c | 102 ++++++++++++++++++++++++++++++++++++++++++++ avahi-daemon/setproctitle.h | 28 ++++++++++++ configure.ac | 2 +- 7 files changed, 184 insertions(+), 26 deletions(-) create mode 100644 avahi-daemon/setproctitle.c create mode 100644 avahi-daemon/setproctitle.h diff --git a/avahi-daemon/Makefile.am b/avahi-daemon/Makefile.am index 0dadede..9819f56 100644 --- a/avahi-daemon/Makefile.am +++ b/avahi-daemon/Makefile.am @@ -50,7 +50,8 @@ avahi_daemon_SOURCES = \ main.c main.h \ simple-protocol.c simple-protocol.h \ static-services.c static-services.h \ - ini-file-parser.c ini-file-parser.h + ini-file-parser.c ini-file-parser.h \ + setproctitle.c setproctitle.h avahi_daemon_CFLAGS = $(AM_CFLAGS) $(LIBDAEMON_CFLAGS) avahi_daemon_LDADD = $(AM_LDADD) ../avahi-common/libavahi-common.la ../avahi-core/libavahi-core.la $(LIBDAEMON_LIBS) -lexpat diff --git a/avahi-daemon/chroot.c b/avahi-daemon/chroot.c index 5504cbd..3cace26 100644 --- a/avahi-daemon/chroot.c +++ b/avahi-daemon/chroot.c @@ -39,6 +39,7 @@ #include "chroot.h" #include "caps.h" +#include "setproctitle.h" enum { AVAHI_CHROOT_SUCCESS = 0, @@ -286,7 +287,7 @@ fail: return ret; } -int avahi_chroot_helper_start(void) { +int avahi_chroot_helper_start(const char *argv0) { int sock[2]; pid_t pid; @@ -306,6 +307,8 @@ int avahi_chroot_helper_start(void) { /* Drop all remaining capabilities */ avahi_caps_drop_all(); + + avahi_set_proc_title("%s: chroot helper process", argv0); close(sock[0]); helper_main(sock[1]); diff --git a/avahi-daemon/chroot.h b/avahi-daemon/chroot.h index 1255739..ea61c5a 100644 --- a/avahi-daemon/chroot.h +++ b/avahi-daemon/chroot.h @@ -24,7 +24,7 @@ #include -int avahi_chroot_helper_start(void); +int avahi_chroot_helper_start(const char *argv0); void avahi_chroot_helper_shutdown(void); int avahi_chroot_helper_get(const char *fname); diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c index 7ebfcd7..7508cf3 100644 --- a/avahi-daemon/main.c +++ b/avahi-daemon/main.c @@ -61,6 +61,7 @@ #include "caps.h" #endif +#include "setproctitle.h" #include "main.h" #include "simple-protocol.h" #include "static-services.h" @@ -72,6 +73,7 @@ AvahiServer *avahi_server = NULL; AvahiSimplePoll *simple_poll_api = NULL; +static char *argv0 = NULL; typedef enum { DAEMON_RUN, @@ -97,6 +99,7 @@ typedef struct { #ifdef ENABLE_CHROOT int use_chroot; #endif + int modify_proc_title; int publish_resolv_conf; char ** publish_dns_servers; @@ -259,6 +262,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda switch (state) { case AVAHI_SERVER_RUNNING: avahi_log_info("Server startup complete. Host name is %s. Local service cookie is %u.", avahi_server_get_host_name_fqdn(s), avahi_server_get_local_service_cookie(s)); + + avahi_set_proc_title("%s: running [%s]", argv0, avahi_server_get_host_name_fqdn(s)); + static_service_add_to_server(); remove_dns_server_entry_groups(); @@ -283,6 +289,9 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda avahi_log_warn("Host name conflict, retrying with <%s>", n); avahi_server_set_host_name(s, n); avahi_free(n); + + avahi_set_proc_title("%s: collision", argv0); + break; } @@ -293,13 +302,16 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda break; case AVAHI_SERVER_REGISTERING: + avahi_set_proc_title("%s: registering [%s]", argv0, avahi_server_get_host_name_fqdn(s)); + + case AVAHI_SERVER_INVALID: break; } } -static void help(FILE *f, const char *argv0) { +static void help(FILE *f) { fprintf(f, "%s [options]\n" " -h --help Show this help\n" @@ -316,6 +328,7 @@ static void help(FILE *f, const char *argv0) { #ifdef ENABLE_CHROOT " --no-chroot Don't chroot()\n" #endif + " --no-proc-title Don't modify process title\n" " --debug Increase verbosity\n", argv0); } @@ -329,25 +342,27 @@ static int parse_command_line(DaemonConfig *c, int argc, char *argv[]) { OPTION_NO_DROP_ROOT, #ifdef ENABLE_CHROOT OPTION_NO_CHROOT, -#endif +#endif + OPTION_NO_PROC_TITLE, OPTION_DEBUG }; static const struct option long_options[] = { - { "help", no_argument, NULL, 'h' }, - { "daemonize", no_argument, NULL, 'D' }, - { "kill", no_argument, NULL, 'k' }, - { "version", no_argument, NULL, 'V' }, - { "file", required_argument, NULL, 'f' }, - { "reload", no_argument, NULL, 'r' }, - { "check", no_argument, NULL, 'c' }, - { "syslog", no_argument, NULL, 's' }, - { "no-rlimits", no_argument, NULL, OPTION_NO_RLIMITS }, - { "no-drop-root", no_argument, NULL, OPTION_NO_DROP_ROOT }, + { "help", no_argument, NULL, 'h' }, + { "daemonize", no_argument, NULL, 'D' }, + { "kill", no_argument, NULL, 'k' }, + { "version", no_argument, NULL, 'V' }, + { "file", required_argument, NULL, 'f' }, + { "reload", no_argument, NULL, 'r' }, + { "check", no_argument, NULL, 'c' }, + { "syslog", no_argument, NULL, 's' }, + { "no-rlimits", no_argument, NULL, OPTION_NO_RLIMITS }, + { "no-drop-root", no_argument, NULL, OPTION_NO_DROP_ROOT }, #ifdef ENABLE_CHROOT - { "no-chroot", no_argument, NULL, OPTION_NO_CHROOT }, -#endif - { "debug", no_argument, NULL, OPTION_DEBUG }, + { "no-chroot", no_argument, NULL, OPTION_NO_CHROOT }, +#endif + { "no-proc-title", no_argument, NULL, OPTION_NO_PROC_TITLE }, + { "debug", no_argument, NULL, OPTION_DEBUG }, { NULL, 0, NULL, 0 } }; @@ -392,7 +407,10 @@ static int parse_command_line(DaemonConfig *c, int argc, char *argv[]) { case OPTION_NO_CHROOT: c->use_chroot = 0; break; -#endif +#endif + case OPTION_NO_PROC_TITLE: + c->modify_proc_title = 0; + break; case OPTION_DEBUG: c->debug = 1; break; @@ -953,7 +971,6 @@ static void init_rand_seed(void) { int main(int argc, char *argv[]) { int r = 255; - const char *argv0; int wrote_pid_file = 0; avahi_set_log_function(log_function); @@ -974,12 +991,12 @@ int main(int argc, char *argv[]) { #ifdef ENABLE_CHROOT config.use_chroot = 1; #endif + config.modify_proc_title = 1; config.publish_dns_servers = NULL; config.publish_resolv_conf = 0; config.use_syslog = 0; config.debug = 0; - config.rlimit_as_set = 0; config.rlimit_core_set = 0; config.rlimit_data_set = 0; @@ -991,9 +1008,9 @@ int main(int argc, char *argv[]) { #endif if ((argv0 = strrchr(argv[0], '/'))) - argv0++; + argv0 = avahi_strdup(argv0 + 1); else - argv0 = argv[0]; + argv0 = avahi_strdup(argv[0]); daemon_pid_file_ident = (const char *) argv0; daemon_log_ident = (char*) argv0; @@ -1002,12 +1019,15 @@ int main(int argc, char *argv[]) { if (parse_command_line(&config, argc, argv) < 0) goto finish; + if (config.modify_proc_title) + avahi_init_proc_title(argc, argv); + #ifdef ENABLE_CHROOT config.use_chroot = config.use_chroot && config.drop_root; #endif if (config.command == DAEMON_HELP) { - help(stdout, argv0); + help(stdout); r = 0; } else if (config.command == DAEMON_VERSION) { printf("%s "PACKAGE_VERSION"\n", argv0); @@ -1106,13 +1126,15 @@ int main(int argc, char *argv[]) { #ifdef ENABLE_CHROOT if (config.drop_root && config.use_chroot) - if (avahi_chroot_helper_start() < 0) { + if (avahi_chroot_helper_start(argv0) < 0) { avahi_log_error("failed to start chroot() helper daemon."); goto finish; } #endif avahi_log_info("%s "PACKAGE_VERSION" starting up.", argv0); + avahi_set_proc_title("%s: starting up", argv0); + if (run_server(&config) == 0) r = 0; } @@ -1139,5 +1161,7 @@ finish: avahi_chroot_helper_shutdown(); #endif + avahi_free(argv0); + return r; } diff --git a/avahi-daemon/setproctitle.c b/avahi-daemon/setproctitle.c new file mode 100644 index 0000000..819f7b0 --- /dev/null +++ b/avahi-daemon/setproctitle.c @@ -0,0 +1,102 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include + +#include "setproctitle.h" + +#if !defined(HAVE_SETPROCTITLE) && defined(__linux__) +static char** argv_buffer = NULL; +static size_t argv_size = 0; + +#if !HAVE_DECL_ENVIRON +extern char **environ; +#endif + +#endif + +void avahi_init_proc_title(int argc, char **argv) { + +#if !defined(HAVE_SETPROCTITLE) && defined(__linux__) + + unsigned i; + char **new_environ, *endptr; + + /* This code is really really ugly. We make some memory layout + * assumptions and reuse the environment array as memory to store + * our process title in */ + + for (i = 0; environ[i]; i++); + + endptr = i ? environ[i-1] + strlen(environ[i-1]) : argv[argc-1] + strlen(argv[argc-1]); + + argv_buffer = argv; + argv_size = endptr - argv_buffer[0]; + + /* Make a copy of environ */ + + new_environ = avahi_malloc(sizeof(char*) * (i + 1)); + for (i = 0; environ[i]; i++) + new_environ[i] = avahi_strdup(environ[i]); + new_environ[i] = NULL; + + environ = new_environ; + +#endif +} + +void avahi_set_proc_title(const char *fmt,...) { +#ifdef HAVE_SETPROCTITLE + char t[256]; + + va_list ap; + va_start(ap); + vsnprintf(t, sizeof(t), fmt, ap); + va_end(ap); + + setproctitle("-%s", t); +#elif __linux__ + size_t l; + va_list ap; + + if (!argv_buffer) + return; + + va_start(ap, fmt); + vsnprintf(argv_buffer[0], argv_size, fmt, ap); + va_end(ap); + + l = strlen(argv_buffer[0]); + + memset(argv_buffer[0] + l, 0, argv_size - l); + argv_buffer[1] = NULL; +#endif +} diff --git a/avahi-daemon/setproctitle.h b/avahi-daemon/setproctitle.h new file mode 100644 index 0000000..6ac7612 --- /dev/null +++ b/avahi-daemon/setproctitle.h @@ -0,0 +1,28 @@ +#ifndef foosetproctitlehfoo +#define foosetproctitlehfoo + +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +void avahi_init_proc_title(int argc, char **argv); +void avahi_set_proc_title(const char *fmt, ...); + +#endif diff --git a/configure.ac b/configure.ac index 4e9a98a..a522b24 100644 --- a/configure.ac +++ b/configure.ac @@ -206,7 +206,7 @@ AC_FUNC_MEMCMP AC_FUNC_SELECT_ARGTYPES AC_FUNC_MALLOC AC_FUNC_REALLOC -AC_CHECK_FUNCS([gethostname memchr memmove memset mkdir select socket strchr strcspn strdup strerror strrchr strspn strstr uname setresuid setreuid setresgid setregid strcasecmp gettimeofday putenv strncasecmp strlcpy gethostbyname seteuid setegid]) +AC_CHECK_FUNCS([gethostname memchr memmove memset mkdir select socket strchr strcspn strdup strerror strrchr strspn strstr uname setresuid setreuid setresgid setregid strcasecmp gettimeofday putenv strncasecmp strlcpy gethostbyname seteuid setegid setproctitle]) AC_FUNC_CHOWN AC_FUNC_STAT -- cgit