hald.c revision 18c2aff776a775d34a4c9893a4c72e0434d68e36
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * CVSID: $Id$
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * hald.c : main startup for HAL daemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright (C) 2005 Danny Kukawka, <danny.kukawka@web.de>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is free software; you can redistribute it and/or modify
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * it under the terms of the GNU General Public License as published by
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * the Free Software Foundation; either version 2 of the License, or
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * (at your option) any later version.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * This program is distributed in the hope that it will be useful,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * but WITHOUT ANY WARRANTY; without even the implied warranty of
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * GNU General Public License for more details.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * You should have received a copy of the GNU General Public License
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * along with this program; if not, write to the Free Software
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_CONFIG_H
18c2aff776a775d34a4c9893a4c72e0434d68e36artem# include <config.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdlib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <string.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <unistd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <getopt.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <pwd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdint.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/stat.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <fcntl.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <errno.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <signal.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <grp.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <syslog.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <dbus/dbus.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <dbus/dbus-glib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <dbus/dbus-glib-lowlevel.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/*#include "master_slave.h"*/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "logger.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hald.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "device_store.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "device_info.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "osspec.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hald_dbus.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "util.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hald_runner.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "util_helper.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void delete_pid(void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unlink(HALD_PID_FILE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/**
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @defgroup HalDaemon HAL daemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @brief The HAL daemon manages persistent device objects available through
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * a D-BUS network API
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic HalDeviceStore *global_device_list = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic HalDeviceStore *temporary_device_list = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemaddon_terminated (HalDevice *device, guint32 exit_type,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gint return_code, gchar **error,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gpointer data1, gpointer data2)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("in addon_terminated for udi=%s", device->udi));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* TODO: log to syslog - addons shouldn't just terminate, this is a bug with the addon */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* however, the world can stop, mark this addon as ready
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * (TODO: potential bug if the addon crashed after calling libhal_device_addon_is_ready())
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_inc_num_ready_addons (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_are_all_addons_ready (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem manager_send_signal_device_added (device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemgdl_store_changed (HalDeviceStore *store, HalDevice *device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gboolean is_added, gpointer user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (is_added) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GSList *addons;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Added device to GDL; udi=%s", hal_device_get_udi(device)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((addons = hal_device_property_get_strlist (device, "info.addons")) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GSList *i;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = addons; i != NULL; i = g_slist_next (i)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const gchar *command_line;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gchar *extra_env[2] = {"HALD_ACTION=addon", NULL};
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem command_line = (const gchar *) i->data;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hald_runner_start(device, command_line, extra_env, addon_terminated, NULL, NULL)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Started addon %s for udi %s",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem command_line, hal_device_get_udi(device)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_inc_num_addons (device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("Cannot start addon %s for udi %s",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem command_line, hal_device_get_udi(device)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Removed device from GDL; udi=%s", hal_device_get_udi(device)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_runner_kill_device(device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /*hal_device_print (device);*/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (is_added) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_are_all_addons_ready (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem manager_send_signal_device_added (device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_are_all_addons_ready (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem manager_send_signal_device_removed (device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemgdl_property_changed (HalDeviceStore *store, HalDevice *device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *key, gboolean added, gboolean removed,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gpointer user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_are_all_addons_ready (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device_send_signal_property_modified (device, key, removed, added);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* only execute the callouts if the property _changed_ */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (added == FALSE && removed == FALSE)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /*hal_callout_property (device, key)*/;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemgdl_capability_added (HalDeviceStore *store, HalDevice *device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *capability, gpointer user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hal_device_are_all_addons_ready (device)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem manager_send_signal_new_capability (device, capability);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /*hal_callout_capability (device, capability, TRUE)*/;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemHalDeviceStore *
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhald_get_gdl (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (global_device_list == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem global_device_list = hal_device_store_new ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_signal_connect (global_device_list,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "store_changed",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem G_CALLBACK (gdl_store_changed), NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_signal_connect (global_device_list,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "device_property_changed",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem G_CALLBACK (gdl_property_changed), NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_signal_connect (global_device_list,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "device_capability_added",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem G_CALLBACK (gdl_capability_added), NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return global_device_list;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemHalDeviceStore *
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhald_get_tdl (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (temporary_device_list == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem temporary_device_list = hal_device_store_new ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return temporary_device_list;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/**
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @defgroup MainDaemon Basic functions
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @ingroup HalDaemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @brief Basic functions in the HAL daemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Print out program usage.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemusage ()
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "\n" "usage : hald [--daemon=yes|no] [--verbose=yes|no] [--help]\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " --daemon=yes|no Become a daemon\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " --verbose=yes|no Print out debug (overrides HALD_VERBOSE)\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " --use-syslog Print out debug messages to syslog instead of stderr.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " Use this option to get debug messages if HAL runs as\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " daemon.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " --help Show this information and exit\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem " --version Output version information and exit"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "The HAL daemon detects devices present in the system and provides the\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "org.freedesktop.Hal service through the system-wide message bus provided\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "by D-BUS.\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "For more information visit http://freedesktop.org/Software/hal\n"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** If #TRUE, we will daemonize */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic dbus_bool_t opt_become_daemon = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** If #TRUE, we will spew out debug */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdbus_bool_t hald_is_verbose = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdbus_bool_t hald_use_syslog = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic int sigterm_unix_signal_pipe_fds[2];
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic GIOChannel *sigterm_iochn;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhandle_sigterm (int value)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ssize_t written;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem static char marker[1] = {'S'};
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* write a 'S' character to the other end to tell about
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * the signal. Note that 'the other end' is a GIOChannel thingy
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * that is only called from the mainloop - thus this is how we
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * defer this since UNIX signal handlers are evil
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Oh, and write(2) is indeed reentrant */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem written = write (sigterm_unix_signal_pipe_fds[1], marker, 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean
18c2aff776a775d34a4c9893a4c72e0434d68e36artemsigterm_iochn_data (GIOChannel *source,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GIOCondition condition,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gpointer user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GError *err = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gchar data[1];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gsize bytes_read;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Empty the pipe */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (G_IO_STATUS_NORMAL !=
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("Error emptying sigterm pipe: %s",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem err->message));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_error_free (err);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Caught SIGTERM, initiating shutdown"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_runner_kill_all();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** This is set to #TRUE if we are probing and #FALSE otherwise */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdbus_bool_t hald_is_initialising;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic int startup_daemonize_pipe[2];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/*--------------------------------------------------------------------------------------------------*/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean child_died = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhandle_sigchld (int value)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem child_died = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic int
18c2aff776a775d34a4c9893a4c72e0434d68e36artemparent_wait_for_child (int child_fd, pid_t child_pid)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fd_set rfds;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fd_set efds;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem struct timeval tv;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int retval;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int ret;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem signal(SIGCHLD, handle_sigchld);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* wait for either
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * o Child writes something to the child_fd; means that device
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * probing is completed and the parent should exit with success
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * o Child is killed (segfault etc.); means that parent should exit
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * with failure
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * o Timeout; means that we should kill the child and exit with
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * failure
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem FD_ZERO(&rfds);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem FD_SET(child_fd, &rfds);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem FD_ZERO(&efds);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem FD_SET(child_fd, &efds);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Wait up to 250 seconds for device probing */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem tv.tv_sec = 250;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem tv.tv_usec = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem retval = select (child_fd + 1, &rfds, NULL, &efds, &tv);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (child_died) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* written from handle_sigchld */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ret = 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (retval > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* means child wrote to socket or closed it; all good */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ret = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* assume timeout; kill child */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem kill (child_pid, SIGTERM);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ret = 2;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return ret;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/*--------------------------------------------------------------------------------------------------*/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Entry point for HAL daemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argc Number of arguments
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param argv Array of arguments
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @return Exit code
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemint
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmain (int argc, char *argv[])
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GMainLoop *loop;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem guint sigterm_iochn_listener_source_id;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *path;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char newpath[512];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem openlog ("hald", LOG_PID, LOG_DAEMON);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_type_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (getenv ("HALD_VERBOSE"))
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_verbose = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem else
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_verbose = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* our helpers are installed into libexec, so adjust out $PATH
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * to include this at the end (since we want to overide in
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * run-hald.sh and friends)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem path = getenv ("PATH");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (path != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_strlcpy (newpath, path, sizeof (newpath));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_strlcat (newpath, ":", sizeof (newpath));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* No PATH was set */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem newpath[0] = '\0';
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_strlcat (newpath, PACKAGE_LIBEXEC_DIR, sizeof (newpath));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_strlcat (newpath, ":", sizeof (newpath));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_strlcat (newpath, PACKAGE_SCRIPT_DIR, sizeof (newpath));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem setenv ("PATH", newpath, TRUE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem while (1) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int c;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int option_index = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *opt;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem static struct option long_options[] = {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {"daemon", 1, NULL, 0},
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {"verbose", 1, NULL, 0},
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {"use-syslog", 0, NULL, 0},
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {"help", 0, NULL, 0},
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {"version", 0, NULL, 0},
18c2aff776a775d34a4c9893a4c72e0434d68e36artem {NULL, 0, NULL, 0}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem };
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem c = getopt_long (argc, argv, "",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem long_options, &option_index);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (c == -1)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (c) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case 0:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem opt = long_options[option_index].name;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strcmp (opt, "help") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (opt, "version") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "HAL package version: " PACKAGE_VERSION "\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (opt, "daemon") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strcmp ("yes", optarg) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem opt_become_daemon = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp ("no", optarg) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem opt_become_daemon = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (opt, "verbose") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strcmp ("yes", optarg) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_verbose = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp ("no", optarg) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_verbose = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (strcmp (opt, "use-syslog") == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_use_syslog = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem default:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hald_is_verbose)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem logger_enable ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem else
18c2aff776a775d34a4c9893a4c72e0434d68e36artem logger_disable ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hald_use_syslog)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem logger_enable_syslog ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem else
18c2aff776a775d34a4c9893a4c72e0434d68e36artem logger_disable_syslog ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* will fork into two; only the child will return here if we are successful */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /*master_slave_setup ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sleep (100000000);*/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem loop = g_main_loop_new (NULL, FALSE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO ((PACKAGE_STRING));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (opt_become_daemon) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int child_pid;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int dev_null_fd;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int pf;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ssize_t written;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char pid[9];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Will daemonize"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Becoming a daemon"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (pipe (startup_daemonize_pipe) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Could not setup pipe: %s\n", strerror(errno));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (chdir ("/") < 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Could not chdir to /: %s\n", strerror(errno));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem child_pid = fork ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (child_pid) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case -1:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "Cannot fork(): %s\n", strerror(errno));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case 0:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* child */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dev_null_fd = open ("/dev/null", O_RDWR);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* ignore if we can't open /dev/null */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (dev_null_fd >= 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* attach /dev/null to stdout, stdin, stderr */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dup2 (dev_null_fd, 0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dup2 (dev_null_fd, 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dup2 (dev_null_fd, 2);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close (dev_null_fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem umask (022);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem default:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* parent, block until child writes */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (parent_wait_for_child (startup_daemonize_pipe[0], child_pid));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Create session */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem setsid ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* remove old pid file */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unlink (HALD_PID_FILE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Make a new one */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((pf= open (HALD_PID_FILE, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644)) > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem snprintf (pid, sizeof(pid), "%lu\n", (long unsigned) getpid ());
18c2aff776a775d34a4c9893a4c72e0434d68e36artem written = write (pf, pid, strlen(pid));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close (pf);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem atexit (delete_pid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Will not daemonize"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* we need to do stuff when we are expected to terminate, thus
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * this involves looking for SIGTERM; UNIX signal handlers are
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * evil though, so set up a pipe to transmit the signal.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* create pipe */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (pipe (sigterm_unix_signal_pipe_fds) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DIE (("Could not setup pipe, errno=%d", errno));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* setup glib handler - 0 is for reading, 1 is for writing */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sigterm_iochn = g_io_channel_unix_new (sigterm_unix_signal_pipe_fds[0]);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (sigterm_iochn == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DIE (("Could not create GIOChannel"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* get callback when there is data to read */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sigterm_iochn_listener_source_id = g_io_add_watch (
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sigterm_iochn, G_IO_IN, sigterm_iochn_data, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Finally, setup unix signal handler for TERM */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem signal (SIGTERM, handle_sigterm);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* set up the local dbus server */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!hald_dbus_local_server_init ())
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Start the runner helper daemon */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!hald_runner_start_runner ()) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem drop_privileges(0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* initialize operating system specific parts */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem osspec_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_initialising = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* detect devices */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem osspec_probe ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* run the main loop and serve clients */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_main_loop_run (loop);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HALD_MEMLEAK_DBG
18c2aff776a775d34a4c9893a4c72e0434d68e36artemextern int dbg_hal_device_object_delta;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* useful for valgrinding; see below */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmy_shutdown (gpointer data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HalDeviceStore *gdl;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Num devices in TDL: %d\n", g_slist_length ((hald_get_tdl ())->devices));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Num devices in GDL: %d\n", g_slist_length ((hald_get_gdl ())->devices));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gdl = hald_get_gdl ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artemnext:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (g_slist_length (gdl->devices) > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HalDevice *d = HAL_DEVICE(gdl->devices->data);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hal_device_store_remove (gdl, d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_object_unref (d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto next;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("hal_device_object_delta = %d (should be zero)\n", dbg_hal_device_object_delta);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_probe_done (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ssize_t written;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char buf[1] = {0};
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("Device probing completed"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!hald_dbus_init ()) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_runner_kill_all();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* tell parent to exit */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem written = write (startup_daemonize_pipe[1], buf, sizeof (buf));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close (startup_daemonize_pipe[0]);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close (startup_daemonize_pipe[1]);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hald_is_initialising = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HALD_MEMLEAK_DBG
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_timeout_add ((HALD_MEMLEAK_DBG) * 1000,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_shutdown,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** @} */