LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - test-bus-server.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 86 101 85.1 %
Date: 2019-08-22 15:41:25 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <pthread.h>
       4             : #include <stdlib.h>
       5             : 
       6             : #include "sd-bus.h"
       7             : 
       8             : #include "bus-internal.h"
       9             : #include "bus-util.h"
      10             : #include "log.h"
      11             : #include "macro.h"
      12             : #include "memory-util.h"
      13             : 
      14             : struct context {
      15             :         int fds[2];
      16             : 
      17             :         bool client_negotiate_unix_fds;
      18             :         bool server_negotiate_unix_fds;
      19             : 
      20             :         bool client_anonymous_auth;
      21             :         bool server_anonymous_auth;
      22             : };
      23             : 
      24           7 : static void *server(void *p) {
      25           7 :         struct context *c = p;
      26           7 :         sd_bus *bus = NULL;
      27             :         sd_id128_t id;
      28           7 :         bool quit = false;
      29             :         int r;
      30             : 
      31           7 :         assert_se(sd_id128_randomize(&id) >= 0);
      32             : 
      33           7 :         assert_se(sd_bus_new(&bus) >= 0);
      34           7 :         assert_se(sd_bus_set_fd(bus, c->fds[0], c->fds[0]) >= 0);
      35           7 :         assert_se(sd_bus_set_server(bus, 1, id) >= 0);
      36           7 :         assert_se(sd_bus_set_anonymous(bus, c->server_anonymous_auth) >= 0);
      37           7 :         assert_se(sd_bus_negotiate_fds(bus, c->server_negotiate_unix_fds) >= 0);
      38           7 :         assert_se(sd_bus_start(bus) >= 0);
      39             : 
      40          37 :         while (!quit) {
      41          55 :                 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
      42             : 
      43          31 :                 r = sd_bus_process(bus, &m);
      44          31 :                 if (r < 0) {
      45           1 :                         log_error_errno(r, "Failed to process requests: %m");
      46           1 :                         goto fail;
      47             :                 }
      48             : 
      49          30 :                 if (r == 0) {
      50           8 :                         r = sd_bus_wait(bus, (uint64_t) -1);
      51           8 :                         if (r < 0) {
      52           0 :                                 log_error_errno(r, "Failed to wait: %m");
      53           0 :                                 goto fail;
      54             :                         }
      55             : 
      56           8 :                         continue;
      57             :                 }
      58             : 
      59          22 :                 if (!m)
      60          15 :                         continue;
      61             : 
      62           7 :                 log_info("Got message! member=%s", strna(sd_bus_message_get_member(m)));
      63             : 
      64           7 :                 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Exit")) {
      65             : 
      66           6 :                         assert_se((sd_bus_can_send(bus, 'h') >= 1) ==
      67             :                                   (c->server_negotiate_unix_fds && c->client_negotiate_unix_fds));
      68             : 
      69           6 :                         r = sd_bus_message_new_method_return(m, &reply);
      70           6 :                         if (r < 0) {
      71           0 :                                 log_error_errno(r, "Failed to allocate return: %m");
      72           0 :                                 goto fail;
      73             :                         }
      74             : 
      75           6 :                         quit = true;
      76             : 
      77           1 :                 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
      78           0 :                         r = sd_bus_message_new_method_error(
      79             :                                         m,
      80             :                                         &reply,
      81           0 :                                         &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method."));
      82           0 :                         if (r < 0) {
      83           0 :                                 log_error_errno(r, "Failed to allocate return: %m");
      84           0 :                                 goto fail;
      85             :                         }
      86             :                 }
      87             : 
      88           7 :                 if (reply) {
      89           6 :                         r = sd_bus_send(bus, reply, NULL);
      90           6 :                         if (r < 0) {
      91           0 :                                 log_error_errno(r, "Failed to send reply: %m");
      92           0 :                                 goto fail;
      93             :                         }
      94             :                 }
      95             :         }
      96             : 
      97           6 :         r = 0;
      98             : 
      99           7 : fail:
     100           7 :         if (bus) {
     101           7 :                 sd_bus_flush(bus);
     102           7 :                 sd_bus_unref(bus);
     103             :         }
     104             : 
     105           7 :         return INT_TO_PTR(r);
     106             : }
     107             : 
     108           7 : static int client(struct context *c) {
     109           7 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
     110           7 :         _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
     111           7 :         sd_bus_error error = SD_BUS_ERROR_NULL;
     112             :         int r;
     113             : 
     114           7 :         assert_se(sd_bus_new(&bus) >= 0);
     115           7 :         assert_se(sd_bus_set_fd(bus, c->fds[1], c->fds[1]) >= 0);
     116           7 :         assert_se(sd_bus_negotiate_fds(bus, c->client_negotiate_unix_fds) >= 0);
     117           7 :         assert_se(sd_bus_set_anonymous(bus, c->client_anonymous_auth) >= 0);
     118           7 :         assert_se(sd_bus_start(bus) >= 0);
     119             : 
     120           7 :         r = sd_bus_message_new_method_call(
     121             :                         bus,
     122             :                         &m,
     123             :                         "org.freedesktop.systemd.test",
     124             :                         "/",
     125             :                         "org.freedesktop.systemd.test",
     126             :                         "Exit");
     127           7 :         if (r < 0)
     128           0 :                 return log_error_errno(r, "Failed to allocate method call: %m");
     129             : 
     130           7 :         r = sd_bus_call(bus, m, 0, &error, &reply);
     131           7 :         if (r < 0)
     132           1 :                 return log_error_errno(r, "Failed to issue method call: %s", bus_error_message(&error, -r));
     133             : 
     134           6 :         return 0;
     135             : }
     136             : 
     137           7 : static int test_one(bool client_negotiate_unix_fds, bool server_negotiate_unix_fds,
     138             :                     bool client_anonymous_auth, bool server_anonymous_auth) {
     139             : 
     140             :         struct context c;
     141             :         pthread_t s;
     142             :         void *p;
     143             :         int r, q;
     144             : 
     145           7 :         zero(c);
     146             : 
     147           7 :         assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, c.fds) >= 0);
     148             : 
     149           7 :         c.client_negotiate_unix_fds = client_negotiate_unix_fds;
     150           7 :         c.server_negotiate_unix_fds = server_negotiate_unix_fds;
     151           7 :         c.client_anonymous_auth = client_anonymous_auth;
     152           7 :         c.server_anonymous_auth = server_anonymous_auth;
     153             : 
     154           7 :         r = pthread_create(&s, NULL, server, &c);
     155           7 :         if (r != 0)
     156           0 :                 return -r;
     157             : 
     158           7 :         r = client(&c);
     159             : 
     160           7 :         q = pthread_join(s, &p);
     161           7 :         if (q != 0)
     162           0 :                 return -q;
     163             : 
     164           7 :         if (r < 0)
     165           1 :                 return r;
     166             : 
     167           6 :         if (PTR_TO_INT(p) < 0)
     168           0 :                 return PTR_TO_INT(p);
     169             : 
     170           6 :         return 0;
     171             : }
     172             : 
     173           1 : int main(int argc, char *argv[]) {
     174             :         int r;
     175             : 
     176           1 :         r = test_one(true, true, false, false);
     177           1 :         assert_se(r >= 0);
     178             : 
     179           1 :         r = test_one(true, false, false, false);
     180           1 :         assert_se(r >= 0);
     181             : 
     182           1 :         r = test_one(false, true, false, false);
     183           1 :         assert_se(r >= 0);
     184             : 
     185           1 :         r = test_one(false, false, false, false);
     186           1 :         assert_se(r >= 0);
     187             : 
     188           1 :         r = test_one(true, true, true, true);
     189           1 :         assert_se(r >= 0);
     190             : 
     191           1 :         r = test_one(true, true, false, true);
     192           1 :         assert_se(r >= 0);
     193             : 
     194           1 :         r = test_one(true, true, true, false);
     195           1 :         assert_se(r == -EPERM);
     196             : 
     197           1 :         return EXIT_SUCCESS;
     198             : }

Generated by: LCOV version 1.14