summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-05-06 15:31:45 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-05-06 15:31:45 -0400
commitc490c14f4e3fbbe8c74b26e6cacac31b0e744c92 (patch)
treedf9113881a866c54b5ef870900e2bd0ae581257b /gio
parentd0a14469d09d5fe23de219ba293fd4a266b02ced (diff)
downloadglib-c490c14f4e3fbbe8c74b26e6cacac31b0e744c92.tar.gz
Set up gtk-doc for GDBus
Also move send_credentials() and receive_credentials() to GUnixConnection. This code might change, discussion is still ongoing in https://bugzilla.gnome.org/show_bug.cgi?id=617483.
Diffstat (limited to 'gio')
-rw-r--r--gio/gcredentials.c4
-rw-r--r--gio/gdbusaddress.c2
-rw-r--r--gio/gdbusauth.c189
-rw-r--r--gio/gdbusauthobserver.c2
-rw-r--r--gio/gdbusconnection.c8
-rw-r--r--gio/gdbuserror.c2
-rw-r--r--gio/gdbusintrospection.c2
-rw-r--r--gio/gdbusmessage.c2
-rw-r--r--gio/gdbusmethodinvocation.c2
-rw-r--r--gio/gdbusnameowning.c4
-rw-r--r--gio/gdbusnamewatching.c4
-rw-r--r--gio/gdbusproxy.c2
-rw-r--r--gio/gdbusproxywatching.c4
-rw-r--r--gio/gdbusserver.c4
-rw-r--r--gio/gdbusutils.c2
-rw-r--r--gio/gunixconnection.c258
-rw-r--r--gio/gunixconnection.h10
17 files changed, 290 insertions, 211 deletions
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index e1712fe61..1ca25432b 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -36,8 +36,8 @@
/**
* SECTION:gcredentials
- * @short_description: Credentials
- * @include: gdbus/gdbus.h
+ * @short_description: An object containing credentials
+ * @include: gio/gio.h
*
* The #GCredentials type is used for storing information that can be
* used for identifying, authenticating and authorizing processes.
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index e50e73781..6cfa5f951 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -40,7 +40,7 @@
* SECTION:gdbusaddress
* @title: D-Bus Addresses
* @short_description: D-Bus connection endpoints
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Routines for working with D-Bus addresses.
*/
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index 850db9aa6..2d47060cd 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -78,195 +78,6 @@ debug_print (const gchar *message, ...)
#endif
}
-
-/* ---------------------------------------------------------------------------------------------------- */
-/* TODO: move to gio */
-
-/**
- * g_unix_connection_send_credentials:
- * @connection: A #GUnixConnection.
- * @credentials: A #GCredentials to send.
- * @cancellable: A #GCancellable or %NULL.
- * @error: Return location for error or %NULL.
- *
- * Passes the credentials stored in @credentials to the recieving side
- * of the connection. The recieving end has to call
- * g_unix_connection_receive_credentials() (or similar) to accept the
- * credentials.
- *
- * The credentials which the sender specifies are checked by the
- * kernel. A process with effective user ID 0 is allowed to specify
- * values that do not match its own. This means that the credentials
- * can be used to authenticate other connections.
- *
- * As well as sending the credentials this also writes a single NUL
- * byte to the stream, as this is required for credentials passing to
- * work on some implementations.
- *
- * Returns: %TRUE on success, %FALSE if @error is set.
- *
- * Since: 2.26
- */
-static gboolean
-g_unix_connection_send_credentials (GUnixConnection *connection,
- GCredentials *credentials,
- GCancellable *cancellable,
- GError **error)
-{
- GSocketControlMessage *scm;
- GSocket *socket;
- gboolean ret;
- GOutputVector vector;
- guchar nul_byte[1] = {'\0'};
-
- g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
- g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- ret = FALSE;
-
- vector.buffer = &nul_byte;
- vector.size = 1;
- scm = g_unix_credentials_message_new_with_credentials (credentials);
- g_object_get (connection, "socket", &socket, NULL);
- if (g_socket_send_message (socket,
- NULL, /* address */
- &vector,
- 1,
- &scm,
- 1,
- G_SOCKET_MSG_NONE,
- cancellable,
- error) != 1)
- {
- g_prefix_error (error, _("Error sending credentials: "));
- goto out;
- }
-
- ret = TRUE;
-
- out:
- g_object_unref (socket);
- g_object_unref (scm);
- return ret;
-}
-
-/**
- * g_unix_connection_receive_credentials:
- * @connection: A #GUnixConnection.
- * @cancellable: A #GCancellable or %NULL.
- * @error: Return location for error or %NULL.
- *
- * Receives credentials from the sending end of the connection. The
- * sending end has to call g_unix_connection_send_credentials() (or
- * similar) for this to work.
- *
- * As well as reading the credentials this also reads (and discards) a
- * single byte from the stream, as this is required for credentials
- * passing to work on some implementations.
- *
- * Returns: Received credentials on success (free with
- * g_object_unref()), %NULL if @error is set.
- *
- * Since: 2.26
- */
-static GCredentials *
-g_unix_connection_receive_credentials (GUnixConnection *connection,
- GCancellable *cancellable,
- GError **error)
-{
- GCredentials *ret;
- GSocketControlMessage **scms;
- gint nscm;
- GSocket *socket;
- gint n;
- volatile GType credentials_message_gtype;
- gssize num_bytes_read;
-
- g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-
- ret = NULL;
- scms = NULL;
-
- g_object_get (connection, "socket", &socket, NULL);
-
-#if 1
- /* TODO: Move this to gsocket.c... */
- {
- int opt_val = 1;
- if (setsockopt (g_socket_get_fd (socket),
- SOL_SOCKET,
- SO_PASSCRED,
- &opt_val,
- sizeof opt_val) != 0)
- {
- g_warning ("boo, error setting SO_PASSCRED: %m");
- }
- }
-#endif
-
- /* ensure the type of GUnixCredentialsMessage has been registered with the type system */
- credentials_message_gtype = G_TYPE_UNIX_CREDENTIALS_MESSAGE;
- num_bytes_read = g_socket_receive_message (socket,
- NULL, /* GSocketAddress **address */
- NULL,
- 0,
- &scms,
- &nscm,
- NULL,
- cancellable,
- error);
- if (num_bytes_read != 1)
- {
- /* Handle situation where g_socket_receive_message() returns
- * 0 bytes and not setting @error
- */
- if (num_bytes_read == 0 && error != NULL && *error == NULL)
- {
- g_set_error_literal (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Expecting to read a single byte for receiving credentials but read zero bytes"));
- }
- goto out;
- }
-
- if (nscm != 1)
- {
- g_set_error (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Expecting 1 control message, got %d"),
- nscm);
- goto out;
- }
-
- if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
- {
- g_set_error_literal (error,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Unexpected type of ancillary data"));
- goto out;
- }
-
- ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
- g_object_ref (ret);
-
- out:
- if (scms != NULL)
- {
- for (n = 0; n < nscm; n++)
- g_object_unref (scms[n]);
- g_free (scms);
- }
- g_object_unref (socket);
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
typedef struct
{
const gchar *name;
diff --git a/gio/gdbusauthobserver.c b/gio/gdbusauthobserver.c
index f0411aba8..4de672283 100644
--- a/gio/gdbusauthobserver.c
+++ b/gio/gdbusauthobserver.c
@@ -33,7 +33,7 @@
/**
* SECTION:gdbusauthobserver
* @short_description: Object used for authenticating connections
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* The #GDBusAuthObserver type provides a mechanism for participating
* in how a #GDBusServer (or a #GDBusConnection) authenticates remote
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 0bcd58f89..fdcb6ed29 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -78,7 +78,7 @@
/**
* SECTION:gdbusconnection
* @short_description: D-Bus Connections
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* <para><note>
* This class is rarely used directly in D-Bus clients. If you are
@@ -89,11 +89,11 @@
* The #GDBusConnection type is used for D-Bus connections to remote
* peers such as a message buses.
*
- * <example id="gdbus-server"><title>D-Bus server example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-server"><title>D-Bus server example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-server.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*
- * <example id="gdbus-subtree-server"><title>D-Bus subtree example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-subtree.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-subtree-server"><title>D-Bus subtree example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-subtree.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*
- * <example id="gdbus-unix-fd-client"><title>D-Bus UNIX File Descriptor example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-unix-fd-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-unix-fd-client"><title>D-Bus UNIX File Descriptor example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-unix-fd-client.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/gdbuserror.c b/gio/gdbuserror.c
index 3b0e080fc..5bc9c69ca 100644
--- a/gio/gdbuserror.c
+++ b/gio/gdbuserror.c
@@ -36,7 +36,7 @@
* SECTION:gdbuserror
* @title: GDBusError
* @short_description: Mapping D-Bus errors to and from #GError
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* All facilities that return errors from remote methods (such as
* g_dbus_connection_invoke_method_sync()) use #GError to represent
diff --git a/gio/gdbusintrospection.c b/gio/gdbusintrospection.c
index 63b945e0e..c76af4eb8 100644
--- a/gio/gdbusintrospection.c
+++ b/gio/gdbusintrospection.c
@@ -32,7 +32,7 @@
* SECTION:gdbusintrospection
* @title: Introspection XML
* @short_description: Parse and Generate Introspection XML
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Various data structures and convenience routines to parse and
* generate D-Bus introspection XML.
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
index 668b1c856..d1929ae3c 100644
--- a/gio/gdbusmessage.c
+++ b/gio/gdbusmessage.c
@@ -48,7 +48,7 @@
/**
* SECTION:gdbusmessage
* @short_description: D-Bus Message
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* A type for representing D-Bus messages that can be sent or received
* on a #GDBusConnection.
diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c
index dc6950bea..5885abcec 100644
--- a/gio/gdbusmethodinvocation.c
+++ b/gio/gdbusmethodinvocation.c
@@ -36,7 +36,7 @@
/**
* SECTION:gdbusmethodinvocation
* @short_description: Object for handling remote calls
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Instances of the #GDBusMethodInvocation class are used when
* handling D-Bus method calls. It provides a way to asynchronously
diff --git a/gio/gdbusnameowning.c b/gio/gdbusnameowning.c
index 30901651f..e840353f8 100644
--- a/gio/gdbusnameowning.c
+++ b/gio/gdbusnameowning.c
@@ -36,11 +36,11 @@
* SECTION:gdbusnameowning
* @title: Owning Bus Names
* @short_description: Simple API for owning bus names
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Convenience API for owning bus names.
*
- * <example id="gdbus-owning-names"><title>Simple application owning a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-own-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-owning-names"><title>Simple application owning a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-own-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
G_LOCK_DEFINE_STATIC (lock);
diff --git a/gio/gdbusnamewatching.c b/gio/gdbusnamewatching.c
index 92e04cc18..6ae4754da 100644
--- a/gio/gdbusnamewatching.c
+++ b/gio/gdbusnamewatching.c
@@ -36,11 +36,11 @@
* SECTION:gdbusnamewatching
* @title: Watching Bus Names
* @short_description: Simple API for watching bus names
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Convenience API for watching bus names.
*
- * <example id="gdbus-watching-names"><title>Simple application watching a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-watch-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-watching-names"><title>Simple application watching a name</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-watch-name.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
G_LOCK_DEFINE_STATIC (lock);
diff --git a/gio/gdbusproxy.c b/gio/gdbusproxy.c
index 39094d0b4..89aced924 100644
--- a/gio/gdbusproxy.c
+++ b/gio/gdbusproxy.c
@@ -42,7 +42,7 @@
/**
* SECTION:gdbusproxy
* @short_description: Base class for proxies
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* #GDBusProxy is a base class used for proxies to access a D-Bus
* interface on a remote object. A #GDBusProxy can only be constructed
diff --git a/gio/gdbusproxywatching.c b/gio/gdbusproxywatching.c
index 4f85c1de5..4025e1f92 100644
--- a/gio/gdbusproxywatching.c
+++ b/gio/gdbusproxywatching.c
@@ -39,11 +39,11 @@
* SECTION:gdbusproxywatching
* @title: Watching Proxies
* @short_description: Simple API for watching proxies
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Convenience API for watching bus proxies.
*
- * <example id="gdbus-watching-proxy"><title>Simple application watching a proxy</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-watch-proxy.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-watching-proxy"><title>Simple application watching a proxy</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-watch-proxy.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 0d0deeaa2..99e7701a2 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -44,12 +44,12 @@
/**
* SECTION:gdbusserver
* @short_description: Helper for accepting connections
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* #GDBusServer is a helper for listening to and accepting D-Bus
* connections.
*
- * <example id="gdbus-peer-to-peer"><title>D-Bus peer-to-peer example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../../gio/tests/gdbus-example-peer.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
+ * <example id="gdbus-peer-to-peer"><title>D-Bus peer-to-peer example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../gio/tests/gdbus-example-peer.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example>
*/
struct _GDBusServerPrivate
diff --git a/gio/gdbusutils.c b/gio/gdbusutils.c
index b1ec0ea1c..00529168a 100644
--- a/gio/gdbusutils.c
+++ b/gio/gdbusutils.c
@@ -33,7 +33,7 @@
* SECTION:gdbusutils
* @title: D-Bus Utilities
* @short_description: Various utilities related to D-Bus.
- * @include: gdbus/gdbus.h
+ * @include: gio/gio.h
*
* Various utility routines related to D-Bus.
*/
diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c
index 92ad246f8..8b618cb0a 100644
--- a/gio/gunixconnection.c
+++ b/gio/gunixconnection.c
@@ -36,6 +36,14 @@
#include <gio/gsocket.h>
#include <unistd.h>
+#ifdef __linux__
+/* for getsockopt() and setsockopt() */
+#include <sys/types.h> /* See NOTES */
+#include <sys/socket.h>
+#include <errno.h>
+#include <string.h>
+#endif
+
#include "gioalias.h"
G_DEFINE_TYPE_WITH_CODE (GUnixConnection, g_unix_connection,
@@ -287,5 +295,255 @@ gboolean g_unix_connection_create_pair (GUnixCo
GError **error);
*/
+
+/**
+ * g_unix_connection_send_credentials:
+ * @connection: A #GUnixConnection.
+ * @credentials: A #GCredentials to send.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Passes the credentials stored in @credentials to the recieving side
+ * of the connection. The recieving end has to call
+ * g_unix_connection_receive_credentials() (or similar) to accept the
+ * credentials.
+ *
+ * The credentials which the sender specifies are checked by the
+ * kernel. A process with effective user ID 0 is allowed to specify
+ * values that do not match its own. This means that the credentials
+ * can be used to authenticate other connections.
+ *
+ * As well as sending the credentials this also writes a single NUL
+ * byte to the stream, as this is required for credentials passing to
+ * work on some implementations.
+ *
+ * Returns: %TRUE on success, %FALSE if @error is set.
+ *
+ * Since: 2.26
+ */
+gboolean
+g_unix_connection_send_credentials (GUnixConnection *connection,
+ GCredentials *credentials,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GSocketControlMessage *scm;
+ GSocket *socket;
+ gboolean ret;
+ GOutputVector vector;
+ guchar nul_byte[1] = {'\0'};
+
+ g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), FALSE);
+ g_return_val_if_fail (G_IS_CREDENTIALS (credentials), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ ret = FALSE;
+
+ vector.buffer = &nul_byte;
+ vector.size = 1;
+ scm = g_unix_credentials_message_new_with_credentials (credentials);
+ g_object_get (connection, "socket", &socket, NULL);
+ if (g_socket_send_message (socket,
+ NULL, /* address */
+ &vector,
+ 1,
+ &scm,
+ 1,
+ G_SOCKET_MSG_NONE,
+ cancellable,
+ error) != 1)
+ {
+ g_prefix_error (error, _("Error sending credentials: "));
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ g_object_unref (socket);
+ g_object_unref (scm);
+ return ret;
+}
+
+/**
+ * g_unix_connection_receive_credentials:
+ * @connection: A #GUnixConnection.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Receives credentials from the sending end of the connection. The
+ * sending end has to call g_unix_connection_send_credentials() (or
+ * similar) for this to work.
+ *
+ * As well as reading the credentials this also reads (and discards) a
+ * single byte from the stream, as this is required for credentials
+ * passing to work on some implementations.
+ *
+ * Returns: Received credentials on success (free with
+ * g_object_unref()), %NULL if @error is set.
+ *
+ * Since: 2.26
+ */
+GCredentials *
+g_unix_connection_receive_credentials (GUnixConnection *connection,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GCredentials *ret;
+ GSocketControlMessage **scms;
+ gint nscm;
+ GSocket *socket;
+ gint n;
+ volatile GType credentials_message_gtype;
+ gssize num_bytes_read;
+#ifdef __linux__
+ gboolean turn_off_so_passcreds;
+#endif
+
+ g_return_val_if_fail (G_IS_UNIX_CONNECTION (connection), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ ret = NULL;
+ scms = NULL;
+
+ g_object_get (connection, "socket", &socket, NULL);
+
+ /* On Linux, we need to turn on SO_PASSCRED if it isn't enabled
+ * already. We also need to turn it off when we're done. See
+ * #617483 for more discussion.
+ */
+#ifdef __linux__
+ {
+ gint opt_val;
+ socklen_t opt_len;
+
+ turn_off_so_passcreds = FALSE;
+ opt_val = 0;
+ opt_len = sizeof (gint);
+ if (getsockopt (g_socket_get_fd (socket),
+ SOL_SOCKET,
+ SO_PASSCRED,
+ &opt_val,
+ &opt_len) != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ _("Error checking if SO_PASSCRED is enabled for socket: %s"),
+ strerror (errno));
+ goto out;
+ }
+ if (opt_len != sizeof (gint))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Unexpected option length while checking if SO_PASSCRED is enabled for socket. "
+ "Expected %d bytes, got %d"),
+ (gint) sizeof (gint), (gint) opt_len);
+ goto out;
+ }
+ if (opt_val == 0)
+ {
+ opt_val = 1;
+ if (setsockopt (g_socket_get_fd (socket),
+ SOL_SOCKET,
+ SO_PASSCRED,
+ &opt_val,
+ sizeof opt_val) != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ _("Error enabling SO_PASSCRED: %s"),
+ strerror (errno));
+ goto out;
+ }
+ turn_off_so_passcreds = TRUE;
+ }
+ }
+#endif
+
+ /* ensure the type of GUnixCredentialsMessage has been registered with the type system */
+ credentials_message_gtype = G_TYPE_UNIX_CREDENTIALS_MESSAGE;
+ num_bytes_read = g_socket_receive_message (socket,
+ NULL, /* GSocketAddress **address */
+ NULL,
+ 0,
+ &scms,
+ &nscm,
+ NULL,
+ cancellable,
+ error);
+ if (num_bytes_read != 1)
+ {
+ /* Handle situation where g_socket_receive_message() returns
+ * 0 bytes and not setting @error
+ */
+ if (num_bytes_read == 0 && error != NULL && *error == NULL)
+ {
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Expecting to read a single byte for receiving credentials but read zero bytes"));
+ }
+ goto out;
+ }
+
+ if (nscm != 1)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Expecting 1 control message, got %d"),
+ nscm);
+ goto out;
+ }
+
+ if (!G_IS_UNIX_CREDENTIALS_MESSAGE (scms[0]))
+ {
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Unexpected type of ancillary data"));
+ goto out;
+ }
+
+ ret = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (scms[0]));
+ g_object_ref (ret);
+
+ out:
+
+#ifdef __linux__
+ if (turn_off_so_passcreds)
+ {
+ gint opt_val;
+ opt_val = 0;
+ if (setsockopt (g_socket_get_fd (socket),
+ SOL_SOCKET,
+ SO_PASSCRED,
+ &opt_val,
+ sizeof opt_val) != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ _("Error while disabling SO_PASSCRED: %s"),
+ strerror (errno));
+ goto out;
+ }
+ }
+#endif
+
+ if (scms != NULL)
+ {
+ for (n = 0; n < nscm; n++)
+ g_object_unref (scms[n]);
+ g_free (scms);
+ }
+ g_object_unref (socket);
+ return ret;
+}
+
#define __G_UNIX_CONNECTION_C__
#include "gioaliasdef.c"
diff --git a/gio/gunixconnection.h b/gio/gunixconnection.h
index 7435e9742..9c691ea0d 100644
--- a/gio/gunixconnection.h
+++ b/gio/gunixconnection.h
@@ -71,6 +71,16 @@ gint g_unix_connection_receive_fd (GUnixCo
GCancellable *cancellable,
GError **error);
+gboolean g_unix_connection_send_credentials (GUnixConnection *connection,
+ GCredentials *credentials,
+ GCancellable *cancellable,
+ GError **error);
+
+GCredentials *g_unix_connection_receive_credentials (GUnixConnection *connection,
+ GCancellable *cancellable,
+ GError **error);
+
+
G_END_DECLS
#endif /* __G_UNIX_CONNECTION_H__ */