1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-28 13:55:08 +03:00
Files
libgpiod/dbus/manager/gpio-manager.c
Bartosz Golaszewski 5204b44f83 dbus: manager: display C API *and* libgpiod package version for '-v'
With the recent changes to the versioning scheme and the disassociation
of the core C API from the libgpiod package version, it now makes sense
to display both in the output of 'gpio-manager --version'.

Acked-by: Erik Wierich <erik@riscstar.com>
Link: https://lore.kernel.org/r/20250903-api-version-detach-v1-6-027ca5928518@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
2025-09-09 10:24:00 +02:00

186 lines
4.5 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2022-2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
#include <gio/gio.h>
#include <glib.h>
#include <glib-unix.h>
#include <gpiod-glib.h>
#include <gpiodbus.h>
#include <stdlib.h>
#include "daemon.h"
static const gchar *const debug_domains[] = {
"gpio-manager",
"gpiodglib",
NULL
};
static gboolean stop_main_loop_on_sig(gpointer data, const gchar *signame)
{
GMainLoop *loop = data;
g_debug("%s received", signame);
g_main_loop_quit(loop);
return G_SOURCE_REMOVE;
}
static gboolean on_sigterm(gpointer data)
{
return stop_main_loop_on_sig(data, "SIGTERM");
}
static gboolean on_sigint(gpointer data)
{
return stop_main_loop_on_sig(data, "SIGINT");
}
static gboolean on_sighup(gpointer data G_GNUC_UNUSED)
{
g_debug("SIGHUB received, ignoring");
return G_SOURCE_CONTINUE;
}
static void on_bus_acquired(GDBusConnection *con,
const gchar *name G_GNUC_UNUSED,
gpointer data)
{
GpiodbusDaemon *daemon = data;
g_debug("D-Bus connection acquired");
gpiodbus_daemon_start(daemon, con);
}
static void on_name_acquired(GDBusConnection *con G_GNUC_UNUSED,
const gchar *name, gpointer data G_GNUC_UNUSED)
{
g_debug("D-Bus name acquired: '%s'", name);
}
static void on_name_lost(GDBusConnection *con,
const gchar *name, gpointer data G_GNUC_UNUSED)
{
g_debug("D-Bus name lost: '%s'", name);
if (!con)
g_error("unable to make connection to the bus");
if (g_dbus_connection_is_closed(con))
g_error("connection to the bus closed");
g_error("name '%s' lost on the bus", name);
}
static void print_version_and_exit(void)
{
g_print("%s v%s (libgpiod v%s)\nD-Bus API version: %d\n",
g_get_prgname(), GPIOD_VERSION_STR,
gpiodglib_api_version(), GPIODBUS_API_VERSION);
exit(EXIT_SUCCESS);
}
static void parse_opts(int argc, char **argv)
{
static const char *const description =
"The gpio-manager is the reference implementation of the GPIO D-Bus API\n"
"built on top of libgpiod. It serves as the central authority managing GPIO\n"
"chips and lines, exposing their functionalities to other applications\n"
"through the D-Bus interface. It supports operations such as requesting,\n"
"releasing, and setting line values, as well as monitoring events like rising\n"
"or falling edges and line property changes.";
gboolean ret, opt_debug = FALSE, opt_version = FALSE;
g_autoptr(GOptionContext) ctx = NULL;
g_auto(GStrv) remaining = NULL;
g_autoptr(GError) err = NULL;
const GOptionEntry opts[] = {
{
.long_name = "debug",
.short_name = 'd',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &opt_debug,
.description = "Emit additional debug log messages.",
},
{
.long_name = "version",
.short_name = 'v',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &opt_version,
.description = "Print version and exit.",
},
{
.long_name = G_OPTION_REMAINING,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_STRING_ARRAY,
.arg_data = &remaining,
},
{ }
};
ctx = g_option_context_new(NULL);
g_option_context_set_summary(ctx, "D-Bus daemon managing GPIOs.");
g_option_context_set_description(ctx, description);
g_option_context_add_main_entries(ctx, opts, NULL);
ret = g_option_context_parse(ctx, &argc, &argv, &err);
if (!ret) {
g_printerr("Option parsing failed: %s\n\nUse %s --help\n",
err->message, g_get_prgname());
exit(EXIT_FAILURE);
}
if (remaining) {
g_printerr("Option parsing failed: additional arguments are not allowed\n");
exit(EXIT_FAILURE);
}
if (opt_version)
print_version_and_exit();
if (opt_debug)
g_log_writer_default_set_debug_domains(debug_domains);
}
int main(int argc, char **argv)
{
g_autoptr(GpiodbusDaemon) daemon = NULL;
g_autofree gchar *basename = NULL;
g_autoptr(GMainLoop) loop = NULL;
guint bus_id;
basename = g_path_get_basename(argv[0]);
g_set_prgname(basename);
parse_opts(argc, argv);
g_message("initializing %s", g_get_prgname());
loop = g_main_loop_new(NULL, FALSE);
daemon = gpiodbus_daemon_new();
g_unix_signal_add(SIGTERM, on_sigterm, loop);
g_unix_signal_add(SIGINT, on_sigint, loop);
g_unix_signal_add(SIGHUP, on_sighup, NULL); /* Ignore SIGHUP. */
bus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "io.gpiod1",
G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired,
on_name_acquired, on_name_lost, daemon, NULL);
g_message("%s started", g_get_prgname());
g_main_loop_run(loop);
g_bus_unown_name(bus_id);
g_message("%s exiting", g_get_prgname());
return EXIT_SUCCESS;
}