/
githubmirror
/
fwupd
Обзор
Документация
Войти
/
githubmirror
/
fwupd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
2.0.21
src/fu-main.c
195 строк
5 KB
Richard Hughes
Refactor the hypervisor and container detection to be usable from plugins
19 ноя 2025, 17:25
19 ноя 2025, 17:25
0bf93bb
Код
Авторство
О чём код?
/* * Copyright 2015 Richard Hughes <richard@hughsie.com> * * SPDX-License-Identifier: LGPL-2.1-or-later */ #define G_LOG_DOMAIN "FuMain" #include "config.h" #include <fwupd.h> #include <glib/gi18n.h> #include <glib/gstdio.h> #include <locale.h> #include <stdlib.h> #ifdef HAVE_GIO_UNIX #include <glib-unix.h> #endif #ifdef HAVE_SYSTEMD #include <systemd/sd-daemon.h> #endif #include "fu-daemon.h" #include "fu-debug.h" #ifdef HAVE_GIO_UNIX static gboolean fu_main_sigterm_cb(gpointer user_data) { FuDaemon *daemon = FU_DAEMON(user_data); g_autoptr(GError) error = NULL; g_warning("Received SIGTERM"); if (!fu_daemon_stop(daemon, &error)) g_warning("failed to stop daemon, will wait: %s\n", error->message); return G_SOURCE_CONTINUE; } #endif static gboolean fu_main_timed_exit_cb(gpointer user_data) { FuDaemon *daemon = FU_DAEMON(user_data); g_autoptr(GError) error = NULL; if (!fu_daemon_stop(daemon, &error)) g_warning("failed to stop daemon, will wait: %s\n", error->message); return G_SOURCE_REMOVE; } static void fu_main_argv_changed_cb(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data) { FuDaemon *daemon = FU_DAEMON(user_data); g_autoptr(GError) error = NULL; g_info("binary changed, shutting down"); if (!fu_daemon_stop(daemon, &error)) g_warning("failed to stop daemon, will wait: %s\n", error->message); } static void fu_main_memory_monitor_warning_cb(GMemoryMonitor *memory_monitor, GMemoryMonitorWarningLevel level, FuDaemon *daemon) { g_autoptr(GError) error = NULL; g_info("OOM event, shutting down"); if (!fu_daemon_stop(daemon, &error)) g_warning("failed to stop daemon, will wait: %s\n", error->message); } int main(int argc, char *argv[]) { gboolean immediate_exit = FALSE; gboolean timed_exit = FALSE; const gchar *socket_filename = g_getenv("FWUPD_DBUS_SOCKET"); const GOptionEntry options[] = { {"timed-exit", '\0', 0, G_OPTION_ARG_NONE, &timed_exit, /* TRANSLATORS: exit after we've started up, used for user profiling */ N_("Exit after a small delay"), NULL}, {"immediate-exit", '\0', 0, G_OPTION_ARG_NONE, &immediate_exit, /* TRANSLATORS: exit straight away, used for automatic profiling */ N_("Exit after the engine has loaded"), NULL}, {NULL}}; g_autofree gchar *socket_address = NULL; g_autoptr(GError) error = NULL; g_autoptr(GFile) argv0_file = g_file_new_for_path(argv[0]); g_autoptr(GOptionContext) context = NULL; g_autoptr(FuDaemon) daemon = fu_daemon_new(); g_autoptr(GFileMonitor) argv0_monitor = NULL; g_autoptr(GMemoryMonitor) memory_monitor = NULL; setlocale(LC_ALL, ""); bindtextdomain(GETTEXT_PACKAGE, FWUPD_LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); /* TRANSLATORS: program name */ g_set_application_name(_("Firmware Update Daemon")); context = g_option_context_new(NULL); g_option_context_add_main_entries(context, options, NULL); g_option_context_add_group(context, fu_debug_get_option_group()); /* TRANSLATORS: program summary */ g_option_context_set_summary(context, _("Firmware Update D-Bus Service")); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("Failed to parse command line: %s\n", error->message); return EXIT_FAILURE; } #ifdef FWUPD_DBUS_SOCKET_ADDRESS /* this is set for macOS and Windows */ if (socket_filename == NULL) socket_filename = g_strdup(FWUPD_DBUS_SOCKET_ADDRESS); #endif /* convert from filename to address, if required */ if (socket_filename != NULL) { if (g_strrstr(socket_filename, "=") == NULL) { #ifndef HAVE_SYSTEMD /* this must be owned by root */ if (g_file_test(socket_filename, G_FILE_TEST_EXISTS)) g_unlink(socket_filename); #endif socket_address = g_strdup_printf("unix:path=%s", socket_filename); } else { socket_address = g_strdup(socket_filename); } } /* set up the daemon, which includes coldplugging devices */ if (!fu_daemon_setup(daemon, socket_address, &error)) { g_printerr("Failed to load daemon: %s\n", error->message); return EXIT_FAILURE; } #ifdef HAVE_GIO_UNIX g_unix_signal_add_full(G_PRIORITY_DEFAULT, SIGTERM, fu_main_sigterm_cb, daemon, NULL); #endif /* HAVE_GIO_UNIX */ /* restart the daemon if the binary gets replaced */ argv0_monitor = g_file_monitor_file(argv0_file, G_FILE_MONITOR_NONE, NULL, &error); g_signal_connect(G_FILE_MONITOR(argv0_monitor), "changed", G_CALLBACK(fu_main_argv_changed_cb), daemon); /* shut down on low memory event as we can just rescan hardware */ memory_monitor = g_memory_monitor_dup_default(); if (memory_monitor != NULL) { g_signal_connect(G_MEMORY_MONITOR(memory_monitor), "low-memory-warning", G_CALLBACK(fu_main_memory_monitor_warning_cb), daemon); } /* Only timeout and close the mainloop if we have specified it * on the command line */ if (immediate_exit) g_idle_add(fu_main_timed_exit_cb, daemon); else if (timed_exit) g_timeout_add_seconds(5, fu_main_timed_exit_cb, daemon); /* wait */ g_message("fwupd %s ready for requests (locale %s)", VERSION, g_getenv("LANG")); if (!fu_daemon_start(daemon, &error)) { g_printerr("Failed to start daemon: %s\n", error->message); return EXIT_FAILURE; } #ifdef HAVE_SYSTEMD /* notify the service manager */ sd_notify(0, "STOPPING=1"); #endif /* cancel to avoid a deadlock */ g_file_monitor_cancel(argv0_monitor); /* success */ return EXIT_SUCCESS; }