为什么退出 sd-bus 容器时出现错误?

问题描述 投票:0回答:1

我使用的是 RHEL 8,systemd 版本是 239-74 我想在 C++ 上使用 dbus 获取数据 仅使用一个容器时这不是问题(但这种情况在退出容器时也会发生相同的错误) 但是当我应该再使用一个容器时,我会收到“设备或资源繁忙”

#include <iostream>
#include <unistd.h>
#include <systemd/sd-bus.h>

int main() {
        sd_bus_error error = SD_BUS_ERROR_NULL;
        sd_bus *bus = nullptr;
        int ret = sd_bus_open_system(&bus);
        const char *service_name = "org.freedesktop.systemd1";
        const char *object_path = "/org/freedesktop/systemd1";
        const char *interface = "org.freedesktop.systemd1.Manager";
        const char *method = "ListUnits";

        sd_bus_message *reply = nullptr;
        ret = sd_bus_call_method(bus,
                        service_name,
                        object_path,
                        interface,
                        method,
                        &error,
                        &reply,
                        "");
        if (ret < 0) {
                return 1;
        }
        const char *unit_name;
        const char *unit_description;
        const char *unit_load_state;
        const char *unit_active_state;
        const char *sub_state,*followed_state,*object1_path,*queued_job,*job_type,*job_object_path;
        unsigned int uint;

        ret = sd_bus_message_enter_container(reply, 'a', "(ssssssouso)");
        if(ret<0){
                std::cerr <<strerror(-ret);
        }
        ret = sd_bus_message_exit_container(reply);
        if(ret<0){
                std::cerr <<strerror(-ret);
        }
        sd_bus_message_unref(reply);
        sd_bus_unref(bus);

        return 0;
}

我认为是环境问题,但在 Ubuntu 上,出现了同样的错误。 我想读取字典数组,但我无法退出容器,所以我无法获取其他数据

c++ linux systemd dbus
1个回答
0
投票

来自文档:

请注意,sd_bus_message_exit_container() 只能在迭代容器的所有成员之后调用,即读取或跳过它们。

退出容器之前需要消耗数组的内容:

ret = sd_bus_message_enter_container(reply, 'a', "(ssssssouso)");
if(ret<0){
    std::cerr <<strerror(-ret);
}

struct {
    const char *primary_name, *human_name, *load_state, *active_state, *sub_state, *following;
    const char **unit_object_path;
    uint32_t queued_job_id;
    const char *job_type
    const char **job_object_path;
} unit;

for (;;) {
    ret = sd_bus_message_read(reply, "(ssssssouso)", &unit.primary_name, &unit.human_name, &unit.load_state, &unit.active_state, &unit.sub_state, &unit.following, &unit.unit_object_path, &unit.queued_job_id, &unit.job_type, &unit.job_object_path);
    if (ret == 0) {
        // done reading
        break;
    }
    if(ret<0){
        std::cerr <<strerror(-ret);
        break;
    }
}

ret = sd_bus_message_exit_container(reply);
if(ret<0){
    std::cerr <<strerror(-ret);
}
© www.soinside.com 2019 - 2024. All rights reserved.