better handle errors and noreply flag

This commit is contained in:
hippoz 2023-01-03 17:20:02 +02:00
parent 161741d59c
commit f7da39acea
Signed by: hippoz
GPG key ID: 56C4E02A85F2FBED
3 changed files with 40 additions and 15 deletions

4
main.c
View file

@ -3,6 +3,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include "match.h"
#include "server.h"
@ -23,6 +24,9 @@ int main(int argc, char *argv[])
const char *socket_path = arg_shift(&argc, &argv);
socket_path = socket_path == NULL ? "/tmp/jitterbug-unix0" : socket_path;
/* we handle send() errors directly in the code */
signal(SIGPIPE, SIG_IGN);
struct jb_server *srv = jb_server_create(socket_path);
if (srv == NULL) {
fprintf(stderr, "server_create failed\n");

View file

@ -249,27 +249,48 @@ int jb_server_broadcast_message(struct jb_server *s, wire_message_t *msg, wire_c
return 0;
}
int jb_server_unicast_message(struct jb_server *s, wire_message_t *msg, wire_context_t *ctx, char *target_name, char *sender_unique_name)
{
struct jb_client *target = jb_server_name_find_client(s, target_name);
if (!target) {
return -1;
}
uint8_t reply_data[4096];
memset(reply_data, 0, 4096);
wire_context_t reply_ctx = {
.byte_cursor = 0,
.data = reply_data,
.data_len = 4096,
};
TRYST(wire_compose_unicast_reply(&reply_ctx, ctx, msg, sender_unique_name));
TRYST(send(target->fd, reply_data, reply_ctx.byte_cursor, 0));
return 0;
}
#define _reply_begin(M_sig) \
do { \
if (!(msg.flags & DBUS_FLAG_NO_REPLY_EXPECTED)) { \
TRYST(wire_compose_reply(&reply_ctx, &msg, (M_sig), &body_length)); \
body_start = reply_ctx.byte_cursor; \
} while(0); \
#define _reply_end() \
do { \
*body_length = reply_ctx.byte_cursor - body_start; \
if (send(s->fds[i].fd, reply_data, reply_ctx.byte_cursor, 0) != reply_ctx.byte_cursor) { \
return -1; \
} \
printf("send: sent %d bytes!\n", reply_ctx.byte_cursor); \
} while(0); \
} /* if (!(msg.flags & DBUS_FLAG_NO_REPLY_EXPECTED)) */
#define _reply_error(message) \
do { \
if (!(msg.flags & DBUS_FLAG_NO_REPLY_EXPECTED)) { \
TRYST(wire_compose_error(&reply_ctx, &msg, (message))); \
if (send(s->fds[i].fd, reply_data, reply_ctx.byte_cursor, 0) != reply_ctx.byte_cursor) { \
return -1; \
} \
} \
} while(0) \
int jb_server_client_process_message(struct jb_server *s, int i, uint8_t *data, size_t data_len)
@ -536,16 +557,16 @@ int jb_server_client_process_message(struct jb_server *s, int i, uint8_t *data,
}
if (destination_field->present) {
/* unicast */
struct jb_client *target = jb_server_name_find_client(s, destination_field->t.str);
if (!target) {
_reply_error("org.freedesktop.DBus.Error.NameHasNoOwner");
if (jb_server_unicast_message(s, &msg, &ctx, destination_field->t.str, s->names[client->unique_name_index].name) < 0) {
_reply_error("xyz.hippoz.jitterbug.UnicastFailed");
return 0;
}
TRYST(wire_compose_unicast_reply(&reply_ctx, &ctx, &msg, s->names[client->unique_name_index].name));
TRYST(send(target->fd, reply_data, reply_ctx.byte_cursor, 0));
} else {
/* broadcast */
TRYST(jb_server_broadcast_message(s, &msg, &ctx, s->names[client->unique_name_index].name));
if (jb_server_broadcast_message(s, &msg, &ctx, s->names[client->unique_name_index].name) < 0) {
_reply_error("xyz.hippoz.jitterbug.BroadcastFailed");
return 0;
}
}
}

4
wire.c
View file

@ -172,7 +172,7 @@ int wire_compose_reply(wire_context_t *c, wire_message_t *msg, const char *signa
TRYPTR(wire_set_u8(c, msg->endianness)); /* endianness */
TRYPTR(wire_set_u8(c, DBUS_MESSAGE_METHOD_RETURN)); /* type */
TRYPTR(wire_set_u8(c, 0)); /* flags */
TRYPTR(wire_set_u8(c, 0 | DBUS_FLAG_NO_REPLY_EXPECTED)); /* flags */
TRYPTR(wire_set_u8(c, DBUS_PROTOCOL_VERSION)); /* protocol_version */
uint32_t *body_length = TRYPTR(wire_set_u32(c, 0)); /* body length */
TRYPTR(wire_set_u32(c, msg->serial+1)); /* serial */
@ -273,7 +273,7 @@ int wire_compose_unicast_reply(wire_context_t *c, wire_context_t *msg_c, wire_me
{
TRYPTR(wire_set_u8(c, msg->endianness)); /* endianness */
TRYPTR(wire_set_u8(c, msg->type)); /* type */
TRYPTR(wire_set_u8(c, 0)); /* flags */
TRYPTR(wire_set_u8(c, msg->flags)); /* flags */
TRYPTR(wire_set_u8(c, DBUS_PROTOCOL_VERSION)); /* protocol_version */
TRYPTR(wire_set_u32(c, msg->body_length)); /* body length */
TRYPTR(wire_set_u32(c, msg->serial)); /* serial */