summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--dbus/dbus-connection-internal.h4
-rw-r--r--dbus/dbus-connection.c14
-rw-r--r--dbus/dbus-sysdeps-unix.c167
-rw-r--r--dbus/dbus-sysdeps-unix.h6
-rw-r--r--dbus/dbus-sysdeps.c18
-rw-r--r--dbus/dbus-test.c2
-rw-r--r--dbus/dbus-test.h1
-rw-r--r--dbus/dbus-transport-unix.c211
-rw-r--r--doc/dbus-launch.14
-rw-r--r--doc/dbus-specification.xml67
-rw-r--r--test/Makefile.am214
12 files changed, 601 insertions, 112 deletions
diff --git a/NEWS b/NEWS
index 58b801dd..6496a1ea 100644
--- a/NEWS
+++ b/NEWS
@@ -9,9 +9,14 @@ D-Bus 1.5.11 (UNRELEASED)
• Turn DBusBasicValue into public API so bindings don't need to invent their
own "union of everything" type (fd.o #11191, Simon McVittie)
+• Enumerate data files included in the build rather than using find(1)
+ (fd.o #33840, Simon McVittie)
+
• Windows-specific:
· make dbus-daemon.exe --print-address (and --print-pid) work again
on Win32, but not on WinCE (fd.o #46049, Simon McVittie)
+ · fix duplicate case value when compiling against mingw-w64
+ (fd.o #47321, Andoni Morales Alastruey)
D-Bus 1.5.10 (2012-02-21)
==
diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
index ac4158e9..3d37f188 100644
--- a/dbus/dbus-connection-internal.h
+++ b/dbus/dbus-connection-internal.h
@@ -114,6 +114,10 @@ void _dbus_connection_get_stats (DBusConnection *connection,
dbus_uint32_t *out_peak_bytes,
dbus_uint32_t *out_peak_fds);
+
+/* if DBUS_BUILD_TESTS */
+const char* _dbus_connection_get_address (DBusConnection *connection);
+
/* This _dbus_bus_* stuff doesn't really belong here, but dbus-bus-internal.h seems
* silly for one function
*/
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 74a9007c..ac0b2c0e 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -6258,4 +6258,18 @@ dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
return res;
}
+#ifdef DBUS_BUILD_TESTS
+/**
+ * Returns the address of the transport object of this connection
+ *
+ * @param connection the connection
+ * @returns the address string
+ */
+const char*
+_dbus_connection_get_address (DBusConnection *connection)
+{
+ return _dbus_transport_get_address (connection->transport);
+}
+#endif
+
/** @} */
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index da3f0350..9fddca73 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -866,6 +866,96 @@ _dbus_connect_unix_socket (const char *path,
}
/**
+ * Creates a UNIX domain socket and connects it to the specified
+ * process to execute.
+ *
+ * This will set FD_CLOEXEC for the socket returned.
+ *
+ * @param path the path to the executable
+ * @param argv the argument list for the process to execute.
+ * argv[0] typically is identical to the path of the executable
+ * @param error return location for error code
+ * @returns connection file descriptor or -1 on error
+ */
+int
+_dbus_connect_exec (const char *path,
+ char *const argv[],
+ DBusError *error)
+{
+ int fds[2];
+ pid_t pid;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ _dbus_verbose ("connecting to process %s\n", path);
+
+ if (socketpair (AF_UNIX, SOCK_STREAM
+#ifdef SOCK_CLOEXEC
+ |SOCK_CLOEXEC
+#endif
+ , 0, fds) < 0)
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to create socket pair: %s",
+ _dbus_strerror (errno));
+ return -1;
+ }
+
+ _dbus_fd_set_close_on_exec (fds[0]);
+ _dbus_fd_set_close_on_exec (fds[1]);
+
+ pid = fork ();
+ if (pid < 0)
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to fork() to call %s: %s",
+ path, _dbus_strerror (errno));
+ close (fds[0]);
+ close (fds[1]);
+ return -1;
+ }
+
+ if (pid == 0)
+ {
+ /* child */
+ close (fds[0]);
+
+ dup2 (fds[1], STDIN_FILENO);
+ dup2 (fds[1], STDOUT_FILENO);
+
+ if (fds[1] != STDIN_FILENO &&
+ fds[1] != STDOUT_FILENO)
+ close (fds[1]);
+
+ /* Inherit STDERR and the controlling terminal from the
+ parent */
+
+ _dbus_close_all ();
+
+ execvp (path, argv);
+
+ fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
+
+ _exit(1);
+ }
+
+ /* parent */
+ close (fds[1]);
+
+ if (!_dbus_set_fd_nonblocking (fds[0], error))
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+
+ close (fds[0]);
+ return -1;
+ }
+
+ return fds[0];
+}
+
+/**
* Enables or disables the reception of credentials on the given socket during
* the next message transmission. This is only effective if the #LOCAL_CREDS
* system feature exists, in which case the other side of the connection does
@@ -3124,7 +3214,6 @@ _read_subprocess_line_argv (const char *progpath,
int ret;
int status;
int orig_len;
- int i;
dbus_bool_t retval;
sigset_t new_set, old_set;
@@ -3177,7 +3266,6 @@ _read_subprocess_line_argv (const char *progpath,
if (pid == 0)
{
/* child process */
- int maxfds;
int fd;
fd = open ("/dev/null", O_RDWR);
@@ -3201,15 +3289,7 @@ _read_subprocess_line_argv (const char *progpath,
if (dup2 (errors_pipe[WRITE_END], 2) == -1)
_exit (1);
- maxfds = sysconf (_SC_OPEN_MAX);
- /* Pick something reasonable if for some reason sysconf
- * says unlimited.
- */
- if (maxfds < 0)
- maxfds = 1024;
- /* close all inherited fds */
- for (i = 3; i < maxfds; i++)
- close (i);
+ _dbus_close_all ();
sigprocmask (SIG_SETMASK, &old_set, NULL);
@@ -3920,4 +4000,69 @@ _dbus_replace_install_prefix (const char *configure_time_path)
return configure_time_path;
}
+/**
+ * Closes all file descriptors except the first three (i.e. stdin,
+ * stdout, stderr).
+ */
+void
+_dbus_close_all (void)
+{
+ int maxfds, i;
+
+#ifdef __linux__
+ DIR *d;
+
+ /* On Linux we can optimize this a bit if /proc is available. If it
+ isn't available, fall back to the brute force way. */
+
+ d = opendir ("/proc/self/fd");
+ if (d)
+ {
+ for (;;)
+ {
+ struct dirent buf, *de;
+ int k, fd;
+ long l;
+ char *e = NULL;
+
+ k = readdir_r (d, &buf, &de);
+ if (k != 0 || !de)
+ break;
+
+ if (de->d_name[0] == '.')
+ continue;
+
+ errno = 0;
+ l = strtol (de->d_name, &e, 10);
+ if (errno != 0 || e == NULL || *e != '\0')
+ continue;
+
+ fd = (int) l;
+ if (fd < 3)
+ continue;
+
+ if (fd == dirfd (d))
+ continue;
+
+ close (fd);
+ }
+
+ closedir (d);
+ return;
+ }
+#endif
+
+ maxfds = sysconf (_SC_OPEN_MAX);
+
+ /* Pick something reasonable if for some reason sysconf says
+ * unlimited.
+ */
+ if (maxfds < 0)
+ maxfds = 1024;
+
+ /* close all inherited fds */
+ for (i = 3; i < maxfds; i++)
+ close (i);
+}
+
/* tests in dbus-sysdeps-util.c */
diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h
index 9f92dcd1..9b708967 100644
--- a/dbus/dbus-sysdeps-unix.h
+++ b/dbus/dbus-sysdeps-unix.h
@@ -70,6 +70,10 @@ int _dbus_listen_unix_socket (const char *path,
dbus_bool_t abstract,
DBusError *error);
+int _dbus_connect_exec (const char *path,
+ char *const argv[],
+ DBusError *error);
+
int _dbus_listen_systemd_sockets (int **fd,
DBusError *error);
@@ -132,6 +136,8 @@ dbus_uid_t _dbus_geteuid (void);
dbus_bool_t _dbus_parse_uid (const DBusString *uid_str,
dbus_uid_t *uid);
+void _dbus_close_all (void);
+
/** @} */
DBUS_END_DECLS
diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
index c2258b3c..1a93cea7 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -614,16 +614,14 @@ _dbus_error_from_errno (int error_number)
#ifdef EPROTONOSUPPORT
case EPROTONOSUPPORT:
return DBUS_ERROR_NOT_SUPPORTED;
-#endif
-#ifdef WSAEPROTONOSUPPORT
+#elif defined(WSAEPROTONOSUPPORT)
case WSAEPROTONOSUPPORT:
return DBUS_ERROR_NOT_SUPPORTED;
#endif
#ifdef EAFNOSUPPORT
case EAFNOSUPPORT:
return DBUS_ERROR_NOT_SUPPORTED;
-#endif
-#ifdef WSAEAFNOSUPPORT
+#elif defined(WSAEAFNOSUPPORT)
case WSAEAFNOSUPPORT:
return DBUS_ERROR_NOT_SUPPORTED;
#endif
@@ -654,32 +652,28 @@ _dbus_error_from_errno (int error_number)
#ifdef ECONNREFUSED
case ECONNREFUSED:
return DBUS_ERROR_NO_SERVER;
-#endif
-#ifdef WSAECONNREFUSED
+#elif defined(WSAECONNREFUSED)
case WSAECONNREFUSED:
return DBUS_ERROR_NO_SERVER;
#endif
#ifdef ETIMEDOUT
case ETIMEDOUT:
return DBUS_ERROR_TIMEOUT;
-#endif
-#ifdef WSAETIMEDOUT
+#elif defined(WSAETIMEDOUT)
case WSAETIMEDOUT:
return DBUS_ERROR_TIMEOUT;
#endif
#ifdef ENETUNREACH
case ENETUNREACH:
return DBUS_ERROR_NO_NETWORK;
-#endif
-#ifdef WSAENETUNREACH
+#elif defined(WSAENETUNREACH)
case WSAENETUNREACH:
return DBUS_ERROR_NO_NETWORK;
#endif
#ifdef EADDRINUSE
case EADDRINUSE:
return DBUS_ERROR_ADDRESS_IN_USE;
-#endif
-#ifdef WSAEADDRINUSE
+#elif defined(WSAEADDRINUSE)
case WSAEADDRINUSE:
return DBUS_ERROR_ADDRESS_IN_USE;
#endif
diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c
index 02eaf89b..224a6c8c 100644
--- a/dbus/dbus-test.c
+++ b/dbus/dbus-test.c
@@ -154,6 +154,8 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir, const char *speci
#ifdef DBUS_UNIX
run_data_test ("userdb", specific_test, _dbus_userdb_test, test_data_dir);
+
+ run_test ("transport-unix", specific_test, _dbus_transport_unix_test);
#endif
run_test ("keyring", specific_test, _dbus_keyring_test);
diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h
index d97d142a..f254388b 100644
--- a/dbus/dbus-test.h
+++ b/dbus/dbus-test.h
@@ -48,6 +48,7 @@ dbus_bool_t _dbus_data_slot_test (void);
dbus_bool_t _dbus_sysdeps_test (void);
dbus_bool_t _dbus_spawn_test (const char *test_data_dir);
dbus_bool_t _dbus_userdb_test (const char *test_data_dir);
+dbus_bool_t _dbus_transport_unix_test (void);
dbus_bool_t _dbus_memory_test (void);
dbus_bool_t _dbus_object_tree_test (void);
dbus_bool_t _dbus_credentials_test (const char *test_data_dir);
diff --git a/dbus/dbus-transport-unix.c b/dbus/dbus-transport-unix.c
index a47756f2..6ba5c0b5 100644
--- a/dbus/dbus-transport-unix.c
+++ b/dbus/dbus-transport-unix.c
@@ -22,6 +22,9 @@
*/
#include <config.h>
+
+#include <stdio.h>
+
#include "dbus-internals.h"
#include "dbus-connection-internal.h"
#include "dbus-transport-unix.h"
@@ -29,6 +32,7 @@
#include "dbus-transport-protected.h"
#include "dbus-watch.h"
#include "dbus-sysdeps-unix.h"
+#include "dbus-test.h"
/**
* @defgroup DBusTransportUnix DBusTransport implementations for UNIX
@@ -108,6 +112,108 @@ _dbus_transport_new_for_domain_socket (const char *path,
}
/**
+ * Creates a new transport for the given binary and arguments. This
+ * creates a client-side of a transport. The process will be forked
+ * off and executed with stdin/stdout connected to a local AF_UNIX
+ * socket.
+ *
+ * @param path the path to the domain socket.
+ * @param argv Parameters list
+ * @param error address where an error can be returned.
+ * @returns a new transport, or #NULL on failure.
+ */
+static DBusTransport*
+_dbus_transport_new_for_exec (const char *path,
+ char *const argv[],
+ DBusError *error)
+{
+ int fd;
+ DBusTransport *transport;
+ DBusString address;
+ unsigned i;
+ char *escaped;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!_dbus_string_init (&address))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ fd = -1;
+
+ escaped = dbus_address_escape_value (path);
+ if (!escaped)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto failed;
+ }
+
+ if (!_dbus_string_append (&address, "unixexec:path=") ||
+ !_dbus_string_append (&address, escaped))
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ dbus_free (escaped);
+ goto failed;
+ }
+
+ dbus_free (escaped);
+
+ if (argv)
+ {
+ for (i = 0; argv[i]; i++)
+ {
+ dbus_bool_t success;
+
+ escaped = dbus_address_escape_value (argv[i]);
+ if (!escaped)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto failed;
+ }
+
+ success = _dbus_string_append_printf (&address, ",argv%u=%s", i, escaped);
+ dbus_free (escaped);
+
+ if (!success)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto failed;
+ }
+ }
+ }
+
+ fd = _dbus_connect_exec (path, argv, error);
+ if (fd < 0)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ goto failed;
+ }
+
+ _dbus_verbose ("Successfully connected to process %s\n",
+ path);
+
+ transport = _dbus_transport_new_for_socket (fd, NULL, &address);
+ if (transport == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ goto failed;
+ }
+
+ _dbus_string_free (&address);
+
+ return transport;
+
+ failed:
+ if (fd >= 0)
+ _dbus_close_socket (fd, NULL);
+
+ _dbus_string_free (&address);
+ return NULL;
+}
+
+/**
* Opens platform specific transport types.
*
* @param entry the address entry to try opening
@@ -168,7 +274,81 @@ _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
{
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
return DBUS_TRANSPORT_OPEN_OK;
- }
+ }
+ }
+ else if (strcmp (method, "unixexec") == 0)
+ {
+ const char *path;
+ unsigned i;
+ char **argv;
+
+ path = dbus_address_entry_get_value (entry, "path");
+ if (path == NULL)
+ {
+ _dbus_set_bad_address (error, NULL, NULL,
+ "No process path specified");
+ return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
+ }
+
+ /* First count argv arguments */
+ for (i = 1; ; i++)
+ {
+ char t[4+20+1]; /* "argv" plus space for a formatted base 10 64bit integer, plus NUL */
+
+ snprintf (t, sizeof(t), "argv%u", i);
+
+ if (!dbus_address_entry_get_value (entry, t))
+ break;
+ }
+
+ /* Allocate string array */
+ argv = dbus_new0 (char*, i+1);
+ if (!argv)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
+ }
+
+ /* Fill in string array */
+ for (i = 0; ; i++)
+ {
+ char t[4+20+1];
+ const char *p;
+
+ snprintf (t, sizeof(t), "argv%u", i);
+
+ p = dbus_address_entry_get_value (entry, t);
+ if (!p)
+ {
+ if (i == 0)
+ /* If argv0 isn't specified, fill in the path instead */
+ p = path;
+ else
+ break;
+ }
+
+ argv[i] = _dbus_strdup (p);
+ if (!argv[i])
+ {
+ dbus_free_string_array (argv);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
+ }
+ }
+
+ *transport_p = _dbus_transport_new_for_exec (path, argv, error);
+ dbus_free_string_array (argv);
+
+ if (*transport_p == NULL)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
+ }
+ else
+ {
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ return DBUS_TRANSPORT_OPEN_OK;
+ }
}
#ifdef DBUS_ENABLE_LAUNCHD
else if (strcmp (method, "launchd") == 0)
@@ -231,3 +411,32 @@ _dbus_transport_open_platform_specific (DBusAddressEntry *entry,
}
/** @} */
+
+#ifdef DBUS_BUILD_TESTS
+
+dbus_bool_t
+_dbus_transport_unix_test (void)
+{
+ DBusConnection *c;
+ DBusError error;
+ dbus_bool_t ret;
+ const char *address;
+
+ dbus_error_init (&error);
+
+ c = dbus_connection_open ("unixexec:argv0=false,argv1=foobar,path=/bin/false", &error);
+ _dbus_assert (c != NULL);
+ _dbus_assert (!dbus_error_is_set (&error));
+
+ address = _dbus_connection_get_address (c);
+ _dbus_assert (address != NULL);
+
+ /* Let's see if the address got parsed, reordered and formatted correctly */
+ ret = strcmp (address, "unixexec:path=/bin/false,argv0=false,argv1=foobar") == 0;
+
+ dbus_connection_unref (c);
+
+ return ret;
+}
+
+#endif
diff --git a/doc/dbus-launch.1 b/doc/dbus-launch.1
index 089e0f2c..a7687cad 100644
--- a/doc/dbus-launch.1
+++ b/doc/dbus-launch.1
@@ -19,7 +19,7 @@ backticks or the $() construct can be used to read information from
\fIdbus\-launch\fP.
With no arguments, \fIdbus\-launch\fP will launch a session bus
-instance and print the address and pid of that instance to standard
+instance and print the address and PID of that instance to standard
output.
You may specify a program to be run; in this case, \fIdbus\-launch\fP
@@ -42,7 +42,7 @@ With the \-\-auto\-syntax option, \fIdbus\-launch\fP looks at the value
of the SHELL environment variable to determine which shell syntax
should be used. If SHELL ends in "csh", then csh\-compatible code is
emitted; otherwise Bourne shell code is emitted. Instead of passing
-\-\-auto\-syntax, you may explicity specify a particular one by using
+\-\-auto\-syntax, you may explicitly specify a particular one by using
\-\-sh\-syntax for Bourne syntax, or \-\-csh\-syntax for csh syntax.
In scripts, it's more robust to avoid \-\-auto\-syntax and you hopefully
know which shell your script is written in.
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index 2ac82128..d806b8ea 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -2667,7 +2667,7 @@
[FIXME we need to specify in detail each transport and its possible arguments]
Current transports include: unix domain sockets (including
- abstract namespace on linux), launchd, systemd, TCP/IP, and a debug/testing transport
+ abstract namespace on linux), launchd, systemd, TCP/IP, an executed subprocess and a debug/testing transport
using in-process pipes. Future possible transports include one that
tunnels over X11 protocol.
</para>
@@ -2689,7 +2689,7 @@
would be padded by Nul bytes.
</para>
<para>
- Unix domain sockets are not available on windows.
+ Unix domain sockets are not available on Windows.
</para>
<sect3 id="transports-unix-domain-sockets-addresses">
<title>Server Address Format</title>
@@ -2806,7 +2806,7 @@
over a network is unsecure.
</para>
<para>
- Windows notes: Because of the tcp stack on windows does not provide sending
+ Windows notes: Because of the tcp stack on Windows does not provide sending
credentials over a tcp connection, the EXTERNAL authentification
mechanismus does not work.
</para>
@@ -2924,6 +2924,67 @@
</informaltable>
</sect3>
</sect2>
+ <sect2 id="transports-exec">
+ <title>Executed Subprocesses on Unix</title>
+ <para>
+ This transport forks off a process and connects its standard
+ input and standard output with an anonymous Unix domain
+ socket. This socket is then used for communication by the
+ transport. This transport may be used to use out-of-process
+ forwarder programs as basis for the D-Bus protocol.
+ </para>
+ <para>
+ The forked process will inherit the standard error output and
+ process group from the parent process.
+ </para>
+ <para>
+ Executed subprocesses are not available on Windows.
+ </para>
+ <sect3 id="transports-exec-addresses">
+ <title>Server Address Format</title>
+ <para>
+ Executed subprocess addresses are identified by the "unixexec:" prefix
+ and support the following key/value pairs:
+ </para>
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Values</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>path</entry>
+ <entry>(path)</entry>
+ <entry>Path of the binary to execute, either an absolute
+ path or a binary name that is searched for in the default
+ search path of the OS. This corresponds to the first
+ argument of execlp(). This key is mandatory.</entry>
+ </row>
+ <row>
+ <entry>argv0</entry>
+ <entry>(string)</entry>
+ <entry>The program name to use when executing the
+ binary. If omitted the same value as specified for path=
+ will be used. This corresponds to the second argument of
+ execlp().</entry>
+ </row>
+ <row>
+ <entry>argv1, argv2, ...</entry>
+ <entry>(string)</entry>
+ <entry>Arguments to pass to the binary. This corresponds
+ to the third and later arguments of execlp(). If a
+ specific argvX is not specified no further argvY for Y > X
+ are taken into account.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
</sect1>
<sect1 id="meta-transports">
<title>Meta Transports</title>
diff --git a/test/Makefile.am b/test/Makefile.am
index 9e66bd27..88a0e8cd 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -186,90 +186,138 @@ if DBUS_ENABLE_INSTALLED_TESTS
$(testexec_PROGRAMS)
endif DBUS_ENABLE_INSTALLED_TESTS
-## keep these in creation order, i.e. uppermost dirs first
-TESTDIRS= \
- data \
- data/valid-messages \
- data/invalid-messages \
- data/incomplete-messages \
- data/auth \
- data/sha-1 \
- data/valid-config-files \
- data/valid-config-files-system \
- data/valid-config-files/basic.d \
- data/valid-config-files/session.d \
- data/valid-config-files/system.d \
- data/valid-service-files \
- data/valid-service-files-system \
- data/invalid-service-files-system \
- data/invalid-config-files \
- data/invalid-config-files-system \
- data/equiv-config-files \
- data/equiv-config-files/basic \
- data/equiv-config-files/basic/basic.d \
- data/equiv-config-files/entities \
- data/equiv-config-files/entities/basic.d
-
-
-FIND_TESTS=find . -type f -a \( -name "*.message" -o -name "*.message-raw" -o -name "*.auth-script" -o -name "*.sha1" -o -name "*.txt" -o -name "*.conf" -o -name "*.service" \)
-
-dist-hook:
- for D in $(TESTDIRS); do \
- test -d $(distdir)/$$D || mkdir $(distdir)/$$D || exit 1 ; \
- done ; \
- FILES=`(cd $(srcdir) && $(FIND_TESTS) -o -name "*.in" -a -not -name Makefile.in | grep -Ev "(.svn|CVS)" )` ; \
- for F in $$FILES; do \
- B=`basename $$F`; \
- if test -e $$F.in; then \
- echo "-- Skipping file $$F (.in version exists)"; \
- elif test "x$$B" = xrun-with-tmp-session-bus.conf; then \
- echo "-- Skipping file $$F (generated)"; \
- elif test -e "$(top_srcdir)/bus/$$B"; then \
- echo "-- Skipping file $$F (from /bus/)"; \
- else \
- echo '-- Disting file '$$F ; \
- cp -f $(srcdir)/$$F $(distdir)/$$F || exit 1; \
- fi; \
- done
-
-## copy tests to builddir so that generated tests and static tests
+in_data = \
+ data/valid-config-files-system/debug-allow-all-fail.conf.in \
+ data/valid-config-files-system/debug-allow-all-pass.conf.in \
+ data/valid-config-files/debug-allow-all-sha1.conf.in \
+ data/valid-config-files/debug-allow-all.conf.in \
+ data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoExec.service.in \
+ data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoService.service.in \
+ data/invalid-service-files-system/org.freedesktop.DBus.TestSuiteNoUser.service.in \
+ data/valid-service-files-system/org.freedesktop.DBus.TestSuiteEchoService.service.in \
+ data/valid-service-files-system/org.freedesktop.DBus.TestSuiteSegfaultService.service.in \
+ data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in \
+ data/valid-service-files-system/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuite.PrivServer.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuiteEchoService.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuiteForkingEchoService.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuiteSegfaultService.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceFail.service.in \
+ data/valid-service-files/org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess.service.in \
+ $(NULL)
+
+EXTRA_DIST += $(in_data)
+
+static_data = \
+ name-test/tmp-session-like-system.conf \
+ data/auth/anonymous-client-successful.auth-script \
+ data/auth/anonymous-server-successful.auth-script \
+ data/auth/cancel.auth-script \
+ data/auth/client-out-of-mechanisms.auth-script \
+ data/auth/external-failed.auth-script \
+ data/auth/external-root.auth-script \
+ data/auth/external-silly.auth-script \
+ data/auth/external-successful.auth-script \
+ data/auth/extra-bytes.auth-script \
+ data/auth/fail-after-n-attempts.auth-script \
+ data/auth/fallback.auth-script \
+ data/auth/invalid-command-client.auth-script \
+ data/auth/invalid-command.auth-script \
+ data/auth/invalid-hex-encoding.auth-script \
+ data/auth/mechanisms.auth-script \
+ data/equiv-config-files/basic/basic-1.conf \
+ data/equiv-config-files/basic/basic-2.conf \
+ data/equiv-config-files/basic/basic.d/basic.conf \
+ data/equiv-config-files/entities/basic.d/basic.conf \
+ data/equiv-config-files/entities/entities-1.conf \
+ data/equiv-config-files/entities/entities-2.conf \
+ data/incomplete-messages/missing-body.message \
+ data/invalid-config-files/badselinux-1.conf \
+ data/invalid-config-files/badselinux-2.conf \
+ data/invalid-config-files/circular-1.conf \
+ data/invalid-config-files/circular-2.conf \
+ data/invalid-config-files/circular-3.conf \
+ data/invalid-config-files/not-well-formed.conf \
+ data/invalid-config-files/truncated-file.conf \
+ data/invalid-messages/array-of-nil.message \
+ data/invalid-messages/array-with-mixed-types.message \
+ data/invalid-messages/bad-boolean-array.message \
+ data/invalid-messages/bad-boolean.message \
+ data/invalid-messages/bad-endian.message \
+ data/invalid-messages/bad-header-field-alignment.message \
+ data/invalid-messages/boolean-has-no-value.message-raw \
+ data/invalid-messages/local-namespace.message \
+ data/invalid-messages/no-dot-in-name.message \
+ data/invalid-messages/not-nul-header-padding.message \
+ data/invalid-messages/overlong-name.message \
+ data/invalid-messages/too-little-header-padding.message \
+ data/invalid-messages/too-much-header-padding-by-far.message \
+ data/invalid-messages/too-much-header-padding.message \
+ data/invalid-messages/too-short-dict.message \
+ data/sha-1/Readme.txt \
+ data/sha-1/bit-hashes.sha1 \
+ data/sha-1/bit-messages.sha1 \
+ data/sha-1/byte-hashes.sha1 \
+ data/sha-1/byte-messages.sha1 \
+ data/valid-config-files/basic.conf \
+ data/valid-config-files/basic.d/basic.conf \
+ data/valid-config-files/entities.conf \
+ data/valid-config-files/incoming-limit.conf \
+ data/valid-config-files/many-rules.conf \
+ data/valid-config-files/system.d/test.conf \
+ data/valid-messages/array-of-array-of-uint32.message \
+ data/valid-messages/dict-simple.message \
+ data/valid-messages/dict.message \
+ data/valid-messages/emptiness.message \
+ data/valid-messages/lots-of-arguments.message \
+ data/valid-messages/no-padding.message \
+ data/valid-messages/opposite-endian.message \
+ data/valid-messages/recursive-types.message \
+ data/valid-messages/simplest-manual.message \
+ data/valid-messages/simplest.message \
+ data/valid-messages/standard-acquire-service.message \
+ data/valid-messages/standard-hello.message \
+ data/valid-messages/standard-list-services.message \
+ data/valid-messages/standard-service-exists.message \
+ data/valid-messages/unknown-header-field.message \
+ $(NULL)
+
+EXTRA_DIST += $(static_data)
+
+## copy tests to builddir so that generated tests and static tests
## are all in one place.
all-local:
- $(AM_V_at)for D in $(TESTDIRS); do \
- test -d $(top_builddir)/test/$$D || mkdir $(top_builddir)/test/$$D || exit 1 ; \
- done ; \
- if ! (test $(srcdir) = . || test $(srcdir) -ef .) ; then \
- FILES=`(cd $(srcdir) && $(FIND_TESTS) | grep -Ev "(.svn|CVS)" )` ; \
- for F in $$FILES; do \
- SRC=$(srcdir)/$$F ; \
- DEST=$(top_builddir)/test/$$F ; \
- echo '-- Copying test file '$$F ; \
- cp $$SRC $$DEST || exit 1 ; \
- chmod u+w $$DEST || exit 1 ; \
- done ; \
- else \
- echo '-- No need to copy test data as srcdir = builddir' ; \
- fi ; \
- echo '-- Copying' $(top_builddir)/bus/*.conf 'to test directory' ; \
- cp $(top_builddir)/bus/*.conf $(top_builddir)/test/data/valid-config-files || exit 1 ; \
- chmod u+w $(top_builddir)/test/data/valid-config-files/*.conf || exit 1
-
-## this doesn't clean generated test data files when srcdir=builddir
+ $(AM_V_at)$(INSTALL) -d data/valid-config-files/session.d
+ $(AM_V_at)set -e && \
+ if test $(srcdir) = . || test $(srcdir) -ef .; then \
+ echo '-- No need to copy test data as srcdir = builddir'; \
+ else \
+ for F in $(static_data); do \
+ $(INSTALL) -d $${F%/*}; \
+ $(INSTALL_DATA) $(srcdir)/$$F $$F; \
+ done; \
+ fi
+
+## this doesn't clean most copied test data files when srcdir=builddir
clean-local:
- if test $(srcdir) != . ; then \
- FILES=`(cd $(top_builddir)/test && $(FIND_TESTS) | grep -Ev "(.svn|CVS)" )` ; \
- for F in $$FILES; do \
- DEST=$(top_builddir)/test/$$F ; \
- echo '-- Deleting test file '$$F ; \
- rm $$DEST || exit 1 ; \
- done ; \
- REVERSEDIRS= ; \
- for D in $(TESTDIRS); do \
- REVERSEDIRS="$$D $$REVERSEDIRS" ; \
- done ; \
- for D in $$REVERSEDIRS; do \
- rmdir $(top_builddir)/test/$$D || \
- test ! -d $(top_builddir)/test/$$D || \
- exit 1 ; \
- done ; \
+ $(AM_V_at)if test $(srcdir) = . || test $(srcdir) -ef .; then \
+ echo '-- No need to clean test data as srcdir = builddir'; \
+ else \
+ rm -f $(static_data); \
fi
+
+imported_data = \
+ data/valid-config-files/session.conf \
+ data/valid-config-files/system.conf \
+ $(NULL)
+
+noinst_DATA = $(imported_data)
+CLEANFILES = $(noinst_DATA)
+
+data/valid-config-files/session.conf: $(top_builddir)/bus/session.conf
+ $(AM_V_at)$(INSTALL) -d data/valid-config-files
+ $(AM_V_GEN)$(INSTALL_DATA) $< $@
+
+data/valid-config-files/system.conf: $(top_builddir)/bus/system.conf
+ $(AM_V_at)$(INSTALL) -d data/valid-config-files
+ $(AM_V_GEN)$(INSTALL_DATA) $< $@