summaryrefslogtreecommitdiffstats
path: root/src/daemon/Daemon.cpp
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2011-04-20 14:01:32 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2011-04-20 14:01:32 +0200
commit1ab41dec5fcc9d9411a7d318523f647ded40b37e (patch)
treebd751576fc9b8ca24015ecb5d8c36c9bcbb0644f /src/daemon/Daemon.cpp
parent6d996b72d7e047aab392ec5a52df82bf85845c05 (diff)
downloadabrt-1ab41dec5fcc9d9411a7d318523f647ded40b37e.tar.gz
abrt-1ab41dec5fcc9d9411a7d318523f647ded40b37e.tar.xz
abrt-1ab41dec5fcc9d9411a7d318523f647ded40b37e.zip
rename Daemon.cpp to abrtd.c
This loses libstdc++, libm and libgcc_s libraries from abrtd Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'src/daemon/Daemon.cpp')
-rw-r--r--src/daemon/Daemon.cpp709
1 files changed, 0 insertions, 709 deletions
diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp
deleted file mode 100644
index 6b894f01..00000000
--- a/src/daemon/Daemon.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc@redhat.com)
- Copyright (C) 2009 RedHat inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-#include <sys/un.h>
-#include <syslog.h>
-#include <sys/inotify.h>
-#include <sys/ioctl.h> /* ioctl(FIONREAD) */
-#include "abrtlib.h"
-#include "comm_layer_inner.h"
-#include "Settings.h"
-#include "CommLayerServerDBus.h"
-#include "MiddleWare.h"
-#include "parse_options.h"
-
-#define PROGNAME "abrtd"
-
-#define VAR_RUN_PIDFILE VAR_RUN"/abrtd.pid"
-
-#define SOCKET_FILE VAR_RUN"/abrt/abrt.socket"
-#define SOCKET_PERMISSION 0666
-/* Maximum number of simultaneously opened client connections. */
-#define MAX_CLIENT_COUNT 10
-
-
-/* Daemon initializes, then sits in glib main loop, waiting for events.
- * Events can be:
- * - inotify: something new appeared under /var/spool/abrt
- * - DBus: dbus message arrived
- * - signal: we got SIGTERM or SIGINT
- *
- * DBus methods we have:
- * - DeleteDebugDump(crash_id): delete it from DB and delete corresponding /var/spool/abrt/DIR
- *
- * DBus signals we emit:
- * - Crash(progname, crash_id, dir, uid) - a new crash occurred (new /var/spool/abrt/DIR is found)
- * - Warning(msg)
- * - Update(msg)
- * Both are sent as unicast to last client set by set_client_name(name).
- * If set_client_name(NULL) was done, they are not sent.
- */
-static volatile sig_atomic_t s_sig_caught;
-static int s_signal_pipe[2];
-static int s_signal_pipe_write = -1;
-static int s_upload_watch = -1;
-static unsigned s_timeout;
-static bool s_exiting;
-
-static GIOChannel *socket_channel = NULL;
-static guint socket_channel_cb_id = 0;
-static int socket_client_count = 0;
-
-
-/* Helpers */
-
-static guint add_watch_or_die(GIOChannel *channel, unsigned condition, GIOFunc func)
-{
- errno = 0;
- guint r = g_io_add_watch(channel, (GIOCondition)condition, func, NULL);
- if (!r)
- perror_msg_and_die("g_io_add_watch failed");
- return r;
-}
-
-
-/* Socket handling */
-
-/* Callback called by glib main loop when a client connects to ABRT's socket. */
-static gboolean server_socket_cb(GIOChannel *source, GIOCondition condition, gpointer ptr_unused)
-{
- /* Check the limit for number of simultaneously attached clients. */
- if (socket_client_count >= MAX_CLIENT_COUNT)
- {
- error_msg("Too many clients, refusing connections to '%s'", SOCKET_FILE);
- /* To avoid infinite loop caused by the descriptor in "ready" state,
- * the callback must be disabled.
- * It is added back in client_free(). */
- g_source_remove(socket_channel_cb_id);
- socket_channel_cb_id = 0;
- return TRUE;
- }
-
- int socket = accept(g_io_channel_unix_get_fd(source), NULL, NULL);
- if (socket == -1)
- {
- perror_msg("accept");
- return TRUE;
- }
-
- log("New client connected");
- pid_t pid = fork();
- if (pid < 0)
- {
- perror_msg("fork");
- close(socket);
- return TRUE;
- }
- if (pid == 0) /* child */
- {
- xmove_fd(socket, 0);
- xdup2(0, 1);
-
- char *argv[3]; /* abrt-server [-s] NULL */
- char **pp = argv;
- *pp++ = (char*)"abrt-server";
- if (logmode & LOGMODE_SYSLOG)
- *pp++ = (char*)"-s";
- *pp = NULL;
-
- execvp(argv[0], argv);
- perror_msg_and_die("Can't execute '%s'", argv[0]);
- }
- /* parent */
- socket_client_count++;
- close(socket);
- return TRUE;
-}
-
-/* Initializes the dump socket, usually in /var/run directory
- * (the path depends on compile-time configuration).
- */
-static void dumpsocket_init()
-{
- unlink(SOCKET_FILE); /* not caring about the result */
-
- int socketfd = xsocket(AF_UNIX, SOCK_STREAM, 0);
- close_on_exec_on(socketfd);
-
- struct sockaddr_un local;
- memset(&local, 0, sizeof(local));
- local.sun_family = AF_UNIX;
- strcpy(local.sun_path, SOCKET_FILE);
- xbind(socketfd, (struct sockaddr*)&local, sizeof(local));
- xlisten(socketfd, MAX_CLIENT_COUNT);
-
- if (chmod(SOCKET_FILE, SOCKET_PERMISSION) != 0)
- perror_msg_and_die("chmod '%s'", SOCKET_FILE);
-
- socket_channel = g_io_channel_unix_new(socketfd);
- g_io_channel_set_close_on_unref(socket_channel, TRUE);
- socket_channel_cb_id = add_watch_or_die(socket_channel, G_IO_IN | G_IO_PRI, server_socket_cb);
-}
-
-/* Releases all resources used by dumpsocket. */
-static void dumpsocket_shutdown()
-{
- /* Set everything to pre-initialization state. */
- if (socket_channel)
- {
- /* Undo add_watch_or_die */
- g_source_remove(socket_channel_cb_id);
- /* Undo g_io_channel_unix_new */
- g_io_channel_unref(socket_channel);
- socket_channel = NULL;
- }
-}
-
-static int create_pidfile()
-{
- /* Note:
- * No O_EXCL: we would happily overwrite stale pidfile from previous boot.
- * No O_TRUNC: we must first try to lock the file, and if lock fails,
- * there is another live abrtd. O_TRUNCing the file in this case
- * would be wrong - it'll erase the pid to empty string!
- */
- int fd = open(VAR_RUN_PIDFILE, O_WRONLY|O_CREAT, 0644);
- if (fd >= 0)
- {
- if (lockf(fd, F_TLOCK, 0) < 0)
- {
- perror_msg("Can't lock file '%s'", VAR_RUN_PIDFILE);
- return -1;
- }
- close_on_exec_on(fd);
- /* write our pid to it */
- char buf[sizeof(long)*3 + 2];
- int len = sprintf(buf, "%lu\n", (long)getpid());
- write(fd, buf, len);
- ftruncate(fd, len);
- /* we leak opened+locked fd intentionally */
- return 0;
- }
-
- perror_msg("Can't open '%s'", VAR_RUN_PIDFILE);
- return -1;
-}
-
-static void handle_signal(int signo)
-{
- int save_errno = errno;
-
- // Enable for debugging only, malloc/printf are unsafe in signal handlers
- //VERB3 log("Got signal %d", signo);
-
- uint8_t l_sig_caught;
- s_sig_caught = l_sig_caught = signo;
- /* Using local copy of s_sig_caught so that concurrent signal
- * won't change it under us */
- if (s_signal_pipe_write >= 0)
- write(s_signal_pipe_write, &l_sig_caught, 1);
-
- errno = save_errno;
-}
-
-/* Signal pipe handler */
-static gboolean handle_signal_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
-{
- char signo;
- gsize len = 0;
- g_io_channel_read(gio, &signo, 1, &len);
- if (len == 1)
- {
- /* we did receive a signal */
- VERB3 log("Got signal %d through signal pipe", signo);
- if (signo != SIGCHLD)
- s_exiting = 1;
- else
- {
- pid_t pid;
- while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
- {
- if (socket_client_count)
- socket_client_count--;
- if (!socket_channel_cb_id)
- {
- log("Accepting connections on '%s'", SOCKET_FILE);
- socket_channel_cb_id = add_watch_or_die(socket_channel, G_IO_IN | G_IO_PRI, server_socket_cb);
- }
- }
- }
- return TRUE;
- }
- return FALSE;
-}
-
-/* Inotify handler */
-static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer ptr_unused)
-{
- /* Default size: 128 simultaneous actions (about 1/2 meg) */
-#define INOTIFY_BUF_SIZE ((sizeof(struct inotify_event) + FILENAME_MAX)*128)
- /* Determine how much to read (it usually is much smaller) */
- /* NB: this variable _must_ be int-sized, ioctl expects that! */
- int inotify_bytes = INOTIFY_BUF_SIZE;
- if (ioctl(g_io_channel_unix_get_fd(gio), FIONREAD, &inotify_bytes) != 0
- || inotify_bytes < sizeof(struct inotify_event)
- || inotify_bytes > INOTIFY_BUF_SIZE
- ) {
- inotify_bytes = INOTIFY_BUF_SIZE;
- }
- VERB3 log("FIONREAD:%d", inotify_bytes);
-
- char *buf = (char*)xmalloc(inotify_bytes);
- errno = 0;
- gsize len;
- GIOError err = g_io_channel_read(gio, buf, inotify_bytes, &len);
- if (err != G_IO_ERROR_NONE)
- {
- perror_msg("Error reading inotify fd");
- free(buf);
- return FALSE;
- }
-
- /* Reconstruct each event and send message to the dbus */
- gsize i = 0;
- while (i < len)
- {
- struct inotify_event *event = (struct inotify_event *) &buf[i];
- const char *name = NULL;
- if (event->len)
- name = event->name;
- //log("i:%d len:%d event->mask:%x IN_ISDIR:%x IN_CLOSE_WRITE:%x event->len:%d",
- // i, len, event->mask, IN_ISDIR, IN_CLOSE_WRITE, event->len);
- i += sizeof(*event) + event->len;
-
- if (event->wd == s_upload_watch)
- {
- /* Was the (presumable newly created) file closed in upload dir,
- * or a file moved to upload dir? */
- if (!(event->mask & IN_ISDIR)
- && event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO)
- && name
- ) {
- const char *ext = strrchr(name, '.');
- if (ext && strcmp(ext + 1, "working") == 0)
- continue;
-
- const char *dir = g_settings_sWatchCrashdumpArchiveDir;
- log("Detected creation of file '%s' in upload directory '%s'", name, dir);
- if (fork() == 0)
- {
- xchdir(dir);
- execlp("abrt-handle-upload", "abrt-handle-upload", DEBUG_DUMPS_DIR, dir, name, (char*)NULL);
- error_msg_and_die("Can't execute '%s'", "abrt-handle-upload");
- }
- }
- continue;
- }
-
- if (!(event->mask & IN_ISDIR) || !name)
- {
- /* ignore lock files and such */
- // Happens all the time during normal run
- //VERB3 log("File '%s' creation detected, ignoring", name);
- continue;
- }
- if (strcmp(strchrnul(name, '.'), ".new") == 0)
- {
- //VERB3 log("Directory '%s' creation detected, ignoring", name);
- continue;
- }
- log("Directory '%s' creation detected", name);
-
- if (g_settings_nMaxCrashReportsSize > 0)
- {
- char *worst_dir = NULL;
- while (g_settings_nMaxCrashReportsSize > 0
- && get_dirsize_find_largest_dir(DEBUG_DUMPS_DIR, &worst_dir, name) / (1024*1024) >= g_settings_nMaxCrashReportsSize
- && worst_dir
- ) {
- log("Size of '%s' >= %u MB, deleting '%s'", DEBUG_DUMPS_DIR, g_settings_nMaxCrashReportsSize, worst_dir);
- send_dbus_sig_QuotaExceeded(_("The size of the report exceeded the quota. Please check system's MaxCrashReportsSize value in abrt.conf."));
- /* deletes both directory and DB record */
- char *d = concat_path_file(DEBUG_DUMPS_DIR, worst_dir);
- free(worst_dir);
- worst_dir = NULL;
- delete_dump_dir(d);
- free(d);
- }
- }
-
- char *fullname = NULL;
- crash_data_t *crash_data = NULL;
- fullname = concat_path_file(DEBUG_DUMPS_DIR, name);
- mw_result_t res = LoadDebugDump(fullname, &crash_data);
- const char *first = crash_data ? get_crash_item_content_or_NULL(crash_data, CD_DUMPDIR) : NULL;
- switch (res)
- {
- case MW_OK:
- log("New dump directory %s, processing", fullname);
- /* Fall through */
-
- case MW_OCCURRED: /* dup */
- {
- if (res != MW_OK)
- {
- log("Deleting dump directory %s (dup of %s), sending dbus signal",
- strrchr(fullname, '/') + 1,
- strrchr(first, '/') + 1);
- delete_dump_dir(fullname);
- }
-
- const char *uid_str = get_crash_item_content_or_NULL(crash_data, FILENAME_UID);
- /* When dup occurs we need to return first occurence,
- * not the one which is deleted
- */
- send_dbus_sig_Crash(get_crash_item_content_or_NULL(crash_data, FILENAME_PACKAGE),
- (first) ? first : fullname,
- uid_str
- );
- break;
- }
- case MW_CORRUPTED:
- case MW_GPG_ERROR:
- default:
- log("Corrupted or bad dump %s (res:%d), deleting", fullname, (int)res);
- delete_dump_dir(fullname);
- break;
- }
- free(fullname);
- free_crash_data(crash_data);
- } /* while */
-
- free(buf);
- return TRUE;
-}
-
-/* Run main loop with idle timeout.
- * Basically, almost like glib's g_main_run(loop)
- */
-static void run_main_loop(GMainLoop* loop)
-{
- GMainContext *context = g_main_loop_get_context(loop);
- int fds_size = 0;
- GPollFD *fds = NULL;
-
- while (!s_exiting)
- {
- gboolean some_ready;
- gint max_priority;
- gint timeout;
- gint nfds;
-
- some_ready = g_main_context_prepare(context, &max_priority);
- if (some_ready)
- g_main_context_dispatch(context);
-
- while (1)
- {
- nfds = g_main_context_query(context, max_priority, &timeout, fds, fds_size);
- if (nfds <= fds_size)
- break;
- fds_size = nfds + 16; /* +16: optimizing realloc frequency */
- fds = (GPollFD *)xrealloc(fds, fds_size * sizeof(fds[0]));
- }
-
- if (s_timeout != 0)
- alarm(s_timeout);
- g_poll(fds, nfds, timeout);
- if (s_timeout != 0)
- alarm(0);
-
- some_ready = g_main_context_check(context, max_priority, fds, nfds);
- if (some_ready)
- g_main_context_dispatch(context);
- }
-
- free(fds);
- g_main_context_unref(context);
-}
-
-static void start_syslog_logging()
-{
- /* Open stdin to /dev/null */
- xmove_fd(xopen("/dev/null", O_RDWR), STDIN_FILENO);
- /* We must not leave fds 0,1,2 closed.
- * Otherwise fprintf(stderr) dumps messages into random fds, etc. */
- xdup2(STDIN_FILENO, STDOUT_FILENO);
- xdup2(STDIN_FILENO, STDERR_FILENO);
- openlog(PROGNAME, 0, LOG_DAEMON);
- logmode = LOGMODE_SYSLOG;
- putenv((char*)"ABRT_SYSLOG=1");
-}
-
-static void ensure_writable_dir(const char *dir, mode_t mode, const char *user)
-{
- struct stat sb;
-
- if (mkdir(dir, mode) != 0 && errno != EEXIST)
- perror_msg_and_die("Can't create '%s'", dir);
- if (stat(dir, &sb) != 0 || !S_ISDIR(sb.st_mode))
- error_msg_and_die("'%s' is not a directory", dir);
-
- struct passwd *pw = getpwnam(user);
- if (!pw)
- perror_msg_and_die("Can't find user '%s'", user);
-
- if ((sb.st_uid != pw->pw_uid || sb.st_gid != pw->pw_gid) && chown(dir, pw->pw_uid, pw->pw_gid) != 0)
- perror_msg_and_die("Can't set owner %u:%u on '%s'", (unsigned int)pw->pw_uid, (unsigned int)pw->pw_gid, dir);
- if ((sb.st_mode & 07777) != mode && chmod(dir, mode) != 0)
- perror_msg_and_die("Can't set mode %o on '%s'", mode, dir);
-}
-
-static void sanitize_dump_dir_rights()
-{
- /* We can't allow everyone to create dumps: otherwise users can flood
- * us with thousands of bogus or malicious dumps */
- /* 07000 bits are setuid, setgit, and sticky, and they must be unset */
- /* 00777 bits are usual "rwxrwxrwx" access rights */
- ensure_writable_dir(DEBUG_DUMPS_DIR, 0755, "abrt");
- /* debuginfo cache */
- ensure_writable_dir(DEBUG_INFO_DIR, 0775, "abrt");
- /* temp dir */
- ensure_writable_dir(VAR_RUN"/abrt", 0755, "root");
-}
-
-int main(int argc, char** argv)
-{
- int parent_pid = getpid();
-
- setlocale(LC_ALL, "");
-
-#if ENABLE_NLS
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-#endif
-
- if (getuid() != 0)
- error_msg_and_die("ABRT daemon must be run as root");
-
- char *env_verbose = getenv("ABRT_VERBOSE");
- if (env_verbose)
- g_verbose = atoi(env_verbose);
-
- const char *program_usage_string = _(
- PROGNAME" [options]"
- );
- enum {
- OPT_v = 1 << 0,
- OPT_d = 1 << 1,
- OPT_s = 1 << 2,
- OPT_t = 1 << 3,
- OPT_p = 1 << 4,
- };
- /* Keep enum above and order of options below in sync! */
- struct options program_options[] = {
- OPT__VERBOSE(&g_verbose),
- OPT_BOOL( 'd', NULL, NULL , _("Do not daemonize")),
- OPT_BOOL( 's', NULL, NULL , _("Log to syslog even with -d")),
- OPT_INTEGER('t', NULL, &s_timeout, _("Exit after SEC seconds of inactivity")),
- OPT_BOOL( 'p', NULL, NULL , _("Add program names to log")),
- OPT_END()
- };
- unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
-
- /* When dbus daemon starts us, it doesn't set PATH
- * (I saw it set only DBUS_STARTER_ADDRESS and DBUS_STARTER_BUS_TYPE).
- * In this case, set something sane:
- */
- const char *env_path = getenv("PATH");
- if (!env_path || !env_path[0])
- putenv((char*)"PATH=/usr/sbin:/usr/bin:/sbin:/bin");
-
- unsetenv("ABRT_SYSLOG");
- putenv(xasprintf("ABRT_VERBOSE=%u", g_verbose));
- msg_prefix = PROGNAME; /* for log(), error_msg() and such */
- if (opts & OPT_p)
- putenv((char*)"ABRT_PROG_PREFIX=1");
- if (opts & OPT_s)
- start_syslog_logging();
-
- xpipe(s_signal_pipe);
- close_on_exec_on(s_signal_pipe[0]);
- close_on_exec_on(s_signal_pipe[1]);
- signal(SIGTERM, handle_signal);
- signal(SIGINT, handle_signal);
- signal(SIGCHLD, handle_signal);
- if (s_timeout != 0)
- signal(SIGALRM, handle_signal);
-
- /* Daemonize unless -d */
- if (!(opts & OPT_d))
- {
- /* forking to background */
- pid_t pid = fork();
- if (pid < 0)
- {
- perror_msg_and_die("fork");
- }
- if (pid > 0)
- {
- /* Parent */
- /* Wait for child to notify us via SIGTERM that it feels ok */
- int i = 20; /* 2 sec */
- while (s_sig_caught == 0 && --i)
- {
- usleep(100 * 1000);
- }
- if (s_sig_caught == SIGTERM)
- {
- exit(0);
- }
- if (s_sig_caught)
- {
- error_msg_and_die("Failed to start: got sig %d", s_sig_caught);
- }
- error_msg_and_die("Failed to start: timeout waiting for child");
- }
- /* Child (daemon) continues */
- setsid(); /* never fails */
- if (g_verbose == 0 && logmode != LOGMODE_SYSLOG)
- start_syslog_logging();
- }
-
- GMainLoop* pMainloop = NULL;
- GIOChannel* channel_inotify = NULL;
- guint channel_inotify_event_id = 0;
- GIOChannel* channel_signal = NULL;
- guint channel_signal_event_id = 0;
- bool pidfile_created = false;
-
- /* Initialization */
- init_daemon_logging();
-
- VERB1 log("Loading settings");
- if (load_settings() != 0)
- goto init_error;
-
- sanitize_dump_dir_rights();
-
- VERB1 log("Creating glib main loop");
- pMainloop = g_main_loop_new(NULL, FALSE);
-
- VERB1 log("Initializing inotify");
- errno = 0;
- int inotify_fd = inotify_init();
- if (inotify_fd == -1)
- perror_msg_and_die("inotify_init failed");
- close_on_exec_on(inotify_fd);
-
- /* Watching DEBUG_DUMPS_DIR for new files... */
- if (inotify_add_watch(inotify_fd, DEBUG_DUMPS_DIR, IN_CREATE | IN_MOVED_TO) < 0)
- {
- perror_msg("inotify_add_watch failed on '%s'", DEBUG_DUMPS_DIR);
- goto init_error;
- }
- if (g_settings_sWatchCrashdumpArchiveDir)
- {
- s_upload_watch = inotify_add_watch(inotify_fd, g_settings_sWatchCrashdumpArchiveDir, IN_CLOSE_WRITE|IN_MOVED_TO);
- if (s_upload_watch < 0)
- {
- perror_msg("inotify_add_watch failed on '%s'", g_settings_sWatchCrashdumpArchiveDir);
- goto init_error;
- }
- }
- VERB1 log("Adding inotify watch to glib main loop");
- channel_inotify = g_io_channel_unix_new(inotify_fd);
- channel_inotify_event_id = g_io_add_watch(channel_inotify,
- G_IO_IN,
- handle_inotify_cb,
- NULL);
-
- /* Add an event source which waits for INT/TERM signal */
- VERB1 log("Adding signal pipe watch to glib main loop");
- channel_signal = g_io_channel_unix_new(s_signal_pipe[0]);
- channel_signal_event_id = g_io_add_watch(channel_signal,
- G_IO_IN,
- handle_signal_cb,
- NULL);
-
- /* Mark the territory */
- VERB1 log("Creating pid file");
- if (create_pidfile() != 0)
- goto init_error;
- pidfile_created = true;
-
- /* Open socket to receive new crashes. */
- dumpsocket_init();
-
- /* Note: this already may process a few dbus messages,
- * therefore it should be the last thing to initialize.
- */
- VERB1 log("Initializing dbus");
- if (init_dbus() != 0)
- goto init_error;
-
- /* Inform parent that we initialized ok */
- if (!(opts & OPT_d))
- {
- VERB1 log("Signalling parent");
- kill(parent_pid, SIGTERM);
- if (logmode != LOGMODE_SYSLOG)
- start_syslog_logging();
- }
-
- /* Only now we want signal pipe to work */
- s_signal_pipe_write = s_signal_pipe[1];
-
- /* Enter the event loop */
- log("Init complete, entering main loop");
- run_main_loop(pMainloop);
-
- cleanup:
- /* Error or INT/TERM. Clean up, in reverse order.
- * Take care to not undo things we did not do.
- */
- dumpsocket_shutdown();
- if (pidfile_created)
- unlink(VAR_RUN_PIDFILE);
-
- if (channel_signal_event_id > 0)
- g_source_remove(channel_signal_event_id);
- if (channel_signal)
- g_io_channel_unref(channel_signal);
- if (channel_inotify_event_id > 0)
- g_source_remove(channel_inotify_event_id);
- if (channel_inotify)
- g_io_channel_unref(channel_inotify);
-
- deinit_dbus();
-
- if (pMainloop)
- g_main_loop_unref(pMainloop);
-
- free_settings();
-
- /* Exiting */
- if (s_sig_caught && s_sig_caught != SIGALRM && s_sig_caught != SIGCHLD)
- {
- error_msg("Got signal %d, exiting", s_sig_caught);
- signal(s_sig_caught, SIG_DFL);
- raise(s_sig_caught);
- }
- error_msg_and_die("Exiting");
-
- init_error:
- /* Initialization error */
- error_msg("Error while initializing daemon");
- /* Inform parent that initialization failed */
- if (!(opts & OPT_d))
- kill(parent_pid, SIGINT);
- goto cleanup;
-}