test-bus-chat.c revision c49b30a23583ff39daaa26696bcab478d2fee0bb
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/***
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2013 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Lesser General Public License for more details.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering***/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <assert.h>
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering#include <stdlib.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <pthread.h>
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering#include <unistd.h>
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include <fcntl.h>
0284adc6a60ce0af1107cb0b50041a65d731f39eLennart Poettering
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include "log.h"
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include "util.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "macro.h"
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek#include "sd-bus.h"
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek#include "bus-message.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "bus-error.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "bus-match.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "bus-internal.h"
3c1668da6202f1ead3d4d3981b89e9da1a0e98e3Lennart Poettering#include "bus-util.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
de190aef08bb267b645205a747762df573b36834Lennart Poetteringstatic int match_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poettering log_info("Match triggered! interface=%s member=%s", strna(sd_bus_message_get_interface(m)), strna(sd_bus_message_get_member(m)));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poetteringstatic int object_callback(sd_bus *bus, sd_bus_message *m, void *userdata) {
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poettering int r;
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering
16e9f408fa9a9626059bdd6c89dc175e06b9e976Lennart Poettering assert(bus);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (sd_bus_message_is_method_error(m, NULL))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (sd_bus_message_is_method_call(m, "org.object.test", "Foobar")) {
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering log_info("Invoked Foobar() on %s", sd_bus_message_get_path(m));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_bus_reply_method_return(bus, m, NULL);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering log_error("Failed to send reply: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
c2373f848dddcc1827cf715c5ef778dc8d475761Lennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering
b0af6f41ea67c97b8beb16fd1d63042379bbf103Lennart Poettering return 0;
feb12d3ed2c7f9132c64773c7c41b9e3a608a814Lennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int server_init(sd_bus **_bus) {
f534928ad7aaeec0bec2d653b4a50e79b0fc8418Michal Schmidt sd_bus *bus = NULL;
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier sd_id128_t id;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
f534928ad7aaeec0bec2d653b4a50e79b0fc8418Michal Schmidt const char *unique;
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(_bus);
f534928ad7aaeec0bec2d653b4a50e79b0fc8418Michal Schmidt
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier r = sd_bus_open_user(&bus);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
f534928ad7aaeec0bec2d653b4a50e79b0fc8418Michal Schmidt log_error("Failed to connect to user bus: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
f534928ad7aaeec0bec2d653b4a50e79b0fc8418Michal Schmidt }
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_bus_get_server_id(bus, &id);
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier if (r < 0) {
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_error("Failed to get server ID: %s", strerror(-r));
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier goto fail;
de190aef08bb267b645205a747762df573b36834Lennart Poettering }
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier r = sd_bus_get_unique_name(bus, &unique);
de190aef08bb267b645205a747762df573b36834Lennart Poettering if (r < 0) {
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_error("Failed to get unique name: %s", strerror(-r));
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier goto fail;
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_info("Unique ID: %s", unique);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier if (r < 0) {
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_error("Failed to acquire name: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier }
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = sd_bus_add_fallback(bus, "/foo/bar", object_callback, NULL);
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier if (r < 0) {
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier log_error("Failed to add object: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
787784c4c1b24a13207d18b415d60483cfbdeaa3Ronny Chevalier }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering r = sd_bus_add_match(bus, "type='signal',interface='foo.bar',member='Notify'", match_callback, NULL);
7560fffcd2531786b9c1ca657667a43e90331326Lennart Poettering if (r < 0) {
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering log_error("Failed to add match: %s", strerror(-r));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek r = sd_bus_add_match(bus, "type='signal',interface='org.freedesktop.DBus',member='NameOwnerChanged'", match_callback, NULL);
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (r < 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek log_error("Failed to add match: %s", strerror(-r));
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek goto fail;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering }
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering bus_match_dump(&bus->match_callbacks, 0);
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek *_bus = bus;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek return 0;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmekfail:
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (bus)
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek sd_bus_unref(bus);
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek return r;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek}
0ac38b707212e9aa40e25d65ffbae648cc9116f5Lennart Poettering
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmekstatic int server(sd_bus *bus) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek int r;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek bool client1_gone = false, client2_gone = false;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek while (!client1_gone || !client2_gone) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek pid_t pid = 0;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek const char *label = NULL;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek r = sd_bus_process(bus, &m);
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (r < 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek log_error("Failed to process requests: %s", strerror(-r));
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek goto fail;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek }
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (r == 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek r = sd_bus_wait(bus, (uint64_t) -1);
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (r < 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek log_error("Failed to wait: %s", strerror(-r));
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek goto fail;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek }
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek continue;
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek }
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (!m)
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek continue;
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek sd_bus_message_get_pid(m, &pid);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering sd_bus_message_get_selinux_context(m, &label);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering log_info("Got message! member=%s pid=%lu label=%s",
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering strna(sd_bus_message_get_member(m)),
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering (unsigned long) pid,
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering strna(label));
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek /* bus_message_dump(m); */
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek /* sd_bus_message_rewind(m, true); */
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
6ad1d1c30621280bfad3e63fcc1c7ceb7d8ffa98Lennart Poettering const char *hello;
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther _cleanup_free_ char *lowercase = NULL;
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther r = sd_bus_message_read(m, "s", &hello);
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther if (r < 0) {
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek log_error("Failed to get parameter: %s", strerror(-r));
6eb7a9a0010d035e5bdbbf70227088ce02b2120eZbigniew Jędrzejewski-Szmek goto fail;
95ea1b90cc61f464f3b9bc147119dee4ba9620b8Lennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering lowercase = strdup(hello);
if (!lowercase) {
r = log_oom();
goto fail;
}
ascii_strlower(lowercase);
r = sd_bus_reply_method_return(bus, m, "s", lowercase);
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
r = sd_bus_reply_method_return(bus, m, NULL);
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
client1_gone = true;
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
r = sd_bus_reply_method_return(bus, m, NULL);
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
client2_gone = true;
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
sleep(1);
r = sd_bus_reply_method_return(bus, m, NULL);
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
} else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) {
int fd;
static const char x = 'X';
r = sd_bus_message_read(m, "h", &fd);
if (r < 0) {
log_error("Failed to get parameter: %s", strerror(-r));
goto fail;
}
log_info("Received fd=%d", fd);
if (write(fd, &x, 1) < 0) {
log_error("Failed to write to fd: %m");
close_nointr_nofail(fd);
goto fail;
}
r = sd_bus_reply_method_return(bus, m, NULL);
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
} else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
r = sd_bus_reply_method_error(
bus, m,
&SD_BUS_ERROR_MAKE(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
if (r < 0) {
log_error("Failed to send reply: %s", strerror(-r));
goto fail;
}
}
}
r = 0;
fail:
if (bus) {
sd_bus_flush(bus);
sd_bus_unref(bus);
}
return r;
}
static void* client1(void*p) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
sd_bus *bus = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
const char *hello;
int r;
int pp[2] = { -1, -1 };
char x;
r = sd_bus_open_user(&bus);
if (r < 0) {
log_error("Failed to connect to user bus: %s", strerror(-r));
goto finish;
}
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"LowerCase",
&error,
&reply,
"s",
"HELLO");
if (r < 0) {
log_error("Failed to issue method call: %s", strerror(-r));
goto finish;
}
r = sd_bus_message_read(reply, "s", &hello);
if (r < 0) {
log_error("Failed to get string: %s", strerror(-r));
goto finish;
}
assert(streq(hello, "hello"));
if (pipe2(pp, O_CLOEXEC|O_NONBLOCK) < 0) {
log_error("Failed to allocate pipe: %m");
r = -errno;
goto finish;
}
log_info("Sending fd=%d", pp[1]);
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"FileDescriptor",
&error,
NULL,
"h",
pp[1]);
if (r < 0) {
log_error("Failed to issue method call: %s", strerror(-r));
goto finish;
}
errno = 0;
if (read(pp[0], &x, 1) <= 0) {
log_error("Failed to read from pipe: %s", errno ? strerror(errno) : "early read");
goto finish;
}
r = 0;
finish:
if (bus) {
_cleanup_bus_message_unref_ sd_bus_message *q;
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"ExitClient1",
&q);
if (r < 0)
log_error("Failed to allocate method call: %s", strerror(-r));
else
sd_bus_send(bus, q, NULL);
sd_bus_flush(bus);
sd_bus_unref(bus);
}
sd_bus_error_free(&error);
close_pipe(pp);
return INT_TO_PTR(r);
}
static int quit_callback(sd_bus *b, sd_bus_message *m, void *userdata) {
bool *x = userdata;
log_error("Quit callback: %s", strerror(sd_bus_message_get_errno(m)));
*x = 1;
return 1;
}
static void* client2(void*p) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
sd_bus *bus = NULL;
sd_bus_error error = SD_BUS_ERROR_NULL;
bool quit = false;
const char *mid;
int r;
r = sd_bus_open_user(&bus);
if (r < 0) {
log_error("Failed to connect to user bus: %s", strerror(-r));
goto finish;
}
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/foo/bar/waldo/piep",
"org.object.test",
"Foobar",
&m);
if (r < 0) {
log_error("Failed to allocate method call: %s", strerror(-r));
goto finish;
}
r = sd_bus_send(bus, m, NULL);
if (r < 0) {
log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
goto finish;
}
sd_bus_message_unref(m);
m = NULL;
r = sd_bus_message_new_signal(
bus,
"/foobar",
"foo.bar",
"Notify",
&m);
if (r < 0) {
log_error("Failed to allocate signal: %s", strerror(-r));
goto finish;
}
r = sd_bus_send(bus, m, NULL);
if (r < 0) {
log_error("Failed to issue signal: %s", bus_error_message(&error, -r));
goto finish;
}
sd_bus_message_unref(m);
m = NULL;
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.DBus.Peer",
"GetMachineId",
&m);
if (r < 0) {
log_error("Failed to allocate method call: %s", strerror(-r));
goto finish;
}
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
goto finish;
}
r = sd_bus_message_read(reply, "s", &mid);
if (r < 0) {
log_error("Failed to parse machine ID: %s", strerror(-r));
goto finish;
}
log_info("Machine ID is %s.", mid);
sd_bus_message_unref(m);
m = NULL;
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"Slow",
&m);
if (r < 0) {
log_error("Failed to allocate method call: %s", strerror(-r));
goto finish;
}
sd_bus_message_unref(reply);
reply = NULL;
r = sd_bus_call(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
if (r < 0)
log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
else
log_info("Slow call succeed.");
sd_bus_message_unref(m);
m = NULL;
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"Slow",
&m);
if (r < 0) {
log_error("Failed to allocate method call: %s", strerror(-r));
goto finish;
}
r = sd_bus_call_async(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
if (r < 0) {
log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
goto finish;
}
while (!quit) {
r = sd_bus_process(bus, NULL);
if (r < 0) {
log_error("Failed to process requests: %s", strerror(-r));
goto finish;
}
if (r == 0) {
r = sd_bus_wait(bus, (uint64_t) -1);
if (r < 0) {
log_error("Failed to wait: %s", strerror(-r));
goto finish;
}
}
}
r = 0;
finish:
if (bus) {
_cleanup_bus_message_unref_ sd_bus_message *q;
r = sd_bus_message_new_method_call(
bus,
"org.freedesktop.systemd.test",
"/",
"org.freedesktop.systemd.test",
"ExitClient2",
&q);
if (r < 0) {
log_error("Failed to allocate method call: %s", strerror(-r));
goto finish;
}
sd_bus_send(bus, q, NULL);
sd_bus_flush(bus);
sd_bus_unref(bus);
}
sd_bus_error_free(&error);
return INT_TO_PTR(r);
}
int main(int argc, char *argv[]) {
pthread_t c1, c2;
sd_bus *bus;
void *p;
int q, r;
r = server_init(&bus);
if (r < 0) {
log_info("Failed to connect to bus, skipping tests.");
return EXIT_TEST_SKIP;
}
log_info("Initialized...");
r = pthread_create(&c1, NULL, client1, bus);
if (r != 0)
return EXIT_FAILURE;
r = pthread_create(&c2, NULL, client2, bus);
if (r != 0)
return EXIT_FAILURE;
r = server(bus);
q = pthread_join(c1, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
q = pthread_join(c2, &p);
if (q != 0)
return EXIT_FAILURE;
if (PTR_TO_INT(p) < 0)
return EXIT_FAILURE;
if (r < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}