summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2011-09-14 18:15:08 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2011-09-14 18:15:08 +0100
commitcf447c8af038d2470011c685eb391fd76ffd8f40 (patch)
treea23357ee0a27fd020ac03184b4e1bb0358869048
parent59c6663293bbbd9399f4c16611e06bbe799ddb8a (diff)
old WiP: inetd-style listeningwip-inetd
-rw-r--r--dbus/dbus-server-unix.c28
-rw-r--r--dbus/dbus-sysdeps-unix.c113
2 files changed, 125 insertions, 16 deletions
diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index 70ad9654..20e2dd8d 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -179,7 +179,33 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
dbus_free (fds);
return DBUS_SERVER_LISTEN_OK;
- }
+ }
+ else if (strcmp (method, "inetd") == 0)
+ {
+ int fd;
+ DBusString address;
+
+ fd = _dbus_listen_inetd (error);
+
+ if (fd < 0)
+ {
+ _DBUS_ASSERT_ERROR_IS_SET (error);
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
+
+ _dbus_string_init_const (&address, "inetd:");
+
+ *server_p = _dbus_server_new_for_socket (&fd, 1, &address, NULL);
+
+ if (*server_p == NULL)
+ {
+ _dbus_close_socket (fd, NULL);
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
+ }
+
+ return DBUS_SERVER_LISTEN_OK;
+ }
#ifdef DBUS_ENABLE_LAUNCHD
else if (strcmp (method, "launchd") == 0)
{
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index e9ea2535..58cd50e8 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -1028,6 +1028,102 @@ _dbus_listen_unix_socket (const char *path,
return listen_fd;
}
+static dbus_bool_t
+check_socket_is_listening_stream (int fd,
+ DBusError *error)
+{
+ /* We use systemd utility functions here: they're meant to be portable
+ * to non-Linux Unixes */
+ r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
+
+ if (r < 0)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (-r),
+ "Failed to verify passed socket type: %s",
+ _dbus_strerror (-r));
+ return FALSE;
+ }
+
+ if (!r)
+ {
+ dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
+ "Passed socket has wrong type.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Acquires the socket that is our stdin and stdout. Reopens stdin and stdout
+ * from/to /dev/null, sets the socket to be nonblocking and close on exec,
+ * and returns the socket's new fd.
+ *
+ * @returns a socket fd, or -1 on error
+ */
+int
+_dbus_listen_inetd (DBusError *error)
+{
+ int fd = -1, nullfd = -1;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+ if (!check_socket_is_listening_stream (STDIN_FILENO, error))
+ return -1;
+
+ if (!check_socket_is_listening_stream (STDOUT_FILENO, error))
+ return -1;
+
+ nullfd = open ("/dev/null", O_RDWR);
+
+ if (nullfd == -1)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED, "Failed to open /dev/null");
+ goto fail;
+ }
+
+ fd = _dbus_dup (STDIN_FILENO, error);
+
+ if (fd < 0)
+ goto fail;
+
+ if (dup2 (fd, STDIN_FILENO))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to dup /dev/null to replace stdin");
+ goto fail;
+ }
+
+ if (dup2 (fd, STDOUT_FILENO))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to dup /dev/null to replace stdout");
+ goto fail;
+ }
+
+ _dbus_close (nullfd, NULL);
+ nullfd = -1;
+
+ if (!_dbus_set_local_creds (fd, TRUE))
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to enable LOCAL_CREDS on inetd socket: %s",
+ _dbus_strerror (errno));
+ goto fail;
+ }
+
+ return fd;
+
+fail:
+ if (fd >= 0)
+ _dbus_close (fd, NULL);
+
+ if (nullfd >= 0)
+ _dbus_close (nullfd, NULL);
+
+ return -1;
+}
+
/**
* Acquires one or more sockets passed in from systemd. The sockets
* are set to be nonblocking.
@@ -1066,21 +1162,8 @@ _dbus_listen_systemd_sockets (int **fds,
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
{
- r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
- if (r < 0)
- {
- dbus_set_error (error, _dbus_error_from_errno (-r),
- "Failed to verify systemd socket type: %s",
- _dbus_strerror (-r));
- return -1;
- }
-
- if (!r)
- {
- dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
- "Passed socket has wrong type.");
- return -1;
- }
+ if (!check_socket_is_listening_stream (fd, error))
+ return -1;
}
/* OK, the file descriptors are all good, so let's take posession of