#include <pwd.h>
#include <grp.h>
#include <linux/limits.h>
-#include <pthread.h>
#include <assert.h>
+#include <mutex>
#define KDBUS_PATH_PREFIX "/sys/fs/kdbus/"
#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus"
char label[256];
} g_udesc;
-static bool init_once_done = false;
-static bool init_once_db[2] = {false, false};
-static bool init_once_conn[2] = {false, false};
+static std::once_flag init_once_done;
+static std::once_flag init_once_db[2];
+static std::once_flag init_once_conn[2];
extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* label)
{
strncpy(g_udesc.label, label, strlen(label) + 1);
}
-static bool dbuspolicy_init_once_locked(void)
+static void dbuspolicy_init_once_locked(void)
{
- if (init_once_done)
- return false;
-
char buf[1024];
int attr_fd;
int r;
attr_fd = open("/proc/self/attr/current", O_RDONLY);
if (attr_fd < 0)
- return true;
+ assert(false && "failed open: /proc/self/attr/current");
r = read(attr_fd, buf, sizeof(buf));
close(attr_fd);
if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */
- return true;
+ assert(false && "failed read: /proc/self/attr/current");
buf[r] = 0;
g_udesc.uid = getuid();
snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf);
__internal_init_once();
-
- init_once_done = true;
-
- return false;
}
static bool bus_type_from_path(const char *bus_path, BusType *bus_type, char **pp)
return ret;
}
-static bool init_common_locked(BusType bus_type)
+static void init_common_locked(BusType bus_type)
{
- dbuspolicy_init_once_locked();
-
- if (init_once_db[bus_type])
- return true;
-
int ret = __internal_init_auto_serialized(bus_type, (bus_type == SYSTEM_BUS) ? system_bus_conf_file_primary() : session_bus_conf_file_primary());
if (ret < 0)
ret = __internal_init(bus_type, (bus_type == SYSTEM_BUS) ? SYSTEM_BUS_CONF_FILE_SECONDARY : SESSION_BUS_CONF_FILE_SECONDARY);
- if (ret >= 0) {
+ if (ret >= 0)
__internal_init_sup_group(bus_type, g_udesc.uid, g_udesc.gid);
- init_once_db[bus_type] = true;
- }
- return ret >= 0;
+ else
+ assert(false && "failed __internal_init");
}
-static struct kconn *init_global_conn_locked(BusType bus_type, const char *resolved_path)
+static void init_global_conn_locked(BusType bus_type, const char *resolved_path)
{
- if (init_once_conn[bus_type])
- return &g_conn[bus_type];
-
- struct kconn *result = &g_conn[bus_type];
- if (kdbus_connect(&result->conn, resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0)
- return NULL;
+ struct kconn *kconn = &g_conn[bus_type];
+ kconn->bus_type = bus_type;
- result->bus_type = bus_type;
- init_once_conn[bus_type] = true;
-
- return result;
+ if (kdbus_connect(&kconn->conn, resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0) {
+ assert(false && "failed kdbus_connect");
+ }
}
-static struct kconn *get_global_conn(BusType bus_type, const char *resolved_path)
+static struct kconn *get_global_conn(BusType bus_type, const char *resolved_path) noexcept
{
- pthread_mutex_lock(&g_mutex);
- struct kconn *result = init_global_conn_locked(bus_type, resolved_path);
- pthread_mutex_unlock(&g_mutex);
- return result;
+ std::call_once(init_once_conn[bus_type], init_global_conn_locked, bus_type, resolved_path);
+
+ return &g_conn[bus_type];
}
static kconn *init_shared_fd(BusType bus_type, int fd)
return result;
}
-static bool can_open(BusType bus_type, uid_t bus_owner)
+static bool can_open(BusType bus_type, uid_t bus_owner) noexcept
{
- pthread_mutex_lock(&g_mutex);
- bool ret = init_common_locked(bus_type);
- pthread_mutex_unlock(&g_mutex);
+ std::call_once(init_once_done, dbuspolicy_init_once_locked);
+ std::call_once(init_once_db[bus_type], init_common_locked, bus_type);
- if (ret)
- return __internal_can_open(bus_type, bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label) > 0;
-
- return false;
+ return __internal_can_open(bus_type, bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label) > 0;
}
DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd)