You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用busctl通过DBus传递文件描述符出现异常的原因排查

问题:GDBus服务接收文件描述符时出现随机大负数

我使用GDBus实现了一个DBus服务,方法定义的XML代码如下:

<method name='GetMimeTypeData'>
    <arg name='id' type='s' direction='in'/>
    <arg name='mime_type' type='s' direction='in'/>
    <arg name='fd' type='h' direction='in'/>
</method>

对应的C函数处理程序:

static gboolean
get_mime_type_data_method_cb(
    BusClippor *object, GDBusMethodInvocation *invocation, const char *id,
    const char *mime_type, int fd, gpointer user_data
)
{
    ClipporClipboard *cb = user_data;

    g_message("hello %d", fd);
    close(fd);

    bus_clippor_complete_get_mime_type_data(object, invocation);

    return G_DBUS_METHOD_INVOCATION_HANDLED;
}

当我用busctl工具传递shell中创建的文件描述符时,服务端收到的是随机大负数,但方法调用本身能正常接收。调用命令如下:

exec {fd}> output.txt
busctl --user call ... $fd

程序输出示例:

** Message: 20:04:40.651: hello -325137072

请问出现该行为的原因是什么?这是否是busctl的限制?


原因分析

这不是busctl的限制,而是传递文件描述符的方式错误:

  • shell中$fd是当前shell进程内的文件描述符编号,但直接将这个数字作为参数传给busctl时,busctl会把它当作普通整数处理,不会触发DBus的文件描述符传递机制。
  • GDBus服务端定义的h类型参数,期望接收的是通过DBus跨进程传递的文件描述符(由内核完成fd的映射)。当收到普通整数时,GDBus内部无法解析出有效的fd,最终得到的是无效的垃圾值,表现为你看到的随机大负数。

解决方法

busctl传递文件描述符需要使用特殊语法,将fd编号包装为fd:<number>格式,正确的调用命令应为:

exec {fd}> output.txt
busctl --user call ... fd:$fd

这样busctl才会识别并通过DBus传递对应的文件描述符,服务端就能收到有效的fd数值。


内容的提问来源于stack exchange,提问作者expoodo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:52:44