寻求基于glib gio与systemd服务交互的示例代码
使用GLib GIO与systemd服务交互的示例代码
systemd通过DBus提供服务管理接口,GLib的GIO模块可通过GDBusProxy直接与这些接口交互。以下是实现启动、停止、查询服务状态的完整示例:
示例代码
#include <glib-2.0/gio/gio.h> #include <stdio.h> #define SYSTEMD_BUS_NAME "org.freedesktop.systemd1" #define SYSTEMD_OBJECT_PATH "/org/freedesktop/systemd1" #define SYSTEMD_MANAGER_INTERFACE "org.freedesktop.systemd1.Manager" #define SYSTEMD_SERVICE_INTERFACE "org.freedesktop.systemd1.Service" // 查询指定服务的状态 gboolean get_service_status(const gchar *service_name, GError **error) { GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, SYSTEMD_BUS_NAME, SYSTEMD_OBJECT_PATH, SYSTEMD_MANAGER_INTERFACE, NULL, error); if (!manager_proxy) return FALSE; // 获取服务的DBus对象路径 GVariant *result = g_dbus_proxy_call_sync(manager_proxy, "GetUnit", g_variant_new("(s)", service_name), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (!result) { g_object_unref(manager_proxy); return FALSE; } gchar *unit_path; g_variant_get(result, "(o)", &unit_path); g_variant_unref(result); // 创建服务对象的代理 GDBusProxy *service_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, SYSTEMD_BUS_NAME, unit_path, SYSTEMD_SERVICE_INTERFACE, NULL, error); g_free(unit_path); if (!service_proxy) { g_object_unref(manager_proxy); return FALSE; } // 获取服务的ActiveState属性 GVariant *state = g_dbus_proxy_get_cached_property(service_proxy, "ActiveState"); if (state) { const gchar *state_str = g_variant_get_string(state, NULL); g_print("服务 %s 状态: %s\n", service_name, state_str); g_variant_unref(state); } g_object_unref(service_proxy); g_object_unref(manager_proxy); return TRUE; } // 启动指定服务 gboolean start_service(const gchar *service_name, GError **error) { GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, SYSTEMD_BUS_NAME, SYSTEMD_OBJECT_PATH, SYSTEMD_MANAGER_INTERFACE, NULL, error); if (!manager_proxy) return FALSE; GVariant *result = g_dbus_proxy_call_sync(manager_proxy, "StartUnit", g_variant_new("(ss)", service_name, "replace"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (result) { g_variant_unref(result); g_print("服务 %s 启动请求已发送\n", service_name); } g_object_unref(manager_proxy); return result != NULL; } // 停止指定服务 gboolean stop_service(const gchar *service_name, GError **error) { GDBusProxy *manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, SYSTEMD_BUS_NAME, SYSTEMD_OBJECT_PATH, SYSTEMD_MANAGER_INTERFACE, NULL, error); if (!manager_proxy) return FALSE; GVariant *result = g_dbus_proxy_call_sync(manager_proxy, "StopUnit", g_variant_new("(ss)", service_name, "replace"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (result) { g_variant_unref(result); g_print("服务 %s 停止请求已发送\n", service_name); } g_object_unref(manager_proxy); return result != NULL; } int main(int argc, char *argv[]) { g_type_init(); GError *error = NULL; if (argc < 3) { g_print("用法: %s <start/stop/status> <服务名(如nginx.service)>\n", argv[0]); return 1; } const gchar *action = argv[1]; const gchar *service = argv[2]; if (g_str_equal(action, "start")) { if (!start_service(service, &error)) goto error_handler; } else if (g_str_equal(action, "stop")) { if (!stop_service(service, &error)) goto error_handler; } else if (g_str_equal(action, "status")) { if (!get_service_status(service, &error)) goto error_handler; } else { g_print("无效操作: %s,支持的操作:start/stop/status\n", action); return 1; } return 0; error_handler: g_print("错误: %s\n", error->message); g_error_free(error); return 1; }
编译与运行
编译时需链接GLib和GIO库,使用以下命令:
gcc -o systemd-gio systemd-gio.c `pkg-config --cflags --libs glib-2.0 gio-2.0`
运行需要root权限(管理systemd服务需特权):
sudo ./systemd-gio status nginx.service sudo ./systemd-gio start nginx.service
关键说明
- 通过系统DBus与systemd交互,使用
G_BUS_TYPE_SYSTEM而非会话DBus - systemd核心管理接口为
org.freedesktop.systemd1.Manager,提供StartUnit、StopUnit、GetUnit等方法 - 服务的具体属性(如运行状态)通过服务对象的
org.freedesktop.systemd1.Service接口获取 - 示例使用同步DBus调用,适合简单场景;如需异步处理,可替换为
g_dbus_proxy_call()
内容的提问来源于stack exchange,提问作者CTCoding
相关产品推荐
相关产品推荐

