一个简单的dbus服务器及其客户端#
由于systemd合并udev之后,咱们就不能再用udev的规则来挂接移动硬盘了
所以决定利用dbus的机制来规避systemd对于cgroup控制导致的挂接移动硬盘问题
开发一个简单的dbus服务器,其功能很简单,接收从客户端过来的命令参数,然后调用system()来执行
这当然是有安全问题的,但在自己的机器使用,谁管呢
Copy Highlighter-hljs
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| #include <dbus/dbus.h> |
| #include <dbus/dbus-glib.h> |
| #include <dbus/dbus-glib-bindings.h> |
| #include <glib-object.h> |
| #include "dbus_exec_cmd.h" |
| #include "simple_exec_glue.h" |
| |
| |
| G_DEFINE_TYPE(DbusExecCmd, dbus_exec_cmd, G_TYPE_OBJECT) |
| |
| GQuark simple_exec_error (void) |
| { |
| static GQuark quark = 0; |
| if (!quark) |
| quark = g_quark_from_static_string ("simple_exec_error"); |
| return quark; |
| } |
| |
| |
| static void dbus_exec_cmd_class_init (DbusExecCmdClass *dbus_exec_cmd_class) |
| { |
| dbus_g_object_type_install_info (G_OBJECT_CLASS_TYPE (dbus_exec_cmd_class), &dbus_glib_simple_exec_object_info); |
| } |
| |
| |
| static void dbus_exec_cmd_init (DbusExecCmd *dbus_exec_cmd) |
| { |
| } |
| |
| gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error) |
| { |
| int status; |
| g_print ("[Simple Dbus Exec]Start to execute: %s\n", cmd_str); |
| status = system(cmd_str); |
| if (0 != status) |
| { |
| |
| g_set_error (error, simple_exec_error(), 1, "[Simple Dbus Exec]fail to execute command:%s\n", cmd_str); |
| g_warning("[Simple Dbus Exec]fail to execute: %s, error: %d\n", cmd_str, status); |
| |
| return FALSE; |
| } |
| if(WIFEXITED(status)) |
| { |
| g_warning("normal termination, exit status = %d\n", WEXITSTATUS(status)); |
| } |
| else if(WIFSIGNALED(status)) |
| { |
| g_warning("abnormal termination,signal number =%d\n", WTERMSIG(status)); |
| else if(WIFSTOPPED(status)) |
| { |
| g_warning("process stopped, signal number =%d\n", WSTOPSIG(status)); |
| g_print ("[Simple Dbus Exec]Finish to execute command\n"); |
| |
| return TRUE; |
| } |
| |
| static void die (const char *prefix, GError *error) |
| { |
| g_error("%s: %s", prefix, error->message); |
| g_error_free (error); |
| exit(1); |
| } |
| |
| #define SIMPLE_EXEC_SERVICE_NAME "org.dbus_exec_cmd.simple_exec" |
| |
| int main (int argc, char **argv) |
| { |
| GMainLoop *loop; |
| DBusGConnection *connection; |
| GError *error = NULL; |
| GObject *obj; |
| DBusGProxy *driver_proxy; |
| guint32 request_name_ret; |
| |
| g_type_init (); |
| |
| if (!g_thread_supported ()) |
| g_thread_init (NULL); |
| |
| dbus_g_thread_init (); |
| |
| loop = g_main_loop_new (NULL, FALSE); |
| |
| g_print ("[Simple Dbus Exec]Launching Simple Exec Object\n"); |
| |
| |
| connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); |
| if (connection == NULL) |
| { |
| die ("[Simple Dbus Exec]Failed to open connection to bus", error); |
| } |
| |
| obj = g_object_new (DBUS_EXEC_CMD_TYPE, NULL); |
| |
| dbus_g_connection_register_g_object (connection, |
| "/org/dbus_exec_cmd/simple_exec", |
| obj); |
| |
| driver_proxy = dbus_g_proxy_new_for_name (connection, |
| DBUS_SERVICE_DBUS, |
| DBUS_PATH_DBUS, |
| DBUS_INTERFACE_DBUS); |
| |
| if (!org_freedesktop_DBus_request_name (driver_proxy, SIMPLE_EXEC_SERVICE_NAME, |
| 0, &request_name_ret, &error)) |
| { |
| die ("[Simple Dbus Exec]Failed to get name", error); |
| } |
| |
| if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) |
| { |
| g_error ("[Simple Dbus Exec]Got result code %u from requesting name", request_name_ret); |
| exit (1); |
| } |
| |
| g_print ("[Simple Dbus Exec]GLib service has name: [%s]\n", SIMPLE_EXEC_SERVICE_NAME); |
| |
| g_print ("[Simple Dbus Exec]GLib service entering main loop\n"); |
| g_main_loop_run (loop); |
| g_print ("[Simple Dbus Exec]Successfully completed %s\n", argv[0]); |
| |
| return 0; |
| } |
Copy Highlighter-hljs
| #include <glib-object.h> |
| |
| typedef struct DbusExecCmd DbusExecCmd; |
| typedef struct DbusExecCmdClass DbusExecCmdClass; |
| |
| GType dbus_exec_cmd_get_type (void); |
| |
| struct DbusExecCmd |
| { |
| GObject parent; |
| }; |
| |
| struct DbusExecCmdClass |
| { |
| GObjectClass parent; |
| }; |
| |
| #define DBUS_EXEC_CMD_TYPE (dbus_exec_cmd_get_type ()) |
| #define DBUS_EXEC_CMD(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DBUS_EXEC_CMD_TYPE, DbusExecCmd)) |
| #define DBUS_EXEC_CMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass)) |
| #define IS_DBUS_EXEC_CMD(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DBUS_EXEC_CMD_TYPE)) |
| #define IS_DBUS_EXEC_CMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUS_EXEC_CMD_TYPE)) |
| #define DBUS_EXEC_CMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass)) |
| |
| typedef enum |
| { |
| ECHO_ERROR_GENERIC |
| } DbusExecCmdError; |
| |
| gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error); |
Copy Highlighter-hljs
| <?xml version="1.0" encoding="UTF-8" ?> |
| <node name="/org/dbus_exec_cmd/simple_exec"> |
| <interface name='org.dbus_exec_cmd.simple_exec'> |
| <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="simple"/> |
| <method name='exec_command'> |
| <arg type='s' name='cmd_str' direction='in' /> |
| </method> |
| </interface> |
| </node> |
Copy Highlighter-hljs
| <!DOCTYPE busconfig PUBLIC |
| "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" |
| "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> |
| <busconfig> |
| |
| <policy user="root"> |
| <allow own="org.dbus_exec_cmd.simple_exec"/> |
| </policy> |
| |
| |
| <policy user="root"> |
| <allow send_destination="org.dbus_exec_cmd.simple_exec"/> |
| <allow receive_sender="org.dbus_exec_cmd.simple_exec"/> |
| </policy> |
| </busconfig> |
Copy Highlighter-hljs
| [D-BUS Service] |
| Name=org.dbus_exec_cmd.simple_exec |
| Exec=@bindir@/simple_exec |
| User=root |
simple_dbus_exec.004.7z
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)