mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-28 00:16:15 +01:00
Merge branch 'win32-afunix' into 'main'
gio: Add some AF_UNIX support on Windows Closes #2487 See merge request GNOME/glib!2445
This commit is contained in:
commit
70c116e602
@ -38,6 +38,7 @@ if get_option('gtk_doc')
|
|||||||
'ghttpproxy.h',
|
'ghttpproxy.h',
|
||||||
'giomodule-priv.h',
|
'giomodule-priv.h',
|
||||||
'gioprivate.h',
|
'gioprivate.h',
|
||||||
|
'giowin32-afunix.h',
|
||||||
'giowin32-priv.h',
|
'giowin32-priv.h',
|
||||||
'gio_probes.h',
|
'gio_probes.h',
|
||||||
'gio_trace.h',
|
'gio_trace.h',
|
||||||
@ -107,14 +108,11 @@ if get_option('gtk_doc')
|
|||||||
if host_system == 'windows'
|
if host_system == 'windows'
|
||||||
ignore_headers += [
|
ignore_headers += [
|
||||||
'gfiledescriptorbased.h',
|
'gfiledescriptorbased.h',
|
||||||
'gunixconnection.h',
|
|
||||||
'gunixcredentialsmessage.h',
|
|
||||||
'gunixmounts.h',
|
'gunixmounts.h',
|
||||||
'gunixfdlist.h',
|
'gunixfdlist.h',
|
||||||
'gunixfdmessage.h',
|
'gunixfdmessage.h',
|
||||||
'gunixinputstream.h',
|
'gunixinputstream.h',
|
||||||
'gunixoutputstream.h',
|
'gunixoutputstream.h',
|
||||||
'gunixsocketaddress.h',
|
|
||||||
'gdesktopappinfo.h',
|
'gdesktopappinfo.h',
|
||||||
'gosxappinfo.h',
|
'gosxappinfo.h',
|
||||||
]
|
]
|
||||||
|
@ -72,6 +72,9 @@
|
|||||||
* On Solaris (including OpenSolaris and its derivatives), the native
|
* On Solaris (including OpenSolaris and its derivatives), the native
|
||||||
* credential type is a `ucred_t`. This corresponds to
|
* credential type is a `ucred_t`. This corresponds to
|
||||||
* %G_CREDENTIALS_TYPE_SOLARIS_UCRED.
|
* %G_CREDENTIALS_TYPE_SOLARIS_UCRED.
|
||||||
|
*
|
||||||
|
* Since GLib 2.72, on Windows, the native credentials may contain the PID of a
|
||||||
|
* process. This corresponds to %G_CREDENTIALS_TYPE_WIN32_PID.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,6 +103,8 @@ struct _GCredentials
|
|||||||
struct sockpeercred native;
|
struct sockpeercred native;
|
||||||
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
ucred_t *native;
|
ucred_t *native;
|
||||||
|
#elif G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
DWORD native;
|
||||||
#else
|
#else
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
@ -188,6 +193,8 @@ g_credentials_init (GCredentials *credentials)
|
|||||||
credentials->native.gid = getegid ();
|
credentials->native.gid = getegid ();
|
||||||
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
credentials->native = ucred_get (P_MYID);
|
credentials->native = ucred_get (P_MYID);
|
||||||
|
#elif G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
credentials->native = GetCurrentProcessId ();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +300,8 @@ g_credentials_to_string (GCredentials *credentials)
|
|||||||
if (ret->str[ret->len - 1] == ',')
|
if (ret->str[ret->len - 1] == ',')
|
||||||
ret->str[ret->len - 1] = '\0';
|
ret->str[ret->len - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
#elif G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
g_string_append_printf (ret, "win32-pid:pid=%lu", credentials->native);
|
||||||
#else
|
#else
|
||||||
g_string_append (ret, "unknown");
|
g_string_append (ret, "unknown");
|
||||||
#endif
|
#endif
|
||||||
@ -600,6 +609,8 @@ g_credentials_get_unix_pid (GCredentials *credentials,
|
|||||||
ret = credentials->native.pid;
|
ret = credentials->native.pid;
|
||||||
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
ret = ucred_getpid (credentials->native);
|
ret = ucred_getpid (credentials->native);
|
||||||
|
#elif G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
ret = credentials->native;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#if G_CREDENTIALS_USE_APPLE_XUCRED
|
#if G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
|
#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
|
||||||
#undef G_CREDENTIALS_USE_SOLARIS_UCRED
|
#undef G_CREDENTIALS_USE_SOLARIS_UCRED
|
||||||
#undef G_CREDENTIALS_USE_APPLE_XUCRED
|
#undef G_CREDENTIALS_USE_APPLE_XUCRED
|
||||||
|
#undef G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* G_CREDENTIALS_NATIVE_TYPE:
|
* G_CREDENTIALS_NATIVE_TYPE:
|
||||||
@ -171,6 +172,14 @@
|
|||||||
void _g_credentials_set_local_peerid (GCredentials *credentials,
|
void _g_credentials_set_local_peerid (GCredentials *credentials,
|
||||||
pid_t pid);
|
pid_t pid);
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define G_CREDENTIALS_SUPPORTED 1
|
||||||
|
#define G_CREDENTIALS_USE_WIN32_PID 1
|
||||||
|
#define G_CREDENTIALS_NATIVE_TYPE G_CREDENTIALS_TYPE_WIN32_PID
|
||||||
|
#define G_CREDENTIALS_NATIVE_SIZE (sizeof (DWORD))
|
||||||
|
#define G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED 1
|
||||||
|
#define G_CREDENTIALS_HAS_PID 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __G_CREDENTIALS_PRIVATE_H__ */
|
#endif /* __G_CREDENTIALS_PRIVATE_H__ */
|
||||||
|
@ -40,12 +40,12 @@
|
|||||||
#include "gdbusprivate.h"
|
#include "gdbusprivate.h"
|
||||||
#include "gstdio.h"
|
#include "gstdio.h"
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <gio/gunixsocketaddress.h>
|
#include <gio/gunixsocketaddress.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@ -66,6 +66,9 @@
|
|||||||
*
|
*
|
||||||
* TCP D-Bus connections are supported, but accessing them via a proxy is
|
* TCP D-Bus connections are supported, but accessing them via a proxy is
|
||||||
* currently not supported.
|
* currently not supported.
|
||||||
|
*
|
||||||
|
* Since GLib 2.72, `unix:` addresses are supported on Windows with `AF_UNIX`
|
||||||
|
* support (Windows 10).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static gchar *get_session_address_platform_specific (GError **error);
|
static gchar *get_session_address_platform_specific (GError **error);
|
||||||
@ -571,11 +574,7 @@ g_dbus_address_connect (const gchar *address_entry,
|
|||||||
ret = NULL;
|
ret = NULL;
|
||||||
nonce_file = NULL;
|
nonce_file = NULL;
|
||||||
|
|
||||||
if (FALSE)
|
if (g_strcmp0 (transport_name, "unix") == 0)
|
||||||
{
|
|
||||||
}
|
|
||||||
#ifdef G_OS_UNIX
|
|
||||||
else if (g_strcmp0 (transport_name, "unix") == 0)
|
|
||||||
{
|
{
|
||||||
const gchar *path;
|
const gchar *path;
|
||||||
const gchar *abstract;
|
const gchar *abstract;
|
||||||
@ -605,7 +604,6 @@ g_dbus_address_connect (const gchar *address_entry,
|
|||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0)
|
else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0)
|
||||||
{
|
{
|
||||||
const gchar *s;
|
const gchar *s;
|
||||||
|
@ -1441,6 +1441,7 @@ typedef enum
|
|||||||
* @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40.
|
* @G_CREDENTIALS_TYPE_SOLARIS_UCRED: The native credentials type is a `ucred_t`. Added in 2.40.
|
||||||
* @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42.
|
* @G_CREDENTIALS_TYPE_NETBSD_UNPCBID: The native credentials type is a `struct unpcbid`. Added in 2.42.
|
||||||
* @G_CREDENTIALS_TYPE_APPLE_XUCRED: The native credentials type is a `struct xucred`. Added in 2.66.
|
* @G_CREDENTIALS_TYPE_APPLE_XUCRED: The native credentials type is a `struct xucred`. Added in 2.66.
|
||||||
|
* @G_CREDENTIALS_TYPE_WIN32_PID: The native credentials type is a PID `DWORD`. Added in 2.72.
|
||||||
*
|
*
|
||||||
* Enumeration describing different kinds of native credential types.
|
* Enumeration describing different kinds of native credential types.
|
||||||
*
|
*
|
||||||
@ -1455,6 +1456,7 @@ typedef enum
|
|||||||
G_CREDENTIALS_TYPE_SOLARIS_UCRED,
|
G_CREDENTIALS_TYPE_SOLARIS_UCRED,
|
||||||
G_CREDENTIALS_TYPE_NETBSD_UNPCBID,
|
G_CREDENTIALS_TYPE_NETBSD_UNPCBID,
|
||||||
G_CREDENTIALS_TYPE_APPLE_XUCRED,
|
G_CREDENTIALS_TYPE_APPLE_XUCRED,
|
||||||
|
G_CREDENTIALS_TYPE_WIN32_PID,
|
||||||
} GCredentialsType;
|
} GCredentialsType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
40
gio/giowin32-afunix.h
Normal file
40
gio/giowin32-afunix.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* GIO - GLib Input, Output and Streaming Library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General
|
||||||
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GIOWIN32_AFUNIX_H_
|
||||||
|
#define GIOWIN32_AFUNIX_H_
|
||||||
|
|
||||||
|
#ifdef HAVE_AFUNIX_H
|
||||||
|
#include <afunix.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback definitions of things we need in afunix.h, if not available from the
|
||||||
|
* used Windows SDK or MinGW headers.
|
||||||
|
*/
|
||||||
|
#define UNIX_PATH_MAX 108
|
||||||
|
|
||||||
|
typedef struct sockaddr_un {
|
||||||
|
ADDRESS_FAMILY sun_family;
|
||||||
|
char sun_path[UNIX_PATH_MAX];
|
||||||
|
} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||||
|
|
||||||
|
#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GIOWIN32_AFUNIX_H_*/
|
@ -76,6 +76,10 @@
|
|||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
#include "gioprivate.h"
|
#include "gioprivate.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include "giowin32-afunix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gsocket
|
* SECTION:gsocket
|
||||||
* @short_description: Low-level socket object
|
* @short_description: Low-level socket object
|
||||||
@ -3997,6 +4001,9 @@ socket_source_dispatch (GSource *source,
|
|||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
if ((socket_source->pollfd.revents & G_IO_NVAL) != 0)
|
||||||
|
events = G_IO_NVAL;
|
||||||
|
else
|
||||||
events = update_condition (socket_source->socket);
|
events = update_condition (socket_source->socket);
|
||||||
#else
|
#else
|
||||||
if (g_socket_is_closed (socket_source->socket))
|
if (g_socket_is_closed (socket_source->socket))
|
||||||
@ -6126,6 +6133,23 @@ g_socket_get_credentials (GSocket *socket,
|
|||||||
ucred_free (ucred);
|
ucred_free (ucred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif G_CREDENTIALS_USE_WIN32_PID
|
||||||
|
{
|
||||||
|
DWORD peerid, drc;
|
||||||
|
|
||||||
|
if (WSAIoctl (socket->priv->fd, SIO_AF_UNIX_GETPEERPID,
|
||||||
|
NULL, 0U,
|
||||||
|
&peerid, sizeof(peerid),
|
||||||
|
/* Windows bug: always 0 https://github.com/microsoft/WSL/issues/4676 */
|
||||||
|
&drc,
|
||||||
|
NULL, NULL) == 0)
|
||||||
|
{
|
||||||
|
ret = g_credentials_new ();
|
||||||
|
g_credentials_set_native (ret,
|
||||||
|
G_CREDENTIALS_TYPE_WIN32_PID,
|
||||||
|
&peerid);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error "G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED is set but this is no code for this platform"
|
#error "G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED is set but this is no code for this platform"
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,8 +35,10 @@
|
|||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
#include "gioenumtypes.h"
|
#include "gioenumtypes.h"
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
|
||||||
#include "gunixsocketaddress.h"
|
#include "gunixsocketaddress.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include "giowin32-afunix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -265,7 +267,6 @@ g_socket_address_new_from_native (gpointer native,
|
|||||||
return sockaddr;
|
return sockaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
|
||||||
if (family == AF_UNIX)
|
if (family == AF_UNIX)
|
||||||
{
|
{
|
||||||
struct sockaddr_un *addr = (struct sockaddr_un *) native;
|
struct sockaddr_un *addr = (struct sockaddr_un *) native;
|
||||||
@ -299,7 +300,6 @@ g_socket_address_new_from_native (gpointer native,
|
|||||||
else
|
else
|
||||||
return g_unix_socket_address_new (addr->sun_path);
|
return g_unix_socket_address_new (addr->sun_path);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return g_native_socket_address_new (native, len);
|
return g_native_socket_address_new (native, len);
|
||||||
}
|
}
|
||||||
|
@ -615,9 +615,7 @@ g_socket_connection_factory_register_type (GType g_type,
|
|||||||
static void
|
static void
|
||||||
init_builtin_types (void)
|
init_builtin_types (void)
|
||||||
{
|
{
|
||||||
#ifndef G_OS_WIN32
|
|
||||||
g_type_ensure (G_TYPE_UNIX_CONNECTION);
|
g_type_ensure (G_TYPE_UNIX_CONNECTION);
|
||||||
#endif
|
|
||||||
g_type_ensure (G_TYPE_TCP_CONNECTION);
|
g_type_ensure (G_TYPE_TCP_CONNECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gunixconnection
|
* SECTION:gunixconnection
|
||||||
@ -39,9 +41,12 @@
|
|||||||
* It contains functions to do some of the UNIX socket specific
|
* It contains functions to do some of the UNIX socket specific
|
||||||
* functionality like passing file descriptors.
|
* functionality like passing file descriptors.
|
||||||
*
|
*
|
||||||
* Note that `<gio/gunixconnection.h>` belongs to the UNIX-specific
|
* Since GLib 2.72, #GUnixConnection is available on all platforms. It requires
|
||||||
* GIO interfaces, thus you have to use the `gio-unix-2.0.pc`
|
* underlying system support (such as Windows 10 with `AF_UNIX`) at run time.
|
||||||
* pkg-config file when using it.
|
*
|
||||||
|
* Before GLib 2.72, `<gio/gunixconnection.h>` belonged to the UNIX-specific GIO
|
||||||
|
* interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file when
|
||||||
|
* using it. This is no longer necessary since GLib 2.72.
|
||||||
*
|
*
|
||||||
* Since: 2.22
|
* Since: 2.22
|
||||||
*/
|
*/
|
||||||
@ -86,6 +91,7 @@ g_unix_connection_send_fd (GUnixConnection *connection,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
GSocketControlMessage *scm;
|
GSocketControlMessage *scm;
|
||||||
GSocket *socket;
|
GSocket *socket;
|
||||||
|
|
||||||
@ -114,6 +120,11 @@ g_unix_connection_send_fd (GUnixConnection *connection,
|
|||||||
g_object_unref (scm);
|
g_object_unref (scm);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
#else
|
||||||
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
_("Sending FD is not supported"));
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,6 +150,7 @@ g_unix_connection_receive_fd (GUnixConnection *connection,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
GSocketControlMessage **scms;
|
GSocketControlMessage **scms;
|
||||||
gint *fds, nfd, fd, nscm;
|
gint *fds, nfd, fd, nscm;
|
||||||
GUnixFDMessage *fdmsg;
|
GUnixFDMessage *fdmsg;
|
||||||
@ -221,6 +233,11 @@ g_unix_connection_receive_fd (GUnixConnection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
|
#else
|
||||||
|
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
_("Receiving FD is not supported"));
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -31,6 +31,14 @@
|
|||||||
* g_unix_connection_receive_credentials(). To receive credentials of
|
* g_unix_connection_receive_credentials(). To receive credentials of
|
||||||
* a foreign process connected to a socket, use
|
* a foreign process connected to a socket, use
|
||||||
* g_socket_get_credentials().
|
* g_socket_get_credentials().
|
||||||
|
*
|
||||||
|
* Since GLib 2.72, #GUnixCredentialMessage is available on all platforms. It
|
||||||
|
* requires underlying system support (such as Windows 10 with `AF_UNIX`) at run
|
||||||
|
* time.
|
||||||
|
*
|
||||||
|
* Before GLib 2.72, `<gio/gunixcredentialsmessage.h>` belonged to the UNIX-specific
|
||||||
|
* GIO interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file
|
||||||
|
* when using it. This is no longer necessary since GLib 2.72.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -40,7 +48,9 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "gunixcredentialsmessage.h"
|
#include "gunixcredentialsmessage.h"
|
||||||
#include "gcredentials.h"
|
#include "gcredentials.h"
|
||||||
|
@ -28,6 +28,9 @@
|
|||||||
#include "glibintl.h"
|
#include "glibintl.h"
|
||||||
#include "gnetworking.h"
|
#include "gnetworking.h"
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include "giowin32-afunix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:gunixsocketaddress
|
* SECTION:gunixsocketaddress
|
||||||
@ -45,9 +48,13 @@
|
|||||||
* errors. You can use g_unix_socket_address_abstract_names_supported()
|
* errors. You can use g_unix_socket_address_abstract_names_supported()
|
||||||
* to see if abstract names are supported.
|
* to see if abstract names are supported.
|
||||||
*
|
*
|
||||||
* Note that `<gio/gunixsocketaddress.h>` belongs to the UNIX-specific GIO
|
* Since GLib 2.72, #GUnixSocketAddress is available on all platforms. It
|
||||||
* interfaces, thus you have to use the `gio-unix-2.0.pc` pkg-config file
|
* requires underlying system support (such as Windows 10 with `AF_UNIX`) at
|
||||||
* when using it.
|
* run time.
|
||||||
|
*
|
||||||
|
* Before GLib 2.72, `<gio/gunixsocketaddress.h>` belonged to the UNIX-specific
|
||||||
|
* GIO interfaces, thus you had to use the `gio-unix-2.0.pc` pkg-config file
|
||||||
|
* when using it. This is no longer necessary since GLib 2.72.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,13 +346,10 @@ if host_system != 'windows'
|
|||||||
unix_sources = files(
|
unix_sources = files(
|
||||||
'gfiledescriptorbased.c',
|
'gfiledescriptorbased.c',
|
||||||
'giounix-private.c',
|
'giounix-private.c',
|
||||||
'gunixconnection.c',
|
|
||||||
'gunixcredentialsmessage.c',
|
|
||||||
'gunixfdlist.c',
|
'gunixfdlist.c',
|
||||||
'gunixfdmessage.c',
|
'gunixfdmessage.c',
|
||||||
'gunixmount.c',
|
'gunixmount.c',
|
||||||
'gunixmounts.c',
|
'gunixmounts.c',
|
||||||
'gunixsocketaddress.c',
|
|
||||||
'gunixvolume.c',
|
'gunixvolume.c',
|
||||||
'gunixvolumemonitor.c',
|
'gunixvolumemonitor.c',
|
||||||
'gunixinputstream.c',
|
'gunixinputstream.c',
|
||||||
@ -376,14 +373,11 @@ if host_system != 'windows'
|
|||||||
|
|
||||||
gio_unix_include_headers = files(
|
gio_unix_include_headers = files(
|
||||||
'gfiledescriptorbased.h',
|
'gfiledescriptorbased.h',
|
||||||
'gunixconnection.h',
|
|
||||||
'gunixcredentialsmessage.h',
|
|
||||||
'gunixmounts.h',
|
'gunixmounts.h',
|
||||||
'gunixfdlist.h',
|
'gunixfdlist.h',
|
||||||
'gunixfdmessage.h',
|
'gunixfdmessage.h',
|
||||||
'gunixinputstream.h',
|
'gunixinputstream.h',
|
||||||
'gunixoutputstream.h',
|
'gunixoutputstream.h',
|
||||||
'gunixsocketaddress.h',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if glib_have_cocoa
|
if glib_have_cocoa
|
||||||
@ -569,6 +563,9 @@ gio_sources = files(
|
|||||||
'gdtlsclientconnection.c',
|
'gdtlsclientconnection.c',
|
||||||
'gdtlsserverconnection.c',
|
'gdtlsserverconnection.c',
|
||||||
'gunionvolumemonitor.c',
|
'gunionvolumemonitor.c',
|
||||||
|
'gunixconnection.c',
|
||||||
|
'gunixcredentialsmessage.c',
|
||||||
|
'gunixsocketaddress.c',
|
||||||
'gvfs.c',
|
'gvfs.c',
|
||||||
'gvolume.c',
|
'gvolume.c',
|
||||||
'gvolumemonitor.c',
|
'gvolumemonitor.c',
|
||||||
@ -704,6 +701,9 @@ gio_headers = files(
|
|||||||
'gdtlsconnection.h',
|
'gdtlsconnection.h',
|
||||||
'gdtlsclientconnection.h',
|
'gdtlsclientconnection.h',
|
||||||
'gdtlsserverconnection.h',
|
'gdtlsserverconnection.h',
|
||||||
|
'gunixconnection.h',
|
||||||
|
'gunixcredentialsmessage.h',
|
||||||
|
'gunixsocketaddress.h',
|
||||||
'gvfs.h',
|
'gvfs.h',
|
||||||
'gvolume.h',
|
'gvolume.h',
|
||||||
'gvolumemonitor.h',
|
'gvolumemonitor.h',
|
||||||
|
@ -25,6 +25,28 @@
|
|||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gio/gcredentialsprivate.h>
|
#include <gio/gcredentialsprivate.h>
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_basic (void)
|
||||||
|
{
|
||||||
|
GCredentials *creds = g_credentials_new ();
|
||||||
|
gchar *stringified;
|
||||||
|
DWORD *pid;
|
||||||
|
|
||||||
|
stringified = g_credentials_to_string (creds);
|
||||||
|
g_test_message ("%s", stringified);
|
||||||
|
g_free (stringified);
|
||||||
|
|
||||||
|
pid = g_credentials_get_native (creds,
|
||||||
|
G_CREDENTIALS_TYPE_WIN32_PID);
|
||||||
|
g_assert_cmpuint (*pid, ==, GetCurrentProcessId ());
|
||||||
|
|
||||||
|
g_object_unref (creds);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_basic (void)
|
test_basic (void)
|
||||||
{
|
{
|
||||||
@ -177,6 +199,8 @@ test_basic (void)
|
|||||||
g_object_unref (other);
|
g_object_unref (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !G_OS_WIN32 */
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
|
@ -17,15 +17,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
#include <gio/gcredentialsprivate.h>
|
#include <gio/gcredentialsprivate.h>
|
||||||
|
#include <gio/gunixconnection.h>
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gio/gnetworking.h>
|
#include <gio/gnetworking.h>
|
||||||
#include <gio/gunixconnection.h>
|
#endif
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
#include "giowin32-afunix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gnetworkingprivate.h"
|
#include "gnetworkingprivate.h"
|
||||||
@ -1327,7 +1333,23 @@ test_sockaddr (void)
|
|||||||
g_object_unref (saddr);
|
g_object_unref (saddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
static void
|
||||||
|
bind_win32_unixfd (int fd)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
gint len, ret;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
memset (&addr, 0, sizeof addr);
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
len = g_snprintf (addr.sun_path, sizeof addr.sun_path, "%s" G_DIR_SEPARATOR_S "%d.sock", g_get_tmp_dir (), fd);
|
||||||
|
g_assert_cmpint (len, <=, sizeof addr.sun_path);
|
||||||
|
ret = bind (fd, (struct sockaddr *)&addr, sizeof addr);
|
||||||
|
g_assert_cmpint (ret, ==, 0);
|
||||||
|
g_remove (addr.sun_path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_unix_from_fd (void)
|
test_unix_from_fd (void)
|
||||||
{
|
{
|
||||||
@ -1338,6 +1360,8 @@ test_unix_from_fd (void)
|
|||||||
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
g_assert_cmpint (fd, !=, -1);
|
g_assert_cmpint (fd, !=, -1);
|
||||||
|
|
||||||
|
bind_win32_unixfd (fd);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
s = g_socket_new_from_fd (fd, &error);
|
s = g_socket_new_from_fd (fd, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -1358,6 +1382,8 @@ test_unix_connection (void)
|
|||||||
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||||
g_assert_cmpint (fd, !=, -1);
|
g_assert_cmpint (fd, !=, -1);
|
||||||
|
|
||||||
|
bind_win32_unixfd (fd);
|
||||||
|
|
||||||
error = NULL;
|
error = NULL;
|
||||||
s = g_socket_new_from_fd (fd, &error);
|
s = g_socket_new_from_fd (fd, &error);
|
||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
@ -1367,6 +1393,7 @@ test_unix_connection (void)
|
|||||||
g_object_unref (s);
|
g_object_unref (s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
static GSocketConnection *
|
static GSocketConnection *
|
||||||
create_connection_for_fd (int fd)
|
create_connection_for_fd (int fd)
|
||||||
{
|
{
|
||||||
@ -1466,6 +1493,7 @@ test_unix_connection_ancillary_data (void)
|
|||||||
* g_unix_connection_receive_credentials().
|
* g_unix_connection_receive_credentials().
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
postmortem_source_cb (GSocket *socket,
|
postmortem_source_cb (GSocket *socket,
|
||||||
@ -1513,8 +1541,6 @@ test_source_postmortem (void)
|
|||||||
g_main_context_unref (context);
|
g_main_context_unref (context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* G_OS_UNIX */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_reuse_tcp (void)
|
test_reuse_tcp (void)
|
||||||
{
|
{
|
||||||
@ -2076,7 +2102,118 @@ client_setup_thread (gpointer user_data)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_WIN32
|
||||||
|
/*
|
||||||
|
* _g_win32_socketpair:
|
||||||
|
*
|
||||||
|
* Create a pair of connected sockets, similar to POSIX/BSD socketpair().
|
||||||
|
*
|
||||||
|
* Windows does not (yet) provide a socketpair() function. However, since the
|
||||||
|
* introduction of AF_UNIX sockets, it is possible to implement a fairly close
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
static gint
|
||||||
|
_g_win32_socketpair (gint domain,
|
||||||
|
gint type,
|
||||||
|
gint protocol,
|
||||||
|
gint sv[2])
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr = { 0, };
|
||||||
|
socklen_t socklen;
|
||||||
|
SOCKET listener = INVALID_SOCKET;
|
||||||
|
SOCKET client = INVALID_SOCKET;
|
||||||
|
SOCKET server = INVALID_SOCKET;
|
||||||
|
gchar *path = NULL;
|
||||||
|
int tmpfd, rv = -1;
|
||||||
|
u_long arg, br;
|
||||||
|
|
||||||
|
g_return_val_if_fail (sv != NULL, -1);
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
socklen = sizeof (addr);
|
||||||
|
|
||||||
|
tmpfd = g_file_open_tmp (NULL, &path, NULL);
|
||||||
|
if (tmpfd == -1)
|
||||||
|
{
|
||||||
|
WSASetLastError (WSAEACCES);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_close (tmpfd, NULL);
|
||||||
|
|
||||||
|
if (strlen (path) >= sizeof (addr.sun_path))
|
||||||
|
{
|
||||||
|
WSASetLastError (WSAEACCES);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
|
||||||
|
|
||||||
|
listener = socket (domain, type, protocol);
|
||||||
|
if (listener == INVALID_SOCKET)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (DeleteFile (path) == 0)
|
||||||
|
{
|
||||||
|
if (GetLastError () != ERROR_FILE_NOT_FOUND)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind (listener, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (listen (listener, 1) == SOCKET_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
client = socket (domain, type, protocol);
|
||||||
|
if (client == INVALID_SOCKET)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
arg = 1;
|
||||||
|
if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (connect (client, (struct sockaddr *) &addr, socklen) == SOCKET_ERROR &&
|
||||||
|
WSAGetLastError () != WSAEWOULDBLOCK)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
server = accept (listener, NULL, NULL);
|
||||||
|
if (server == INVALID_SOCKET)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
arg = 0;
|
||||||
|
if (ioctlsocket (client, FIONBIO, &arg) == SOCKET_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (WSAIoctl (server, SIO_AF_UNIX_GETPEERPID,
|
||||||
|
NULL, 0U,
|
||||||
|
&arg, sizeof (arg), &br,
|
||||||
|
NULL, NULL) == SOCKET_ERROR || arg != GetCurrentProcessId ())
|
||||||
|
{
|
||||||
|
WSASetLastError (WSAEACCES);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sv[0] = server;
|
||||||
|
server = INVALID_SOCKET;
|
||||||
|
sv[1] = client;
|
||||||
|
client = INVALID_SOCKET;
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (listener != INVALID_SOCKET)
|
||||||
|
closesocket (listener);
|
||||||
|
if (client != INVALID_SOCKET)
|
||||||
|
closesocket (client);
|
||||||
|
if (server != INVALID_SOCKET)
|
||||||
|
closesocket (server);
|
||||||
|
|
||||||
|
DeleteFile (path);
|
||||||
|
g_free (path);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif /* G_OS_WIN32 */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_credentials_unix_socketpair (void)
|
test_credentials_unix_socketpair (void)
|
||||||
{
|
{
|
||||||
@ -2086,7 +2223,11 @@ test_credentials_unix_socketpair (void)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GCredentials *creds;
|
GCredentials *creds;
|
||||||
|
|
||||||
|
#ifdef G_OS_WIN32
|
||||||
|
status = _g_win32_socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
|
||||||
|
#else
|
||||||
status = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
|
status = socketpair (PF_UNIX, SOCK_STREAM, 0, fds);
|
||||||
|
#endif
|
||||||
g_assert_cmpint (status, ==, 0);
|
g_assert_cmpint (status, ==, 0);
|
||||||
|
|
||||||
sock = g_socket_new_from_fd (fds[0], &error);
|
sock = g_socket_new_from_fd (fds[0], &error);
|
||||||
@ -2107,10 +2248,9 @@ test_credentials_unix_socketpair (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (sock);
|
g_object_unref (sock);
|
||||||
close (fds[1]);
|
g_close (fds[1], NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
@ -2151,12 +2291,12 @@ main (int argc,
|
|||||||
g_test_add_func ("/socket/timed_wait", test_timed_wait);
|
g_test_add_func ("/socket/timed_wait", test_timed_wait);
|
||||||
g_test_add_func ("/socket/fd_reuse", test_fd_reuse);
|
g_test_add_func ("/socket/fd_reuse", test_fd_reuse);
|
||||||
g_test_add_func ("/socket/address", test_sockaddr);
|
g_test_add_func ("/socket/address", test_sockaddr);
|
||||||
#ifdef G_OS_UNIX
|
|
||||||
g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
|
g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
|
||||||
g_test_add_func ("/socket/unix-connection", test_unix_connection);
|
g_test_add_func ("/socket/unix-connection", test_unix_connection);
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
|
g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
|
||||||
g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
|
|
||||||
#endif
|
#endif
|
||||||
|
g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
|
||||||
g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
|
g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
|
||||||
g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
|
g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
|
||||||
g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM),
|
g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM),
|
||||||
@ -2173,9 +2313,7 @@ main (int argc,
|
|||||||
#if G_CREDENTIALS_SUPPORTED
|
#if G_CREDENTIALS_SUPPORTED
|
||||||
g_test_add_func ("/socket/credentials/tcp_client", test_credentials_tcp_client);
|
g_test_add_func ("/socket/credentials/tcp_client", test_credentials_tcp_client);
|
||||||
g_test_add_func ("/socket/credentials/tcp_server", test_credentials_tcp_server);
|
g_test_add_func ("/socket/credentials/tcp_server", test_credentials_tcp_server);
|
||||||
#ifdef G_OS_UNIX
|
|
||||||
g_test_add_func ("/socket/credentials/unix_socketpair", test_credentials_unix_socketpair);
|
g_test_add_func ("/socket/credentials/unix_socketpair", test_credentials_unix_socketpair);
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
|
@ -277,6 +277,7 @@ add_project_arguments(glib_debug_cflags, language: 'c')
|
|||||||
|
|
||||||
headers = [
|
headers = [
|
||||||
'alloca.h',
|
'alloca.h',
|
||||||
|
'afunix.h',
|
||||||
'crt_externs.h',
|
'crt_externs.h',
|
||||||
'dirent.h', # MSC does not come with this by default
|
'dirent.h', # MSC does not come with this by default
|
||||||
'float.h',
|
'float.h',
|
||||||
|
Loading…
Reference in New Issue
Block a user