diff options
Diffstat (limited to 'src/daemon.c')
-rw-r--r-- | src/daemon.c | 97 |
1 files changed, 97 insertions, 0 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); +} |