/** * Main * * @param argc Number of command line arguments * @param argv Array with command line arguments * @return 0 on success, non-zero on failure */ int main(int argc, char **argv) { int status = EXIT_FAILURE; /* Set the program-name */ progname = PRG_NAME; /* Parse the command-line options */ if( !mce_command_line_parse(options, argc, argv) ) goto EXIT; /* We don't take any non-flag arguments */ if ((argc - optind) > 0) { fprintf(stderr, "%s: Too many arguments\n" "Try: `%s --help' for more information.\n", progname, progname); exit(EXIT_FAILURE); } mce_log_open(PRG_NAME, LOG_DAEMON, mce_args.logtype); mce_log_set_verbosity(mce_args.verbosity); #ifdef ENABLE_WAKELOCKS /* Since mce enables automatic suspend, we must try to * disable it when mce process exits */ atexit(mce_cleanup_wakelocks); /* Allow acquiring of multiplexed wakelock */ mce_wakelock_init(); #endif /* Identify mce version & flavor on start up */ mce_log(LL_WARN, "MCE %s (%s) starting up", G_STRINGIFY(PRG_VERSION), (LL_DEVEL == LL_EXTRA) ? "devel" : "release"); /* Daemonize if requested */ if( mce_args.daemonflag ) daemonize(); /* Register a mainloop */ mainloop = g_main_loop_new(NULL, FALSE); /* Signal handlers can be installed once we have a mainloop */ if( !mce_init_signal_pipe() ) { mce_log(LL_CRIT, "Failed to initialise signal pipe"); exit(EXIT_FAILURE); } mce_signal_handlers_install(); /* Initialise subsystems */ /* Get configuration options */ if( !mce_conf_init() ) { mce_log(LL_CRIT, "Failed to initialise configuration options"); exit(EXIT_FAILURE); } /* Open fbdev as early as possible */ mce_fbdev_init(); /* Start worker thread */ if( !mce_worker_init() ) goto EXIT; /* Initialise D-Bus */ if( !mce_dbus_init(mce_args.systembus) ) { mce_log(LL_CRIT, "Failed to initialise D-Bus"); exit(EXIT_FAILURE); } /* Initialise GConf * pre-requisite: g_type_init() */ if (mce_setting_init() == FALSE) { mce_log(LL_CRIT, "Cannot connect to default GConf engine"); exit(EXIT_FAILURE); } /* Setup all datapipes */ mce_datapipe_init(); /* Allow registering of suspend proof timers */ mce_hbtimer_init(); /* Allow registering of suspend blocking timers */ mce_wltimer_init(); /* Initialise mode management * pre-requisite: mce_setting_init() * pre-requisite: mce_dbus_init() */ if (mce_mode_init() == FALSE) { goto EXIT; } /* Initialise DSME * pre-requisite: mce_setting_init() * pre-requisite: mce_dbus_init() * pre-requisite: mce_mce_init() */ if( !mce_dsme_init() ) goto EXIT; /* Initialise powerkey driver */ if (mce_powerkey_init() == FALSE) { goto EXIT; } /* Initialise /dev/input driver * pre-requisite: g_type_init() */ if (mce_input_init() == FALSE) { goto EXIT; } /* Initialise switch driver */ if (mce_switches_init() == FALSE) { goto EXIT; } /* Initialise tklock driver */ if (mce_tklock_init() == FALSE) { goto EXIT; } if( !mce_sensorfw_init() ) { goto EXIT; } if( !mce_common_init() ) goto EXIT; /* Load all modules */ if (mce_modules_init() == FALSE) { goto EXIT; } if( mce_args.show_module_info ) { mce_modules_dump_info(); goto EXIT; } /* MCE startup succeeded */ status = EXIT_SUCCESS; /* Tell systemd that we have started up */ if( mce_args.systemd_notify ) { mce_log(LL_NOTICE, "notifying systemd"); sd_notify(0, "READY=1"); } /* Debug feature: exit after startup is finished */ if( mce_args.auto_exit >= 0 ) { mce_log(LL_WARN, "auto-exit scheduled"); g_idle_add(mce_auto_exit_cb, 0); } /* Use timerfd to detect resume from suspend */ mce_io_init_resume_timer(); /* Run the main loop */ g_main_loop_run(mainloop); /* If we get here, the main loop has terminated; * either because we requested or because of an error */ EXIT: mce_io_quit_resume_timer(); /* Unload all modules */ mce_modules_exit(); mce_common_quit(); /* Call the exit function for all components */ mce_sensorfw_quit(); mce_tklock_exit(); mce_switches_exit(); mce_input_exit(); mce_powerkey_exit(); mce_dsme_exit(); mce_mode_exit(); mce_wltimer_quit(); mce_hbtimer_quit(); /* Free all datapipes */ mce_datapipe_quit(); /* Call the exit function for all subsystems */ mce_setting_exit(); mce_dbus_exit(); mce_conf_exit(); mce_worker_quit(); mce_fbdev_quit(); /* If the mainloop is initialised, unreference it */ if (mainloop != NULL) { g_main_loop_unref(mainloop); mainloop = 0; } /* Close signal pipe & remove io watch for it */ mce_quit_signal_pipe(); /* Release multiplexed wakelock */ mce_wakelock_quit(); /* Log a farewell message and close the log */ mce_log(LL_INFO, "Exiting..."); /* No more logging expected */ mce_log_close(); return status; }
/** * Main * * @param argc Number of command line arguments * @param argv Array with command line arguments * @return 0 on success, non-zero on failure */ int main(int argc, char **argv) { int optc; int opt_index; int verbosity = LL_DEFAULT; int logtype = MCE_LOG_SYSLOG; gint status = EXIT_FAILURE; gboolean show_module_info = FALSE; gboolean daemonflag = FALSE; gboolean systembus = TRUE; gboolean debugmode = FALSE; const char optline[] = "dsTSMDqvhVt:"; struct option const options[] = { { "daemonflag", no_argument, 0, 'd' }, { "force-syslog", no_argument, 0, 's' }, { "force-stderr", no_argument, 0, 'T' }, { "session", no_argument, 0, 'S' }, { "show-module-info", no_argument, 0, 'M' }, { "debug-mode", no_argument, 0, 'D' }, { "quiet", no_argument, 0, 'q' }, { "verbose", no_argument, 0, 'v' }, { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "trace", required_argument, 0, 't' }, { 0, 0, 0, 0 } }; /* Initialise support for locales, and set the program-name */ if (init_locales(PRG_NAME) != 0) goto EXIT; /* Parse the command-line options */ while ((optc = getopt_long(argc, argv, optline, options, &opt_index)) != -1) { switch (optc) { case 'd': daemonflag = TRUE; break; case 's': logtype = MCE_LOG_SYSLOG; break; case 'T': logtype = MCE_LOG_STDERR; break; case 'S': systembus = FALSE; break; case 'M': show_module_info = TRUE; break; case 'D': debugmode = TRUE; break; case 'q': if (verbosity > LL_NONE) verbosity--; break; case 'v': if (verbosity < LL_DEBUG) verbosity++; break; case 'h': usage(); exit(EXIT_SUCCESS); case 'V': version(); exit(EXIT_SUCCESS); case 't': if( !mce_enable_trace(optarg) ) exit(EXIT_FAILURE); break; default: usage(); exit(EXIT_FAILURE); } } /* We don't take any non-flag arguments */ if ((argc - optind) > 0) { fprintf(stderr, _("%s: Too many arguments\n" "Try: `%s --help' for more information.\n"), progname, progname); exit(EXIT_FAILURE); } mce_log_open(PRG_NAME, LOG_DAEMON, logtype); mce_log_set_verbosity(verbosity); #ifdef ENABLE_WAKELOCKS /* Since mce enables automatic suspend, we must try to * disable it when mce process exits */ atexit(mce_cleanup_wakelocks); #endif /* Daemonize if requested */ if (daemonflag == TRUE) daemonize(); /* Initialise GType system */ g_type_init(); /* Register a mainloop */ mainloop = g_main_loop_new(NULL, FALSE); /* Signal handlers can be installed once we have a mainloop */ if( !mce_init_signal_pipe() ) { mce_log(LL_CRIT, "Failed to initialise signal pipe"); exit(EXIT_FAILURE); } install_signal_handlers(); /* Initialise subsystems */ /* Get configuration options */ if( !mce_conf_init() ) { mce_log(LL_CRIT, "Failed to initialise configuration options"); exit(EXIT_FAILURE); } /* Initialise D-Bus */ if (mce_dbus_init(systembus) == FALSE) { mce_log(LL_CRIT, "Failed to initialise D-Bus"); mce_log_close(); exit(EXIT_FAILURE); } /* Initialise GConf * pre-requisite: g_type_init() */ if (mce_gconf_init() == FALSE) { mce_log(LL_CRIT, "Cannot connect to default GConf engine"); mce_log_close(); exit(EXIT_FAILURE); } /* Setup all datapipes */ setup_datapipe(&system_state_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(MCE_STATE_UNDEF)); setup_datapipe(&master_radio_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&call_state_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(CALL_STATE_NONE)); setup_datapipe(&call_type_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(NORMAL_CALL)); setup_datapipe(&alarm_ui_state_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(MCE_ALARM_UI_INVALID_INT32)); setup_datapipe(&submode_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(MCE_NORMAL_SUBMODE)); setup_datapipe(&display_state_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(MCE_DISPLAY_UNDEF)); setup_datapipe(&display_brightness_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&led_brightness_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&led_pattern_activate_pipe, READ_ONLY, FREE_CACHE, 0, NULL); setup_datapipe(&led_pattern_deactivate_pipe, READ_ONLY, FREE_CACHE, 0, NULL); setup_datapipe(&key_backlight_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&keypress_pipe, READ_ONLY, FREE_CACHE, sizeof (struct input_event), NULL); setup_datapipe(&touchscreen_pipe, READ_ONLY, FREE_CACHE, sizeof (struct input_event), NULL); setup_datapipe(&device_inactive_pipe, READ_WRITE, DONT_FREE_CACHE, 0, GINT_TO_POINTER(FALSE)); setup_datapipe(&lockkey_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&keyboard_slide_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&lid_cover_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&lens_cover_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&proximity_sensor_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&tk_lock_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(LOCK_UNDEF)); setup_datapipe(&charger_state_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&battery_status_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(BATTERY_STATUS_UNDEF)); setup_datapipe(&battery_level_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(100)); setup_datapipe(&camera_button_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(CAMERA_BUTTON_UNDEF)); setup_datapipe(&inactivity_timeout_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(DEFAULT_INACTIVITY_TIMEOUT)); setup_datapipe(&audio_route_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(AUDIO_ROUTE_UNDEF)); setup_datapipe(&usb_cable_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&jack_sense_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&power_saving_mode_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); setup_datapipe(&thermal_state_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(THERMAL_STATE_UNDEF)); setup_datapipe(&heartbeat_pipe, READ_ONLY, DONT_FREE_CACHE, 0, GINT_TO_POINTER(0)); /* Initialise mode management * pre-requisite: mce_gconf_init() * pre-requisite: mce_dbus_init() */ if (mce_mode_init() == FALSE) { goto EXIT; } /* Initialise DSME * pre-requisite: mce_gconf_init() * pre-requisite: mce_dbus_init() * pre-requisite: mce_mce_init() */ if (mce_dsme_init(debugmode) == FALSE) { if (debugmode == FALSE) { mce_log(LL_CRIT, "Cannot connect to DSME"); goto EXIT; } } /* Initialise powerkey driver */ if (mce_powerkey_init() == FALSE) { goto EXIT; } /* Initialise /dev/input driver * pre-requisite: g_type_init() */ if (mce_input_init() == FALSE) { goto EXIT; } /* Initialise switch driver */ if (mce_switches_init() == FALSE) { goto EXIT; } /* Initialise tklock driver */ if (mce_tklock_init() == FALSE) { goto EXIT; } /* Load all modules */ if (mce_modules_init() == FALSE) { goto EXIT; } if (show_module_info == TRUE) { mce_modules_dump_info(); goto EXIT; } /* MCE startup succeeded */ status = EXIT_SUCCESS; /* Run the main loop */ g_main_loop_run(mainloop); /* If we get here, the main loop has terminated; * either because we requested or because of an error */ EXIT: /* Unload all modules */ mce_modules_exit(); /* Call the exit function for all components */ mce_tklock_exit(); mce_switches_exit(); mce_input_exit(); mce_powerkey_exit(); mce_dsme_exit(); mce_mode_exit(); /* Free all datapipes */ free_datapipe(&thermal_state_pipe); free_datapipe(&power_saving_mode_pipe); free_datapipe(&jack_sense_pipe); free_datapipe(&usb_cable_pipe); free_datapipe(&audio_route_pipe); free_datapipe(&inactivity_timeout_pipe); free_datapipe(&battery_level_pipe); free_datapipe(&battery_status_pipe); free_datapipe(&charger_state_pipe); free_datapipe(&tk_lock_pipe); free_datapipe(&proximity_sensor_pipe); free_datapipe(&lens_cover_pipe); free_datapipe(&lid_cover_pipe); free_datapipe(&keyboard_slide_pipe); free_datapipe(&lockkey_pipe); free_datapipe(&device_inactive_pipe); free_datapipe(&touchscreen_pipe); free_datapipe(&keypress_pipe); free_datapipe(&key_backlight_pipe); free_datapipe(&led_pattern_deactivate_pipe); free_datapipe(&led_pattern_activate_pipe); free_datapipe(&led_brightness_pipe); free_datapipe(&display_brightness_pipe); free_datapipe(&display_state_pipe); free_datapipe(&submode_pipe); free_datapipe(&alarm_ui_state_pipe); free_datapipe(&call_type_pipe); free_datapipe(&call_state_pipe); free_datapipe(&master_radio_pipe); free_datapipe(&system_state_pipe); free_datapipe(&heartbeat_pipe); /* Call the exit function for all subsystems */ mce_gconf_exit(); mce_dbus_exit(); mce_conf_exit(); /* If the mainloop is initialised, unreference it */ if (mainloop != NULL) { g_main_loop_unref(mainloop); mainloop = 0; } /* Log a farewell message and close the log */ mce_log(LL_INFO, "Exiting..."); /* We do not need to explicitly close the log and doing so * would not allow logging from atexit handlers */ //mce_log_close(); return status; }