diff options
-rw-r--r-- | src/daemon.c | 97 | ||||
-rw-r--r-- | src/daemon.h | 19 | ||||
-rw-r--r-- | src/main.c | 101 |
3 files changed, 119 insertions, 98 deletions
diff --git a/src/daemon.c b/src/daemon.c index 566c59250..99ba4d9df 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -28,6 +28,46 @@ #include <sys/stat.h> #include <fcntl.h> +#ifndef WIN32 +#include <signal.h> +#include <pwd.h> +#include <grp.h> +#endif + +void +daemonize_kill(void) +{ +#ifndef WIN32 + FILE *fp; + struct config_param *param = + parseConfigFilePath(CONF_PID_FILE, 0); + int pid, ret; + + if (param == NULL) + g_error("no pid_file specified in the config file"); + + fp = fopen(param->value, "r"); + if (fp == NULL) + g_error("unable to open %s \"%s\": %s", + CONF_PID_FILE, param->value, g_strerror(errno)); + + if (fscanf(fp, "%i", &pid) != 1) { + g_error("unable to read the pid from file \"%s\"", + param->value); + } + fclose(fp); + + ret = kill(pid, SIGTERM); + if (ret < 0) + g_error("unable to kill proccess %i: %s", + pid, g_strerror(errno)); + + exit(EXIT_SUCCESS); +#else + g_error("--kill is not available on WIN32"); +#endif +} + void daemonize_close_stdin(void) { @@ -42,6 +82,50 @@ daemonize_close_stdin(void) } void +daemonize_set_user(void) +{ +#ifndef WIN32 + struct config_param *param = config_get_param(CONF_USER); + + if (param && strlen(param->value)) { + /* get uid */ + struct passwd *userpwd; + if ((userpwd = getpwnam(param->value)) == NULL) { + g_error("no such user \"%s\" at line %i", + param->value, param->line); + } + + if (setgid(userpwd->pw_gid) == -1) { + g_error("cannot setgid for user \"%s\" at line %i: %s", + param->value, param->line, strerror(errno)); + } +#ifdef _BSD_SOURCE + /* init suplementary groups + * (must be done before we change our uid) + */ + if (initgroups(param->value, userpwd->pw_gid) == -1) { + g_warning("cannot init supplementary groups " + "of user \"%s\" at line %i: %s", + param->value, param->line, strerror(errno)); + } +#endif + + /* set uid */ + if (setuid(userpwd->pw_uid) == -1) { + g_error("cannot change to uid of user " + "\"%s\" at line %i: %s", + param->value, param->line, strerror(errno)); + } + + /* this is needed by libs such as arts */ + if (userpwd->pw_dir) { + g_setenv("HOME", userpwd->pw_dir, true); + } + } +#endif +} + +void daemonize(Options *options) { #ifndef WIN32 @@ -91,3 +175,16 @@ daemonize(Options *options) (void)options; #endif } + +void +daemonize_delete_pidfile(void) +{ + struct config_param *param = parseConfigFilePath(CONF_PID_FILE, 0); + + if (param == NULL) + return; + + g_debug("cleaning up pid file"); + + unlink(param->value); +} diff --git a/src/daemon.h b/src/daemon.h index f2ea58c5f..8f1b70313 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -22,12 +22,31 @@ #include "cmdline.h" /** + * Kill the MPD which is currently running, pid determined from the + * pid file. + */ +void +daemonize_kill(void); + +/** * Close stdin (fd 0) and re-open it as /dev/null. */ void daemonize_close_stdin(void); +/** + * Change to the configured Unix user. + */ +void +daemonize_set_user(void); + void daemonize(Options *options); +/** + * Deletes the pidfile which was created when MPD started. + */ +void +daemonize_delete_pidfile(void); + #endif diff --git a/src/main.c b/src/main.c index 1bcae8f36..bfe89ae2a 100644 --- a/src/main.c +++ b/src/main.c @@ -63,15 +63,9 @@ #include <unistd.h> #include <stdlib.h> -#include <signal.h> #include <errno.h> #include <string.h> -#ifndef WIN32 -#include <pwd.h> -#include <grp.h> -#endif - #ifdef HAVE_LOCALE_H #include <locale.h> #endif @@ -81,49 +75,6 @@ GMainLoop *main_loop; struct notify main_notify; -static void changeToUser(void) -{ -#ifndef WIN32 - struct config_param *param = config_get_param(CONF_USER); - - if (param && strlen(param->value)) { - /* get uid */ - struct passwd *userpwd; - if ((userpwd = getpwnam(param->value)) == NULL) { - g_error("no such user \"%s\" at line %i", - param->value, param->line); - } - - if (setgid(userpwd->pw_gid) == -1) { - g_error("cannot setgid for user \"%s\" at line %i: %s", - param->value, param->line, strerror(errno)); - } -#ifdef _BSD_SOURCE - /* init suplementary groups - * (must be done before we change our uid) - */ - if (initgroups(param->value, userpwd->pw_gid) == -1) { - g_warning("cannot init supplementary groups " - "of user \"%s\" at line %i: %s", - param->value, param->line, strerror(errno)); - } -#endif - - /* set uid */ - if (setuid(userpwd->pw_uid) == -1) { - g_error("cannot change to uid of user " - "\"%s\" at line %i: %s", - param->value, param->line, strerror(errno)); - } - - /* this is needed by libs such as arts */ - if (userpwd->pw_dir) { - g_setenv("HOME", userpwd->pw_dir, true); - } - } -#endif -} - static void openDB(Options * options, char *argv0) { struct config_param *param; @@ -160,52 +111,6 @@ static void openDB(Options * options, char *argv0) } } -static void cleanUpPidFile(void) -{ - struct config_param *pidFileParam = - parseConfigFilePath(CONF_PID_FILE, 0); - - if (!pidFileParam) - return; - - g_debug("cleaning up pid file"); - - unlink(pidFileParam->value); -} - -static void killFromPidFile(void) -{ -#ifndef WIN32 - FILE *fp; - struct config_param *pidFileParam = - parseConfigFilePath(CONF_PID_FILE, 0); - int pid; - - if (!pidFileParam) { - g_error("no pid_file specified in the config file"); - } - - fp = fopen(pidFileParam->value, "r"); - if (!fp) { - g_error("unable to open %s \"%s\": %s", - CONF_PID_FILE, pidFileParam->value, strerror(errno)); - } - if (fscanf(fp, "%i", &pid) != 1) { - g_error("unable to read the pid from file \"%s\"", - pidFileParam->value); - } - fclose(fp); - - if (kill(pid, SIGTERM)) { - g_error("unable to kill proccess %i: %s", - pid, strerror(errno)); - } - exit(EXIT_SUCCESS); -#else - g_error("--kill is not available on WIN32"); -#endif -} - static gboolean timer_save_state_file(G_GNUC_UNUSED gpointer data) { @@ -253,7 +158,7 @@ int main(int argc, char *argv[]) parseOptions(argc, argv, &options); if (options.kill) - killFromPidFile(); + daemonize_kill(); stats_global_init(); tag_lib_init(); @@ -261,7 +166,7 @@ int main(int argc, char *argv[]) listenOnPort(); - changeToUser(); + daemonize_set_user(); main_task = g_thread_self(); main_loop = g_main_loop_new(NULL, FALSE); @@ -356,7 +261,7 @@ int main(int argc, char *argv[]) archive_plugin_deinit_all(); #endif music_pipe_free(); - cleanUpPidFile(); + daemonize_delete_pidfile(); config_global_finish(); tag_pool_deinit(); songvec_deinit(); |