Add dbus-test-tool, currently with "echo" and "spam" modes
authorAlban Crequy <alban.crequy@collabora.co.uk>
Mon, 26 Sep 2011 10:02:59 +0000 (11:02 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 14 Oct 2014 12:53:54 +0000 (13:53 +0100)
This is installed by default, but easy to filter out for embedded systems
or whatever.

Based on earlier work by Simon McVittie and Will Thompson

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=34140
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
tools/.gitignore
tools/Makefile.am
tools/dbus-echo.c [new file with mode: 0644]
tools/dbus-spam.c [new file with mode: 0644]
tools/test-tool.c [new file with mode: 0644]
tools/test-tool.h [new file with mode: 0644]
tools/tool-common.c [new file with mode: 0644]
tools/tool-common.h [new file with mode: 0644]

index d7c21af..1e0d987 100644 (file)
@@ -19,3 +19,4 @@ dbus-glib-bindings.h
 run-with-tmp-session-bus.conf
 print-introspect
 dbus-bus-introspect.xml
+dbus-test-tool
index 2ec19ed..05d1dcb 100644 (file)
@@ -15,6 +15,7 @@ bin_PROGRAMS = \
        dbus-launch \
        dbus-monitor \
        dbus-send \
+       dbus-test-tool \
        $(NULL)
 
 if DBUS_UNIX
@@ -81,6 +82,16 @@ dist_examples_SCRIPTS = \
        GetAllMatchRules.py \
        $(NULL)
 
+dbus_test_tool_SOURCES = \
+       dbus-echo.c \
+       dbus-spam.c \
+       tool-common.c \
+       tool-common.h \
+       test-tool.c \
+       test-tool.h \
+       $(NULL)
+dbus_test_tool_LDADD = $(top_builddir)/dbus/libdbus-1.la
+
 EXTRA_DIST = run-with-tmp-session-bus.sh strtoll.c strtoull.c
 CLEANFILES =                           \
        run-with-tmp-session-bus.conf
diff --git a/tools/dbus-echo.c b/tools/dbus-echo.c
new file mode 100644 (file)
index 0000000..05af601
--- /dev/null
@@ -0,0 +1,154 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-echo.c - a plain libdbus echo server
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+
+#include "test-tool.h"
+#include "tool-common.h"
+
+static void
+usage (int exit_with)
+{
+  fprintf (stderr,
+           "Usage: dbus-test-tool echo [OPTIONS]\n"
+           "\n"
+           "Respond to all method calls with an empty reply.\n"
+           "\n"
+           "Options:\n"
+           "\n"
+           "    --name=NAME   claim this well-known name first\n"
+           "\n"
+           "    --sleep=N     sleep N milliseconds before sending each reply\n"
+           "\n"
+           "    --session     use the session bus (default)\n"
+           "    --system      use the system bus\n"
+           );
+  exit (exit_with);
+}
+
+static DBusHandlerResult
+filter (DBusConnection *connection,
+    DBusMessage *message,
+    void *user_data)
+{
+  DBusMessage *reply;
+  int *sleep_ms = user_data;
+
+  if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+  if (*sleep_ms > 0)
+    {
+      tool_millisleep (*sleep_ms);
+    }
+
+  reply = dbus_message_new_method_return (message);
+
+  if (reply == NULL)
+    tool_oom ("allocating reply");
+
+  if (!dbus_connection_send (connection, reply, NULL))
+    tool_oom ("sending reply");
+
+  dbus_message_unref (reply);
+
+  return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+int
+dbus_test_tool_echo (int argc, char **argv)
+{
+  DBusConnection *connection;
+  DBusError error = DBUS_ERROR_INIT;
+  DBusBusType type = DBUS_BUS_SESSION;
+  int i;
+  int sleep_ms = -1;
+  const char *name = NULL;
+
+  /* argv[1] is the tool name, so start from 2 */
+
+  for (i = 2; i < argc; i++)
+    {
+      const char *arg = argv[i];
+
+      if (strcmp (arg, "--system") == 0)
+        {
+          type = DBUS_BUS_SYSTEM;
+        }
+      else if (strcmp (arg, "--session") == 0)
+        {
+          type = DBUS_BUS_SESSION;
+        }
+      else if (strstr (arg, "--name=") == arg)
+        {
+          name = arg + strlen ("--name=");
+        }
+      else if (strstr (arg, "--sleep-ms=") == arg)
+        {
+          sleep_ms = atoi (arg + strlen ("--sleep-ms="));
+        }
+      else
+        {
+          usage (2);
+        }
+    }
+
+  connection = dbus_bus_get (type, &error);
+
+  if (connection == NULL)
+    {
+      fprintf (stderr, "Failed to connect to bus: %s: %s\n",
+               error.name, error.message);
+      dbus_error_free (&error);
+      return 1;
+    }
+
+  if (name != NULL)
+    {
+      if (dbus_bus_request_name (connection, name, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+                                 NULL) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+        {
+          fprintf (stderr, "failed to take bus name %s\n", name);
+          exit (1);
+        }
+    }
+  else
+    {
+      printf ("%s\n", dbus_bus_get_unique_name (connection));
+    }
+
+  if (!dbus_connection_add_filter (connection, filter, &sleep_ms, NULL))
+    tool_oom ("adding message filter");
+
+  while (dbus_connection_read_write_dispatch (connection, -1))
+    {}
+
+  dbus_connection_unref (connection);
+  return 0;
+}
diff --git a/tools/dbus-spam.c b/tools/dbus-spam.c
new file mode 100644 (file)
index 0000000..76f0e06
--- /dev/null
@@ -0,0 +1,461 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-spam.c - a plain libdbus message-sender, loosely based on dbus-send
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <dbus/dbus.h>
+
+#include "test-tool.h"
+#include "tool-common.h"
+
+static dbus_bool_t ignore_errors = FALSE;
+
+static void
+usage (int ecode)
+{
+  fprintf (stderr,
+           "Usage: dbus-test-tool spam [OPTIONS]\n"
+           "\n"
+           "Repeatedly call com.example.Spam() on the given D-Bus service.\n"
+           "\n"
+           "Options:\n"
+           "\n"
+           "    --session     use the session bus (default)\n"
+           "    --system      use the system bus\n"
+           "\n"
+           "    --ignore-errors    ignore errors\n"
+           "    --dest=NAME   call methods on NAME (default " DBUS_SERVICE_DBUS ")\n"
+           "\n"
+           "    --count=N     send N messages (default 1)\n"
+           "    --queue=N     queue up N messages at a time (default 1)\n"
+           "    --flood       send all messages immediately\n"
+           "    --no-reply    set the NO_REPLY flag (implies --flood)\n"
+           "\n"
+           "    --string      send payload as a string (default)\n"
+           "    --bytes       send payload as a byte-array\n"
+           "    --empty       send an empty payload\n"
+           "\n"
+           "    --payload=S   use S as payload (default \"hello, world!\")\n"
+           "    --stdin       read payload from stdin, until EOF\n"
+           "    --message-stdin   read a complete D-Bus message from stdin\n"
+           "    --random-size read whitespace-separated ASCII decimal\n"
+           "                  payload sizes from stdin and pick one randomly\n"
+           "                  for each message\n"
+           "\n"
+           "    --seed=SEED   seed for srand (default is time())\n"
+           "\n"
+           );
+  exit (ecode);
+}
+
+static void
+pc_notify (DBusPendingCall *pc,
+           void            *data)
+{
+  DBusMessage *message;
+  int *received_p = data;
+  DBusError error;
+
+  dbus_error_init (&error);
+
+  message = dbus_pending_call_steal_reply (pc);
+
+  if (!ignore_errors && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      dbus_set_error_from_message (&error, message);
+      fprintf (stderr, "Failed to receive reply #%d: %s: %s\n", *received_p,
+               error.name, error.message);
+    }
+  else
+    {
+      VERBOSE (stderr, "received message #%d\n", *received_p);
+    }
+
+  (*received_p)++;
+}
+
+static void
+consume_stdin (char   **payload_p,
+               size_t  *len_p)
+{
+  const size_t BLOCK_SIZE = 4096;
+  size_t len = BLOCK_SIZE;
+  size_t pos = 0;
+  size_t n;
+  char *buf;
+
+  buf = dbus_malloc (len);
+
+  if (buf == NULL)
+    tool_oom ("reading payload from stdin");
+
+  while (1)
+    {
+      if (len - pos < BLOCK_SIZE)
+        {
+          char *tmp = dbus_realloc (buf, len + BLOCK_SIZE);
+
+          if (tmp == NULL)
+            tool_oom ("reading payload from stdin");
+
+          buf = tmp;
+          len += BLOCK_SIZE;
+        }
+
+      n = fread (buf + pos, 1, len - pos, stdin);
+
+      if (n <= 0)
+        {
+          /* EOF or error - treat as EOF */
+          break;
+        }
+
+      pos += n;
+    }
+
+  *len_p = pos;
+  *payload_p = buf;
+}
+
+int
+dbus_test_tool_spam (int argc, char **argv)
+{
+  DBusConnection *connection;
+  DBusError error = DBUS_ERROR_INIT;
+  DBusBusType type = DBUS_BUS_SESSION;
+  const char *destination = DBUS_SERVICE_DBUS;
+  int i;
+  int count = 1;
+  int sent = 0;
+  int received = 0;
+  int queue_len = 1;
+  const char *payload = NULL;
+  char *payload_buf = NULL;
+  size_t payload_len;
+  int payload_type = DBUS_TYPE_STRING;
+  DBusMessage *template = NULL;
+  dbus_bool_t no_reply = FALSE;
+  unsigned int seed = time (NULL);
+  int n_random_sizes = 0;
+  unsigned int *random_sizes = NULL;
+
+  /* argv[1] is the tool name, so start from 2 */
+
+  for (i = 2; i < argc; i++)
+    {
+      const char *arg = argv[i];
+
+      if (strcmp (arg, "--system") == 0)
+        {
+          type = DBUS_BUS_SYSTEM;
+        }
+      else if (strcmp (arg, "--session") == 0)
+        {
+          type = DBUS_BUS_SESSION;
+        }
+      else if (strstr (arg, "--count=") == arg)
+        {
+          count = atoi (arg + strlen ("--count="));
+
+          if (count < 1)
+            usage (2);
+        }
+      else if (strcmp (arg, "--ignore-errors") == 0)
+        {
+          ignore_errors = TRUE;
+        }
+      else if (strstr (arg, "--dest=") == arg)
+        {
+          destination = arg + strlen ("--dest=");
+        }
+      else if (strstr (arg, "--payload=") == arg)
+        {
+          payload = arg + strlen ("--payload=");
+        }
+      else if (strcmp (arg, "--stdin") == 0)
+        {
+          consume_stdin (&payload_buf, &payload_len);
+          payload = payload_buf;
+        }
+      else if (strcmp (arg, "--message-stdin") == 0)
+        {
+          consume_stdin (&payload_buf, &payload_len);
+          payload = payload_buf;
+          template = dbus_message_demarshal (payload, payload_len, &error);
+
+          if (template == NULL)
+            {
+              fprintf (stderr, "Unable to demarshal template message: %s: %s",
+                       error.name, error.message);
+              exit (1);
+            }
+
+          if (dbus_message_get_type (template) != DBUS_MESSAGE_TYPE_METHOD_CALL)
+            {
+              fprintf (stderr, "Template message must be a method call\n");
+              exit (1);
+            }
+        }
+      else if (strcmp (arg, "--random-size") == 0)
+        {
+          unsigned int len, max = 0;
+          int j, consumed = 0;
+          const char *p;
+
+          consume_stdin (&payload_buf, &payload_len);
+
+          for (p = payload_buf; p < payload_buf + payload_len; p += consumed)
+            {
+              /* the space character matches any (or no) whitespace */
+              if (sscanf (p, " %u %n", &len, &consumed) == 0)
+                break;
+
+              n_random_sizes++;
+            }
+
+          random_sizes = dbus_new0 (int, n_random_sizes);
+
+          if (random_sizes == NULL)
+            tool_oom ("allocating array of message lengths");
+
+          for (p = payload_buf, j = 0;
+              p < payload_buf + payload_len && j < n_random_sizes;
+              p += consumed, j++)
+            {
+              sscanf (p, " %u %n", &len, &consumed);
+              random_sizes[j] = len;
+
+              if (len > max)
+                max = len;
+            }
+
+          dbus_free (payload_buf);
+          payload_len = max + 1;
+          payload_buf = dbus_new (char, payload_len);
+          payload = payload_buf;
+
+          if (payload_buf == NULL)
+            tool_oom ("allocating maximum-sized payload");
+
+          memset (payload_buf, 'X', payload_len);
+          payload_buf[payload_len - 1] = '\0';
+        }
+      else if (strcmp (arg, "--empty") == 0)
+        {
+          payload_type = DBUS_TYPE_INVALID;
+        }
+      else if (strcmp (arg, "--string") == 0)
+        {
+          payload_type = DBUS_TYPE_STRING;
+        }
+      else if (strcmp (arg, "--bytes") == 0)
+        {
+          payload_type = DBUS_TYPE_ARRAY;
+        }
+      else if (strcmp (arg, "--flood") == 0)
+        {
+          queue_len = -1;
+        }
+      else if (strcmp (arg, "--no-reply") == 0)
+        {
+          queue_len = -1;
+          no_reply = TRUE;
+        }
+      else if (strstr (arg, "--queue=") == arg)
+        {
+          queue_len = atoi (arg + strlen ("--queue="));
+
+          if (queue_len < 1)
+            usage (2);
+        }
+      else if (strstr (arg, "--seed=") == arg)
+        {
+          seed = strtoul (arg + strlen ("--seed="), NULL, 10);
+        }
+      else
+        {
+          usage (2);
+        }
+    }
+
+  srand (seed);
+
+  if (payload == NULL)
+    {
+      payload = "hello, world!";
+      payload_len = strlen (payload);
+    }
+
+  VERBOSE (stderr, "Will send up to %d messages, with up to %d queued\n",
+           count, queue_len);
+
+  connection = dbus_bus_get_private (type, &error);
+
+  if (connection == NULL)
+    {
+      fprintf (stderr, "Failed to connect to bus: %s: %s\n",
+               error.name, error.message);
+      dbus_error_free (&error);
+      return 1;
+    }
+
+  while (no_reply ? sent < count : received < count)
+    {
+      while (sent < count &&
+             (queue_len == -1 || sent < queue_len + received))
+        {
+          DBusMessage *message;
+
+          if (template != NULL)
+            {
+              message = dbus_message_copy (template);
+
+              if (message == NULL)
+                tool_oom ("copying message");
+
+              dbus_message_set_no_reply (message, no_reply);
+            }
+          else
+            {
+              dbus_bool_t mem;
+              unsigned int len = 0;
+
+              message = dbus_message_new_method_call (destination,
+                                                      "/",
+                                                      "com.example",
+                                                      "Spam");
+
+              if (message == NULL)
+                tool_oom ("allocating message");
+
+              dbus_message_set_no_reply (message, no_reply);
+
+              switch (payload_type)
+                {
+                  case DBUS_TYPE_STRING:
+                    if (random_sizes != NULL)
+                      {
+                        /* this isn't fair, strictly speaking - the first few
+                         * are a bit more likely to be chosen, unless
+                         * RAND_MAX is divisible by n_random_sizes - but it's
+                         * good enough for traffic-generation */
+                        len = random_sizes[rand () % n_random_sizes];
+                        payload_buf[len] = '\0';
+                      }
+
+                    mem = dbus_message_append_args (message,
+                                                    DBUS_TYPE_STRING, &payload,
+                                                    DBUS_TYPE_INVALID);
+
+                    if (random_sizes != NULL)
+                      {
+                        /* undo the truncation above */
+                        payload_buf[len] = 'X';
+                      }
+
+                    break;
+
+                  case DBUS_TYPE_ARRAY:
+                    len = payload_len;
+
+                    /* as above, not strictly fair, but close enough */
+                    if (random_sizes != NULL)
+                      len = random_sizes[rand () % n_random_sizes];
+
+                    mem = dbus_message_append_args (message,
+                                                    DBUS_TYPE_ARRAY,
+                                                      DBUS_TYPE_BYTE,
+                                                      &payload,
+                                                      (dbus_uint32_t) len,
+                                                    DBUS_TYPE_INVALID);
+                    break;
+
+                  default:
+                    mem = TRUE;
+                }
+
+              if (!mem)
+                tool_oom ("building message");
+            }
+
+          if (no_reply)
+            {
+              if (!dbus_connection_send (connection, message, NULL))
+                tool_oom ("sending message");
+
+              sent++;
+            }
+          else
+            {
+              DBusPendingCall *pc;
+
+              if (!dbus_connection_send_with_reply (connection,
+                                                    message,
+                                                    &pc,
+                                                    DBUS_TIMEOUT_INFINITE))
+                tool_oom ("sending message");
+
+              VERBOSE (stderr, "sent message #%d\n", sent);
+              sent++;
+
+              if (pc == NULL)
+                tool_oom ("sending message");
+
+              if (dbus_pending_call_get_completed (pc))
+                pc_notify (pc, &received);
+              else if (!dbus_pending_call_set_notify (pc, pc_notify, &received,
+                                                      NULL))
+                tool_oom ("setting pending call notifier");
+
+              dbus_pending_call_unref (pc);
+            }
+
+          dbus_message_unref (message);
+        }
+
+      if (!dbus_connection_read_write_dispatch (connection, -1))
+        {
+          fprintf (stderr, "Disconnected from bus\n");
+          exit (1);
+        }
+    }
+
+  dbus_connection_flush (connection);
+
+  VERBOSE (stderr, "Done\n");
+
+  dbus_free (payload_buf);
+
+  if (template != NULL)
+    dbus_message_unref (template);
+
+  dbus_connection_close (connection);
+  dbus_connection_unref (connection);
+  dbus_shutdown ();
+  return 0;
+}
diff --git a/tools/test-tool.c b/tools/test-tool.c
new file mode 100644 (file)
index 0000000..1893b78
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-test-tool - D-Bus swiss army knife
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <config.h>
+#include "test-tool.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dbus/dbus.h>
+
+static struct {
+    const char *name;
+    int (*callback) (int, char **);
+} subcommands[] = {
+      { "echo", dbus_test_tool_echo },
+      { "spam", dbus_test_tool_spam },
+      { NULL, NULL }
+};
+
+static void usage (int exit_with) _DBUS_GNUC_NORETURN;
+
+static void
+usage (int exit_with)
+{
+  int i;
+
+  fprintf (stderr,
+           "Usage: dbus-test-tool SUBCOMMAND [OPTIONS]\n"
+           "\n"
+           "Known SUBCOMMANDs are:\n"
+           "\n"
+           );
+
+  for (i = 0; subcommands[i].name != NULL; i++)
+    {
+      fprintf (stderr, "- %s\n", subcommands[i].name);
+    }
+
+  fprintf (stderr,
+           "\n"
+           "For more information: dbus-test-tool SUBCOMMAND --help\n"
+           );
+
+  exit (exit_with);
+}
+
+int
+main (int argc, char **argv)
+{
+  int i;
+
+  if (argc < 2)
+    {
+      usage (2);
+    }
+
+  for (i = 0; subcommands[i].name != NULL; i++)
+    {
+      if (!strcmp (argv[1], subcommands[i].name))
+        return subcommands[i].callback (argc, argv);
+    }
+
+  usage (2);
+  return 2;
+}
diff --git a/tools/test-tool.h b/tools/test-tool.h
new file mode 100644 (file)
index 0000000..b6d51c2
--- /dev/null
@@ -0,0 +1,30 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* dbus-test-tool - D-Bus swiss army knife
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef DBUS_TEST_TOOL_H
+#define DBUS_TEST_TOOL_H
+
+int dbus_test_tool_echo (int argc, char **argv);
+int dbus_test_tool_spam (int argc, char **argv);
+
+#endif
diff --git a/tools/tool-common.c b/tools/tool-common.c
new file mode 100644 (file)
index 0000000..b6af629
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* tool-common - common functionality for dbus-test-tool modules
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <config.h>
+#include "tool-common.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef DBUS_WIN
+#include <windows.h>
+#endif
+
+/* a hack to avoid having to depend on the static -util version of libdbus;
+ * it's useful for ancillary programs to be able to use the shared library */
+void
+tool_millisleep (int ms)
+{
+#ifdef DBUS_WIN
+  Sleep (ms);
+#else
+  fd_set nothing;
+  struct timeval tv;
+
+  tv.tv_sec = ms / 1000;
+  tv.tv_usec = (ms % 1000) * 1000;
+
+  FD_ZERO (&nothing);
+  select (1, &nothing, &nothing, &nothing, &tv);
+#endif
+}
+
+void
+tool_oom (const char *doing)
+{
+  fprintf (stderr, "OOM while %s\n", doing);
+  exit (1);
+}
diff --git a/tools/tool-common.h b/tools/tool-common.h
new file mode 100644 (file)
index 0000000..f31076f
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/* tool-common - common functionality for dbus-test-tool modules
+ *
+ * Copyright © 2003 Philip Blundell <philb@gnu.org>
+ * Copyright © 2011 Nokia Corporation
+ * Copyright © 2014 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef DBUS_TOOL_COMMON_H
+#define DBUS_TOOL_COMMON_H
+
+#include <dbus/dbus.h>
+
+#if 0
+#define VERBOSE fprintf
+#else
+#define VERBOSE(...) do {} while (0)
+#endif
+
+void tool_millisleep (int ms);
+void tool_oom (const char *doing);
+
+#endif