struct kdbus_conn * kdbus_hello_registrar(const char *path, const char *name, const struct kdbus_policy_access *access, size_t num_access, uint64_t flags) { struct kdbus_item *item, *items; size_t i, size; size = KDBUS_ITEM_SIZE(strlen(name) + 1) + num_access * KDBUS_ITEM_SIZE(sizeof(*access)); items = alloca(size); item = items; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; item->type = KDBUS_ITEM_NAME; strcpy(item->str, name); item = KDBUS_ITEM_NEXT(item); for (i = 0; i < num_access; i++) { item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_policy_access); item->type = KDBUS_ITEM_POLICY_ACCESS; item->policy_access.type = access[i].type; item->policy_access.access = access[i].access; item->policy_access.id = access[i].id; item = KDBUS_ITEM_NEXT(item); } return kdbus_hello(path, flags, items, size); }
int kdbus_conn_update_policy(struct kdbus_conn *conn, const char *name, const struct kdbus_policy_access *access, size_t num_access) { struct kdbus_cmd_update *update; struct kdbus_item *item; size_t i, size; int ret; size = sizeof(struct kdbus_cmd_update); size += KDBUS_ITEM_SIZE(strlen(name) + 1); size += num_access * KDBUS_ITEM_SIZE(sizeof(struct kdbus_policy_access)); update = malloc(size); if (!update) { ret = -errno; kdbus_printf("error malloc: %d (%m)\n", ret); return ret; } memset(update, 0, size); update->size = size; item = update->items; item->type = KDBUS_ITEM_NAME; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; strcpy(item->str, name); item = KDBUS_ITEM_NEXT(item); for (i = 0; i < num_access; i++) { item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_policy_access); item->type = KDBUS_ITEM_POLICY_ACCESS; item->policy_access.type = access[i].type; item->policy_access.access = access[i].access; item->policy_access.id = access[i].id; item = KDBUS_ITEM_NEXT(item); } ret = ioctl(conn->fd, KDBUS_CMD_CONN_UPDATE, update); if (ret < 0) { ret = -errno; kdbus_printf("error conn update: %d (%m)\n", ret); } free(update); return ret; }
static int send_fd(struct kdbus_conn *conn, uint64_t dst_id, int fd) { struct kdbus_item *item; struct kdbus_msg *msg; uint64_t size; int ret; size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(int[2])); msg = alloca(size); memset(msg, 0, size); msg->size = size; msg->src_id = conn->id; msg->dst_id = dst_id; msg->payload_type = KDBUS_PAYLOAD_DBUS; item = msg->items; item->type = KDBUS_ITEM_FDS; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(int); item->fds[0] = fd; item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg); if (ret) { kdbus_printf("error sending message: %d err %d (%m)\n", ret, errno); return -errno; } return 0; }
static struct conn *make_activator(const char *path, const char *name) { int fd, ret; struct kdbus_cmd_hello *hello; struct kdbus_item *item; struct conn *conn; size_t size, slen; slen = strlen(name) + 1; size = sizeof(*hello) + KDBUS_ITEM_SIZE(slen); hello = alloca(size); memset(hello, 0, size); printf("-- opening ACTIVATOR bus connection %s\n", path); fd = open(path, O_RDWR|O_CLOEXEC); if (fd < 0) { fprintf(stderr, "--- error %d (%m)\n", fd); return NULL; } hello->size = size; hello->pool_size = POOL_SIZE; hello->conn_flags = KDBUS_HELLO_ACTIVATOR; item = hello->items; item->size = KDBUS_ITEM_HEADER_SIZE + slen; item->type = KDBUS_ITEM_NAME; strcpy(item->str, name); ret = ioctl(fd, KDBUS_CMD_HELLO, hello); if (ret < 0) { fprintf(stderr, "--- error when saying hello: %d (%m)\n", ret); return NULL; } printf("-- Our peer ID for activator %s: %llu\n", name, (unsigned long long) hello->id); conn = malloc(sizeof(*conn)); if (!conn) { fprintf(stderr, "unable to malloc()!?\n"); return NULL; } conn->fd = fd; conn->id = hello->id; return conn; }
int kdbus_conn_update_attach_flags(struct kdbus_conn *conn, uint64_t flags) { int ret; size_t size; struct kdbus_cmd_update *update; struct kdbus_item *item; size = sizeof(struct kdbus_cmd_update); size += KDBUS_ITEM_SIZE(sizeof(uint64_t)); update = malloc(size); if (!update) { ret = -errno; kdbus_printf("error malloc: %d (%m)\n", ret); return ret; } memset(update, 0, size); update->size = size; item = update->items; item->type = KDBUS_ITEM_ATTACH_FLAGS; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(uint64_t); item->data64[0] = flags; item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_CONN_UPDATE, update); if (ret < 0) { ret = -errno; kdbus_printf("error conn update: %d (%m)\n", ret); } free(update); return ret; }
static int kdbus_notify_reply(struct kdbus_ep *ep, u64 src_id, u64 cookie, u64 msg_type) { struct kdbus_conn *dst_conn; struct kdbus_kmsg *kmsg; struct kdbus_item *item; int ret; dst_conn = kdbus_bus_find_conn_by_id(ep->bus, src_id); if (!dst_conn) return -ENXIO; ret = kdbus_kmsg_new(KDBUS_ITEM_SIZE(0), &kmsg); if (ret < 0) return ret; /* * a kernel-generated notification can only contain one * struct kdbus_item, so make a shortcut here for * faster lookup in the match db. */ kmsg->notification_type = msg_type; kmsg->msg.dst_id = src_id; kmsg->msg.src_id = KDBUS_SRC_ID_KERNEL; kmsg->msg.payload_type = KDBUS_PAYLOAD_KERNEL; kmsg->msg.cookie_reply = cookie; item = kmsg->msg.items; item->type = msg_type; ret = kdbus_conn_kmsg_send(ep, NULL, kmsg); kdbus_kmsg_free(kmsg); return ret; }
static int send_echo_request(struct conn *conn, uint64_t dst_id) { struct kdbus_msg *msg; struct kdbus_item *item; uint64_t size; int memfd = -1; int ret; struct timeval now; gettimeofday(&now, NULL); size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &memfd); if (ret < 0) { fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n"); return EXIT_FAILURE; } if (write(memfd, &now, sizeof(now)) != sizeof(now)) { fprintf(stderr, "writing to memfd failed: %m\n"); return EXIT_FAILURE; } ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true); if (ret < 0) { fprintf(stderr, "memfd sealing failed: %m\n"); return EXIT_FAILURE; } size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); msg = malloc(size); if (!msg) { fprintf(stderr, "unable to malloc()!?\n"); return EXIT_FAILURE; } memset(msg, 0, size); msg->size = size; msg->src_id = conn->id; msg->dst_id = dst_id; msg->payload_type = KDBUS_PAYLOAD_DBUS; item = msg->items; item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uint64_t) stress_payload; item->vec.size = sizeof(stress_payload); item = KDBUS_ITEM_NEXT(item); item->type = KDBUS_ITEM_PAYLOAD_MEMFD; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd); item->memfd.size = 16; item->memfd.fd = memfd; item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg); if (ret) { fprintf(stderr, "error sending message: %d err %d (%m)\n", ret, errno); return EXIT_FAILURE; } if (memfd >= 0) close(memfd); free(msg); return 0; }
int msg_send(const struct conn *conn, const char *name, uint64_t cookie, uint64_t dst_id) { struct kdbus_msg *msg; const char ref1[1024 * 1024 + 3] = "0123456789_0"; const char ref2[] = "0123456789_1"; struct kdbus_item *item; uint64_t size; int memfd = -1; int ret; size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); if (dst_id == KDBUS_DST_ID_BROADCAST) size += KDBUS_ITEM_HEADER_SIZE + 64; else { struct { struct kdbus_cmd_memfd_make cmd; uint64_t size; uint64_t type; char name[16]; } m = {}; m.cmd.size = sizeof(m); m.cmd.file_size = 1024 * 1024; m.cmd.items[0].type = KDBUS_ITEM_MEMFD_NAME; m.cmd.items[0].size = KDBUS_ITEM_HEADER_SIZE + sizeof(m.name); strcpy(m.name, "my-name-is-nice"); ret = ioctl(conn->fd, KDBUS_CMD_MEMFD_NEW, &m); if (ret < 0) { fprintf(stderr, "KDBUS_CMD_MEMFD_NEW failed: %m\n"); return EXIT_FAILURE; } memfd = m.cmd.fd; if (write(memfd, "kdbus memfd 1234567", 19) != 19) { fprintf(stderr, "writing to memfd failed: %m\n"); return EXIT_FAILURE; } ret = ioctl(memfd, KDBUS_CMD_MEMFD_SEAL_SET, true); if (ret < 0) { fprintf(stderr, "memfd sealing failed: %m\n"); return EXIT_FAILURE; } size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); } if (name) size += KDBUS_ITEM_SIZE(strlen(name) + 1); msg = malloc(size); if (!msg) { fprintf(stderr, "unable to malloc()!?\n"); return EXIT_FAILURE; } memset(msg, 0, size); msg->size = size; msg->src_id = conn->id; msg->dst_id = name ? 0 : dst_id; msg->cookie = cookie; msg->payload_type = KDBUS_PAYLOAD_DBUS; item = msg->items; if (name) { item->type = KDBUS_ITEM_DST_NAME; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; strcpy(item->str, name); item = KDBUS_ITEM_NEXT(item); } item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref1; item->vec.size = sizeof(ref1); item = KDBUS_ITEM_NEXT(item); /* data padding for ref1 */ item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)NULL; item->vec.size = KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1); item = KDBUS_ITEM_NEXT(item); item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref2; item->vec.size = sizeof(ref2); item = KDBUS_ITEM_NEXT(item); if (dst_id == KDBUS_DST_ID_BROADCAST) { item->type = KDBUS_ITEM_BLOOM; item->size = KDBUS_ITEM_HEADER_SIZE + 64; } else { item->type = KDBUS_ITEM_PAYLOAD_MEMFD; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd); item->memfd.size = 16; item->memfd.fd = memfd; } item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg); if (ret < 0) { fprintf(stderr, "error sending message: %d err %d (%m)\n", ret, errno); return EXIT_FAILURE; } if (memfd >= 0) close(memfd); free(msg); return 0; }
int kdbus_msg_send(const struct kdbus_conn *conn, const char *name, uint64_t cookie, uint64_t flags, uint64_t timeout, int64_t priority, uint64_t dst_id) { struct kdbus_msg *msg; const char ref1[1024 * 128 + 3] = "0123456789_0"; const char ref2[] = "0123456789_1"; struct kdbus_item *item; uint64_t size; int memfd = -1; int ret; size = sizeof(struct kdbus_msg); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec)); if (dst_id == KDBUS_DST_ID_BROADCAST) size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; else { memfd = sys_memfd_create("my-name-is-nice", 1024 * 1024); if (memfd < 0) { kdbus_printf("failed to create memfd: %m\n"); return memfd; } if (write(memfd, "kdbus memfd 1234567", 19) != 19) { ret = -errno; kdbus_printf("writing to memfd failed: %m\n"); return ret; } ret = sys_memfd_seal_set(memfd); if (ret < 0) { ret = -errno; kdbus_printf("memfd sealing failed: %m\n"); return ret; } size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd)); } if (name) size += KDBUS_ITEM_SIZE(strlen(name) + 1); msg = malloc(size); if (!msg) { ret = -errno; kdbus_printf("unable to malloc()!?\n"); return ret; } memset(msg, 0, size); msg->flags = flags; msg->timeout_ns = timeout; msg->priority = priority; msg->size = size; msg->src_id = conn->id; msg->dst_id = name ? 0 : dst_id; msg->cookie = cookie; msg->payload_type = KDBUS_PAYLOAD_DBUS; item = msg->items; if (name) { item->type = KDBUS_ITEM_DST_NAME; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; strcpy(item->str, name); item = KDBUS_ITEM_NEXT(item); } item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref1; item->vec.size = sizeof(ref1); item = KDBUS_ITEM_NEXT(item); /* data padding for ref1 */ item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)NULL; item->vec.size = KDBUS_ALIGN8(sizeof(ref1)) - sizeof(ref1); item = KDBUS_ITEM_NEXT(item); item->type = KDBUS_ITEM_PAYLOAD_VEC; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_vec); item->vec.address = (uintptr_t)&ref2; item->vec.size = sizeof(ref2); item = KDBUS_ITEM_NEXT(item); if (dst_id == KDBUS_DST_ID_BROADCAST) { item->type = KDBUS_ITEM_BLOOM_FILTER; item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64; item->bloom_filter.generation = 0; } else { item->type = KDBUS_ITEM_PAYLOAD_MEMFD; item->size = KDBUS_ITEM_HEADER_SIZE + sizeof(struct kdbus_memfd); item->memfd.size = 16; item->memfd.fd = memfd; } item = KDBUS_ITEM_NEXT(item); ret = ioctl(conn->fd, KDBUS_CMD_MSG_SEND, msg); if (ret < 0) { ret = -errno; kdbus_printf("error sending message: %d (%m)\n", ret); return ret; } if (memfd >= 0) close(memfd); if (flags & KDBUS_MSG_FLAGS_SYNC_REPLY) { struct kdbus_msg *reply; kdbus_printf("SYNC REPLY @offset %llu:\n", msg->offset_reply); reply = (struct kdbus_msg *)(conn->buf + msg->offset_reply); kdbus_msg_dump(conn, reply); ret = kdbus_free(conn, msg->offset_reply); if (ret < 0) return ret; } free(msg); return 0; }