From 366b3ffcde4f19cabf8685efdc1ccd20dcade0ca Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 20 May 2010 10:51:00 -0400 Subject: [PATCH] =?UTF-8?q?Bug=20619142=20=E2=80=93=20Build=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix various #include issues - Change #error to #warning for the EXTERNAL authentication mechanism. It is not clear if this should work on Win32 at all. - Call close() before unlink() for the SHA1 keyring - Change #error to #warning so we don't forget to do permission checking of the .dbus-keyrings directory - Use Win32 SID for the SHA1 auth mech - Apparently we can't use word 'interface' as an identifier - Implement a _g_dbus_win32_get_user_sid() function. For now it's private. Don't know if it should be public somewhere. Maybe in a future GCredentials support for Win32? I don't know. - GFileDescriptorBased is not available on Win32. So avoid using it in GLocalFile stuff. Now, Win32 still uses GLocalFile + friends (which works with file descriptors) so expose a private function to get the fd for an OutputStream so things still work. - Fixup gio.symbols - Fixup tests/gdbus-peer.c so it builds With this, at least things compile and the gdbus-peer.exe test case passes. Which is a great start. I've tested this by cross-compiling on a x86_64 Fedora 13 host using mingw32 and running the code on a 32-bit Windows 7 box. https://bugzilla.gnome.org/show_bug.cgi?id=619142 Signed-off-by: David Zeuthen --- gio/gdbusaddress.c | 6 +++ gio/gdbusauth.c | 8 ++-- gio/gdbusauthmechanismexternal.c | 4 +- gio/gdbusauthmechanismsha1.c | 39 ++++++++-------- gio/gdbusconnection.c | 2 + gio/gdbusmessage.c | 20 ++++----- gio/gdbusmessage.h | 4 +- gio/gdbusprivate.c | 76 ++++++++++++++++++++++++++++++++ gio/gdbusprivate.h | 4 ++ gio/gdbusserver.c | 7 +++ gio/gio.symbols | 12 ++++- gio/glocalfileinputstream.c | 20 +++++++-- gio/glocalfileiostream.c | 8 +++- gio/glocalfileoutputstream.c | 30 ++++++++++--- gio/glocalfileoutputstream.h | 6 +++ gio/tests/Makefile.am | 2 +- gio/tests/gdbus-peer.c | 18 ++++++++ 17 files changed, 214 insertions(+), 52 deletions(-) diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c index 5d8fc9c96..364e75809 100644 --- a/gio/gdbusaddress.c +++ b/gio/gdbusaddress.c @@ -25,10 +25,16 @@ #include #include +#include "gioerror.h" #include "gdbusutils.h" #include "gdbusaddress.h" #include "gdbuserror.h" #include "gioenumtypes.h" +#include "gnetworkaddress.h" +#include "gsocketclient.h" +#include "giostream.h" +#include "gasyncresult.h" +#include "gsimpleasyncresult.h" #include "gdbusprivate.h" #ifdef G_OS_UNIX diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c index 35f100a6a..eeced636f 100644 --- a/gio/gdbusauth.c +++ b/gio/gdbusauth.c @@ -22,9 +22,6 @@ #include "config.h" -#include -#include - #include "gdbusauth.h" #include "gdbusauthmechanismanon.h" @@ -37,8 +34,13 @@ #include "gioenumtypes.h" #include "gcredentials.h" #include "gdbusprivate.h" +#include "giostream.h" +#include "gdatainputstream.h" +#include "gdataoutputstream.h" #ifdef G_OS_UNIX +#include +#include #include "gunixconnection.h" #include "gunixcredentialsmessage.h" #endif diff --git a/gio/gdbusauthmechanismexternal.c b/gio/gdbusauthmechanismexternal.c index 9cd3b78cf..46d393147 100644 --- a/gio/gdbusauthmechanismexternal.c +++ b/gio/gdbusauthmechanismexternal.c @@ -352,9 +352,7 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism, #if defined(G_OS_UNIX) initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) g_credentials_get_unix_user (credentials, NULL)); #elif defined(G_OS_WIN32) - initial_response = g_strdup_printf ("%s", g_credentials_get_windows_user ()); -#else -#warning Dont know how to send credentials on this OS. Please implement. +#warning Dont know how to send credentials on this OS. The EXTERNAL D-Bus authentication mechanism will not work. m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED; #endif return initial_response; diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c index 020aaba0d..bca42a845 100644 --- a/gio/gdbusauthmechanismsha1.c +++ b/gio/gdbusauthmechanismsha1.c @@ -37,6 +37,7 @@ #include "gdbuserror.h" #include "gioenumtypes.h" #include "gioerror.h" +#include "gdbusprivate.h" #include "glibintl.h" #include "gioalias.h" @@ -280,7 +281,7 @@ ensure_keyring_directory (GError **error) goto out; } #else -#error Please implement permission checking on non-UNIX platforms +#warning Please implement permission checking on this non-UNIX platform #endif } goto out; @@ -583,16 +584,6 @@ keyring_release_lock (const gchar *path, ret = FALSE; lock = g_strdup_printf ("%s.lock", path); - if (g_unlink (lock) != 0) - { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - _("Error unlinking lock-file `%s': %s"), - lock, - strerror (errno)); - goto out; - } if (close (lock_fd) != 0) { g_set_error (error, @@ -603,6 +594,16 @@ keyring_release_lock (const gchar *path, strerror (errno)); goto out; } + if (g_unlink (lock) != 0) + { + g_set_error (error, + G_IO_ERROR, + g_io_error_from_errno (errno), + _("Error unlinking lock-file `%s': %s"), + lock, + strerror (errno)); + goto out; + } ret = TRUE; @@ -953,11 +954,11 @@ mechanism_server_initiate (GDBusAuthMechanism *mechanism, } } #elif defined(G_OS_WIN32) - GCredentials *credentials; - credentials = g_credentials_new_for_process (); - if (g_strcmp0 (g_credentials_get_windows_user (credentials), initial_response) == 0) + gchar *sid; + sid = _g_dbus_win32_get_user_sid (); + if (g_strcmp0 (initial_response, sid) == 0) m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_HAVE_DATA_TO_SEND; - g_object_unref (credentials); + g_free (sid); #else #error Please implement for your OS #endif @@ -1109,13 +1110,9 @@ mechanism_client_initiate (GDBusAuthMechanism *mechanism, #ifdef G_OS_UNIX initial_response = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) getuid ()); #elif defined (G_OS_WIN32) - { - GCredentials *credentials; - credentials = g_credentials_new_for_process (); - initial_response = g_strdup (g_credentials_get_windows_user (credentials)); - g_object_unref (credentials); - } +initial_response = _g_dbus_win32_get_user_sid (); #else +#error Please implement for your OS #endif g_assert (initial_response != NULL); diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c index 8bd6f38d0..017b2d462 100644 --- a/gio/gdbusconnection.c +++ b/gio/gdbusconnection.c @@ -1815,6 +1815,7 @@ initable_init (GInitable *initable, //g_debug ("haz unix fd passing powers: %d", connection->priv->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING); +#ifdef G_OS_UNIX /* Hack used until * * https://bugzilla.gnome.org/show_bug.cgi?id=616458 @@ -1825,6 +1826,7 @@ initable_init (GInitable *initable, { g_socket_set_blocking (g_socket_connection_get_socket (G_SOCKET_CONNECTION (connection->priv->stream)), FALSE); } +#endif connection->priv->worker = _g_dbus_worker_new (connection->priv->stream, connection->priv->capabilities, diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c index e733bba9d..24d5ef62f 100644 --- a/gio/gdbusmessage.c +++ b/gio/gdbusmessage.c @@ -134,7 +134,7 @@ g_dbus_message_new (void) * g_dbus_message_new_method_call: * @name: A valid D-Bus name or %NULL. * @path: A valid object path. - * @interface: A valid D-Bus interface name or %NULL. + * @interface_: A valid D-Bus interface name or %NULL. * @method: A valid method name. * * Creates a new #GDBusMessage for a method call. @@ -146,7 +146,7 @@ g_dbus_message_new (void) GDBusMessage * g_dbus_message_new_method_call (const gchar *name, const gchar *path, - const gchar *interface, + const gchar *interface_, const gchar *method) { GDBusMessage *message; @@ -154,7 +154,7 @@ g_dbus_message_new_method_call (const gchar *name, g_return_val_if_fail (name == NULL || g_dbus_is_name (name), NULL); g_return_val_if_fail (g_variant_is_object_path (path), NULL); g_return_val_if_fail (g_dbus_is_member_name (method), NULL); - g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL); + g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL); message = g_dbus_message_new (); message->priv->type = G_DBUS_MESSAGE_TYPE_METHOD_CALL; @@ -163,8 +163,8 @@ g_dbus_message_new_method_call (const gchar *name, g_dbus_message_set_destination (message, name); g_dbus_message_set_path (message, path); g_dbus_message_set_member (message, method); - if (interface != NULL) - g_dbus_message_set_interface (message, interface); + if (interface_ != NULL) + g_dbus_message_set_interface (message, interface_); return message; } @@ -172,7 +172,7 @@ g_dbus_message_new_method_call (const gchar *name, /** * g_dbus_message_new_signal: * @path: A valid object path. - * @interface: A valid D-Bus interface name or %NULL. + * @interface_: A valid D-Bus interface name or %NULL. * @signal: A valid signal name. * * Creates a new #GDBusMessage for a signal emission. @@ -183,14 +183,14 @@ g_dbus_message_new_method_call (const gchar *name, */ GDBusMessage * g_dbus_message_new_signal (const gchar *path, - const gchar *interface, + const gchar *interface_, const gchar *signal) { GDBusMessage *message; g_return_val_if_fail (g_variant_is_object_path (path), NULL); g_return_val_if_fail (g_dbus_is_member_name (signal), NULL); - g_return_val_if_fail (interface == NULL || g_dbus_is_interface_name (interface), NULL); + g_return_val_if_fail (interface_ == NULL || g_dbus_is_interface_name (interface_), NULL); message = g_dbus_message_new (); message->priv->type = G_DBUS_MESSAGE_TYPE_SIGNAL; @@ -199,8 +199,8 @@ g_dbus_message_new_signal (const gchar *path, g_dbus_message_set_path (message, path); g_dbus_message_set_member (message, signal); - if (interface != NULL) - g_dbus_message_set_interface (message, interface); + if (interface_ != NULL) + g_dbus_message_set_interface (message, interface_); return message; } diff --git a/gio/gdbusmessage.h b/gio/gdbusmessage.h index b77440917..af3fdfd48 100644 --- a/gio/gdbusmessage.h +++ b/gio/gdbusmessage.h @@ -68,11 +68,11 @@ struct _GDBusMessage GType g_dbus_message_get_type (void) G_GNUC_CONST; GDBusMessage *g_dbus_message_new (void); GDBusMessage *g_dbus_message_new_signal (const gchar *path, - const gchar *interface, + const gchar *interface_, const gchar *signal); GDBusMessage *g_dbus_message_new_method_call (const gchar *name, const gchar *path, - const gchar *interface, + const gchar *interface_, const gchar *method); GDBusMessage *g_dbus_message_new_method_reply (GDBusMessage *method_call_message); GDBusMessage *g_dbus_message_new_method_error (GDBusMessage *method_call_message, diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c index d85c97f79..186ba7f58 100644 --- a/gio/gdbusprivate.c +++ b/gio/gdbusprivate.c @@ -39,6 +39,7 @@ #include "ginputstream.h" #include "giostream.h" #include "gsocketcontrolmessage.h" +#include "gsocketconnection.h" #ifdef G_OS_UNIX #include "gunixfdmessage.h" @@ -46,6 +47,10 @@ #include "gunixcredentialsmessage.h" #endif +#ifdef G_OS_WIN32 +#include +#endif + #include "glibintl.h" #include "gioalias.h" @@ -588,11 +593,13 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream, goto out; } +#ifdef G_OS_UNIX if (worker->read_fd_list != NULL) { g_dbus_message_set_unix_fd_list (message, worker->read_fd_list); worker->read_fd_list = NULL; } +#endif if (G_UNLIKELY (_g_dbus_debug_message ())) { @@ -1049,5 +1056,74 @@ _g_dbus_compute_complete_signature (GDBusArgInfo **args, return g_string_free (s, FALSE); } +/* ---------------------------------------------------------------------------------------------------- */ + +#ifdef G_OS_WIN32 + +extern BOOL WINAPI ConvertSidToStringSidA (PSID Sid, LPSTR *StringSid); + +gchar * +_g_dbus_win32_get_user_sid (void) +{ + HANDLE h; + TOKEN_USER *user; + DWORD token_information_len; + PSID psid; + gchar *sid; + gchar *ret; + + ret = NULL; + user = NULL; + h = INVALID_HANDLE_VALUE; + + if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &h)) + { + g_warning ("OpenProcessToken failed with error code %d", (gint) GetLastError ()); + goto out; + } + + /* Get length of buffer */ + token_information_len = 0; + if (!GetTokenInformation (h, TokenUser, NULL, 0, &token_information_len)) + { + if (GetLastError () != ERROR_INSUFFICIENT_BUFFER) + { + g_warning ("GetTokenInformation() failed with error code %d", (gint) GetLastError ()); + goto out; + } + } + user = g_malloc (token_information_len); + if (!GetTokenInformation (h, TokenUser, user, token_information_len, &token_information_len)) + { + g_warning ("GetTokenInformation() failed with error code %d", (gint) GetLastError ()); + goto out; + } + + psid = user->User.Sid; + if (!IsValidSid (psid)) + { + g_warning ("Invalid SID"); + goto out; + } + + if (!ConvertSidToStringSidA (psid, &sid)) + { + g_warning ("Invalid SID"); + goto out; + } + + ret = g_strdup (sid); + LocalFree (sid); + +out: + g_free (user); + if (h != INVALID_HANDLE_VALUE) + CloseHandle (h); + return ret; +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + #define __G_DBUS_PRIVATE_C__ #include "gioaliasdef.c" diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h index 37cc03d56..09ec56d62 100644 --- a/gio/gdbusprivate.h +++ b/gio/gdbusprivate.h @@ -78,6 +78,10 @@ gchar * _g_dbus_compute_complete_signature (GDBusArgInfo **args, /* ---------------------------------------------------------------------------------------------------- */ +#ifdef G_OS_WIN32 +gchar *_g_dbus_win32_get_user_sid (void); +#endif + G_END_DECLS #endif /* __G_DBUS_PRIVATE_H__ */ diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c index cb1c59543..008f85dc6 100644 --- a/gio/gdbusserver.c +++ b/gio/gdbusserver.c @@ -30,6 +30,7 @@ #endif #include "giotypes.h" +#include "gioerror.h" #include "gdbusaddress.h" #include "gdbusutils.h" #include "gdbusconnection.h" @@ -40,6 +41,12 @@ #include "gio-marshal.h" #include "ginitable.h" #include "gsocketservice.h" +#include "gthreadedsocketservice.h" +#include "gresolver.h" +#include "ginetaddress.h" +#include "ginetsocketaddress.h" +#include "ginputstream.h" +#include "giostream.h" #ifdef G_OS_UNIX #include "gunixsocketaddress.h" diff --git a/gio/gio.symbols b/gio/gio.symbols index c7adc7ccc..8aebd4450 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -1390,10 +1390,12 @@ g_zlib_decompressor_new #if IN_HEADER(__G_FILE_DESCRIPTOR_BASED_H__) #if IN_FILE(__G_FILE_DESCRIPTOR_BASED_C__) +#ifdef G_OS_UNIX g_file_descriptor_based_get_type G_GNUC_CONST g_file_descriptor_based_get_fd #endif #endif +#endif #if IN_HEADER(__G_SETTINGS_BACKEND_H__) #if IN_FILE(__G_KEYFILE_SETTINGS_BACKEND_C__) @@ -1455,10 +1457,12 @@ g_credentials_to_string g_credentials_get_native g_credentials_set_native g_credentials_is_same_user +#ifdef G_OS_UNIX g_credentials_get_unix_user g_credentials_set_unix_user #endif #endif +#endif #if IN_HEADER(__G_DBUS_ADDRESS_H__) #if IN_FILE(__G_DBUS_ADDRESS_C__) @@ -1597,7 +1601,6 @@ g_dbus_message_get_sender g_dbus_message_get_serial g_dbus_message_get_signature g_dbus_message_get_message_type -g_dbus_message_get_unix_fd_list g_dbus_message_print g_dbus_message_set_body g_dbus_message_set_destination @@ -1613,9 +1616,12 @@ g_dbus_message_set_sender g_dbus_message_set_serial g_dbus_message_set_signature g_dbus_message_set_message_type -g_dbus_message_set_unix_fd_list g_dbus_message_to_blob g_dbus_message_to_gerror +#ifdef G_OS_UNIX +g_dbus_message_get_unix_fd_list +g_dbus_message_set_unix_fd_list +#endif #endif #endif @@ -1715,6 +1721,7 @@ g_dbus_is_unique_name #if IN_HEADER(__G_UNIX_CREDENTIALS_MESSAGE_H__) #if IN_FILE(__G_UNIX_CREDENTIALS_MESSAGE_C__) +#ifdef G_OS_UNIX g_unix_credentials_message_get_type G_GNUC_CONST g_unix_credentials_message_new g_unix_credentials_message_new_with_credentials @@ -1722,3 +1729,4 @@ g_unix_credentials_message_get_credentials g_unix_credentials_message_is_supported #endif #endif +#endif diff --git a/gio/glocalfileinputstream.c b/gio/glocalfileinputstream.c index 2411ceb3e..646daefe5 100644 --- a/gio/glocalfileinputstream.c +++ b/gio/glocalfileinputstream.c @@ -33,12 +33,15 @@ #include #include #include "gcancellable.h" -#include "gfiledescriptorbased.h" #include "gioerror.h" #include "glocalfileinputstream.h" #include "glocalfileinfo.h" #include "glibintl.h" +#ifdef G_OS_UNIX +#include "gfiledescriptorbased.h" +#endif + #ifdef G_OS_WIN32 #include #endif @@ -46,11 +49,17 @@ #include "gioalias.h" +#ifdef G_OS_UNIX static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + #define g_local_file_input_stream_get_type _g_local_file_input_stream_get_type G_DEFINE_TYPE_WITH_CODE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM, +#ifdef G_OS_UNIX G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, - g_file_descriptor_based_iface_init)); + g_file_descriptor_based_iface_init) +#endif +); struct _GLocalFileInputStreamPrivate { int fd; @@ -80,7 +89,9 @@ static GFileInfo *g_local_file_input_stream_query_info (GFileInputStream *strea const char *attributes, GCancellable *cancellable, GError **error); +#ifdef G_OS_UNIX static int g_local_file_input_stream_get_fd (GFileDescriptorBased *stream); +#endif static void g_local_file_input_stream_finalize (GObject *object) @@ -115,11 +126,13 @@ g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass) file_stream_class->query_info = g_local_file_input_stream_query_info; } +#ifdef G_OS_UNIX static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) { iface->get_fd = g_local_file_input_stream_get_fd; } +#endif static void g_local_file_input_stream_init (GLocalFileInputStream *info) @@ -349,10 +362,11 @@ g_local_file_input_stream_query_info (GFileInputStream *stream, error); } +#ifdef G_OS_UNIX static int g_local_file_input_stream_get_fd (GFileDescriptorBased *fd_based) { GLocalFileInputStream *stream = G_LOCAL_FILE_INPUT_STREAM (fd_based); return stream->priv->fd; } - +#endif diff --git a/gio/glocalfileiostream.c b/gio/glocalfileiostream.c index e1f295c5a..5a421ddb8 100644 --- a/gio/glocalfileiostream.c +++ b/gio/glocalfileiostream.c @@ -27,11 +27,14 @@ #include "glibintl.h" #include "gioerror.h" #include "gcancellable.h" -#include "gfiledescriptorbased.h" #include "glocalfileiostream.h" #include "glocalfileinputstream.h" #include "glocalfileinfo.h" +#ifdef G_OS_UNIX +#include "gfiledescriptorbased.h" +#endif + #include "gioalias.h" #define g_local_file_io_stream_get_type _g_local_file_io_stream_get_type @@ -59,8 +62,9 @@ _g_local_file_io_stream_new (GLocalFileOutputStream *output_stream) stream = g_object_new (G_TYPE_LOCAL_FILE_IO_STREAM, NULL); stream->output_stream = g_object_ref (output_stream); _g_local_file_output_stream_set_do_close (output_stream, FALSE); - fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (output_stream)); + fd = _g_local_file_output_stream_get_fd (output_stream); stream->input_stream = (GInputStream *)_g_local_file_input_stream_new (fd); + _g_local_file_input_stream_set_do_close (G_LOCAL_FILE_INPUT_STREAM (stream->input_stream), FALSE); diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c index f870d7b5d..7916b0302 100644 --- a/gio/glocalfileoutputstream.c +++ b/gio/glocalfileoutputstream.c @@ -36,10 +36,13 @@ #include "glibintl.h" #include "gioerror.h" #include "gcancellable.h" -#include "gfiledescriptorbased.h" #include "glocalfileoutputstream.h" #include "glocalfileinfo.h" +#ifdef G_OS_UNIX +#include "gfiledescriptorbased.h" +#endif + #ifdef G_OS_WIN32 #include #ifndef S_ISDIR @@ -56,11 +59,17 @@ #include "gioalias.h" +#ifdef G_OS_UNIX static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface); +#endif + #define g_local_file_output_stream_get_type _g_local_file_output_stream_get_type G_DEFINE_TYPE_WITH_CODE (GLocalFileOutputStream, g_local_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM, +#ifdef G_OS_UNIX G_IMPLEMENT_INTERFACE (G_TYPE_FILE_DESCRIPTOR_BASED, - g_file_descriptor_based_iface_init)); + g_file_descriptor_based_iface_init) +#endif + ); /* Some of the file replacement code was based on the code from gedit, @@ -104,7 +113,9 @@ static gboolean g_local_file_output_stream_truncate (GFileOutputStream *s goffset size, GCancellable *cancellable, GError **error); +#ifdef G_OS_UNIX static int g_local_file_output_stream_get_fd (GFileDescriptorBased *stream); +#endif static void g_local_file_output_stream_finalize (GObject *object) @@ -144,11 +155,13 @@ g_local_file_output_stream_class_init (GLocalFileOutputStreamClass *klass) file_stream_class->truncate_fn = g_local_file_output_stream_truncate; } +#ifdef G_OS_UNIX static void g_file_descriptor_based_iface_init (GFileDescriptorBasedIface *iface) { iface->get_fd = g_local_file_output_stream_get_fd; } +#endif static void g_local_file_output_stream_init (GLocalFileOutputStream *stream) @@ -1159,11 +1172,18 @@ _g_local_file_output_stream_replace (const char *filename, return G_FILE_OUTPUT_STREAM (stream); } +gint +_g_local_file_output_stream_get_fd (GLocalFileOutputStream *stream) +{ + g_return_val_if_fail (G_IS_LOCAL_FILE_OUTPUT_STREAM (stream), -1); + return stream->priv->fd; +} + +#ifdef G_OS_UNIX static int g_local_file_output_stream_get_fd (GFileDescriptorBased *fd_based) { GLocalFileOutputStream *stream = G_LOCAL_FILE_OUTPUT_STREAM (fd_based); - - return stream->priv->fd; + return _g_local_file_output_stream_get_fd (stream); } - +#endif diff --git a/gio/glocalfileoutputstream.h b/gio/glocalfileoutputstream.h index a8ec7363f..831c37f12 100644 --- a/gio/glocalfileoutputstream.h +++ b/gio/glocalfileoutputstream.h @@ -80,6 +80,12 @@ GFileOutputStream * _g_local_file_output_stream_replace (const char *file GCancellable *cancellable, GError **error); +/* Hack to get the fd since GFileDescriptorBased (which is how you + * _should_ get the fd) is only available on UNIX but things like + * win32 needs this as well + */ +gint _g_local_file_output_stream_get_fd (GLocalFileOutputStream *output_stream); + G_END_DECLS #endif /* __G_LOCAL_FILE_OUTPUT_STREAM_H__ */ diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index f4b3e0d42..a534722a9 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -210,7 +210,7 @@ gdbus_export_LDADD = $(progs_ldadd) gdbus_error_SOURCES = gdbus-error.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c gdbus_error_LDADD = $(progs_ldadd) -gdbus_peer_SOURCES = gdbus-peer.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c +gdbus_peer_SOURCES = gdbus-peer.c gdbus-tests.h gdbus-tests.c gdbus_peer_LDADD = $(progs_ldadd) gdbus_exit_on_close_SOURCES = gdbus-exit-on-close.c gdbus-sessionbus.c gdbus-sessionbus.h gdbus-tests.h gdbus-tests.c diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index abea94849..97f030840 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -126,6 +126,7 @@ test_interface_method_call (GDBusConnection *connection, } else if (g_strcmp0 (method_name, "OpenFile") == 0) { +#ifdef G_OS_UNIX const gchar *path; GDBusMessage *reply; GError *error; @@ -154,6 +155,11 @@ test_interface_method_call (GDBusConnection *connection, &error); g_assert_no_error (error); g_object_unref (reply); +#else + g_dbus_method_invocation_return_dbus_error (invocation, + "org.gtk.GDBus.NotOnUnix", + "Your OS does not support file descriptor passing"); +#endif } else { @@ -617,6 +623,18 @@ test_peer (void) g_assert_cmpstr (buf, ==, buf2); g_free (buf2); } +#else + error = NULL; + result = g_dbus_proxy_call_sync (proxy, + "OpenFile", + g_variant_new ("(s)", "boo"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + &error); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); + g_assert (result == NULL); + g_error_free (error); #endif /* G_OS_UNIX */