Created
June 12, 2021 06:32
-
-
Save kapil1024/67cd6314d515b978aa9e1f92802a40af to your computer and use it in GitHub Desktop.
sdbus library: dbus client-server using socket pair
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <errno.h> | |
#include <sys/socket.h> | |
#include <systemd/sd-bus.h> | |
int fds[2]; | |
#define INT_TO_PTR(integer) ((void*) (long) ((int)integer)) | |
#define PTR_TO_INT(ptr) ((int) (long) (ptr)) | |
static int method_multiply(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { | |
int64_t x, y; | |
int r; | |
/* Read the parameters */ | |
r = sd_bus_message_read(m, "xx", &x, &y); | |
if (r < 0) { | |
fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r)); | |
return r; | |
} | |
/* Reply with the response */ | |
return sd_bus_reply_method_return(m, "x", x * y); | |
} | |
static int method_divide(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { | |
int64_t x, y; | |
int r; | |
/* Read the parameters */ | |
r = sd_bus_message_read(m, "xx", &x, &y); | |
if (r < 0) { | |
fprintf(stderr, "Failed to parse parameters: %s\n", strerror(-r)); | |
return r; | |
} | |
/* Return an error on division by zero */ | |
if (y == 0) { | |
sd_bus_error_set_const(ret_error, "net.poettering.DivisionByZero", "Sorry, can't allow division by zero."); | |
return -EINVAL; | |
} | |
return sd_bus_reply_method_return(m, "x", x / y); | |
} | |
/* The vtable of our little object, implements the net.poettering.Calculator interface */ | |
static const sd_bus_vtable calculator_vtable[] = { | |
SD_BUS_VTABLE_START(0), | |
SD_BUS_METHOD("Multiply", "xx", "x", method_multiply, SD_BUS_VTABLE_UNPRIVILEGED), | |
SD_BUS_METHOD("Divide", "xx", "x", method_divide, SD_BUS_VTABLE_UNPRIVILEGED), | |
SD_BUS_VTABLE_END | |
}; | |
void *server(void *p) { | |
sd_bus_slot *slot = NULL; | |
sd_bus *bus = NULL; | |
int r; | |
sd_id128_t id; | |
r = sd_id128_randomize(&id); | |
if (r < 0) { | |
fprintf(stderr, "Failed to get new bus id: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_new(&bus); | |
if (r < 0) { | |
fprintf(stderr, "Failed to create new bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_set_fd(bus, fds[0], fds[0]); | |
if (r < 0) { | |
fprintf(stderr, "Failed to set bus fd: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_set_server(bus, 1, id); | |
if (r < 0) { | |
fprintf(stderr, "Failed to set bus server id: %s\n", strerror(-r)); | |
goto finish; | |
} | |
/* Install the object */ | |
r = sd_bus_add_object_vtable(bus, | |
&slot, | |
"/net/poettering/Calculator", /* object path */ | |
"net.poettering.Calculator", /* interface name */ | |
calculator_vtable, | |
NULL); | |
if (r < 0) { | |
fprintf(stderr, "Failed to issue method call: %s\n", strerror(-r)); | |
goto finish; | |
} | |
/* Take a well-known service name so that clients can find us */ | |
r = sd_bus_request_name(bus, "net.poettering.Calculator", 0); | |
if (r < 0) { | |
fprintf(stderr, "Failed to acquire service name: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_start(bus); | |
if (r < 0) { | |
fprintf(stderr, "Failed to start bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
for (;;) { | |
/* Process requests */ | |
r = sd_bus_process(bus, NULL); | |
if (r < 0) { | |
fprintf(stderr, "Failed to process bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
if (r > 0) /* we processed a request, try to process another one, right-away */ | |
continue; | |
/* Wait for the next request to process */ | |
r = sd_bus_wait(bus, (uint64_t) -1); | |
if (r < 0) { | |
fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
} | |
finish: | |
sd_bus_slot_unref(slot); | |
sd_bus_flush(bus); | |
sd_bus_unref(bus); | |
return INT_TO_PTR(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS); | |
} | |
int client () { | |
sd_bus_error error = SD_BUS_ERROR_NULL; | |
sd_bus_message *m = NULL; | |
sd_bus *bus = NULL; | |
int64_t x, y, z; | |
int r; | |
r = sd_bus_new(&bus); | |
if (r < 0) { | |
fprintf(stderr, "Failed to create new bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_set_fd(bus, fds[1], fds[1]); | |
if (r < 0) { | |
fprintf(stderr, "Failed to set bus fds: %s\n", strerror(-r)); | |
goto finish; | |
} | |
r = sd_bus_start(bus); | |
if (r < 0) { | |
fprintf(stderr, "Failed to start the bus: %s\n", strerror(-r)); | |
goto finish; | |
} | |
/* Issue the method call and store the respons message in m */ | |
x = 99; | |
y = 17; | |
r = sd_bus_call_method(bus, | |
"net.poettering.Calculator", /* service to contact */ | |
"/net/poettering/Calculator", /* object path */ | |
"net.poettering.Calculator", /* interface name */ | |
"Divide", /* method name */ | |
&error, /* object to return error in */ | |
&m, /* return message on success */ | |
"xx", /* input signature */ | |
x, /* first argument */ | |
y); /* second argument */ | |
if (r < 0) { | |
fprintf(stderr, "Failed to issue method call: %s\n", error.message); | |
goto finish; | |
} | |
/* Parse the response message */ | |
r = sd_bus_message_read(m, "x", &z); | |
if (r < 0) { | |
fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r)); | |
goto finish; | |
} | |
printf("%ld/%ld=%ld\n", x, y, z); | |
finish: | |
sd_bus_error_free(&error); | |
sd_bus_message_unref(m); | |
sd_bus_unref(bus); | |
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; | |
} | |
int main(int argc, char *argv[]) { | |
pthread_t s; | |
void *p; | |
int r, q; | |
r = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); | |
if (r < 0) { | |
fprintf(stderr, "Failed to create socket pair: %s\n", strerror(-r)); | |
return -r; | |
} | |
r = pthread_create(&s, NULL, server, NULL); | |
if (r != 0) | |
return -r; | |
r = client(); | |
q = pthread_join(s, &p); | |
if (q != 0) | |
return -q; | |
if (r < 0) | |
return r; | |
if (PTR_TO_INT(p) < 0) | |
return PTR_TO_INT(p); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment