mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Updated SIO_ADDRESS_LIST_CHANGE patches.
This commit is contained in:
parent
94813ecf3c
commit
bfb7d535af
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,3 +1,7 @@
|
||||
wine-compholio (1.7.19) unstable; urgency=low
|
||||
* Updated SIO_ADDRESS_LIST_CHANGE patches.
|
||||
-- Erich E. Hoover <erich.e.hoover@gmail.com> Tue, 06 May 2014 15:42:32 -0600
|
||||
|
||||
wine-compholio (1.7.18-1) unstable; urgency=low
|
||||
* Fix some issues on BSD systems.
|
||||
* Add additional patches to silence a few FIXMEs.
|
||||
|
@ -1,15 +1,15 @@
|
||||
From 69e77bd226057f486d1c076ccbebb963d3b750ee Mon Sep 17 00:00:00 2001
|
||||
From 864781654bfbb059a351fdcda6773e2857019278 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:25:48 -0600
|
||||
Date: Tue, 6 May 2014 08:39:18 -0600
|
||||
Subject: server: Add socket-side support for the interface change
|
||||
notification object.
|
||||
|
||||
---
|
||||
server/sock.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 91 insertions(+), 1 deletion(-)
|
||||
server/sock.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 86 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 05fc38b..20d022f 100644
|
||||
index 3eb1bdf..ad20a69 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -106,12 +106,18 @@ struct sock
|
||||
@ -22,26 +22,26 @@ index 05fc38b..20d022f 100644
|
||||
};
|
||||
|
||||
static void sock_dump( struct object *obj, int verbose );
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
+static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *sock_get_fd( struct object *obj );
|
||||
static void sock_destroy( struct object *obj );
|
||||
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue );
|
||||
+static struct async_queue *sock_get_ifchange_q( struct sock *sock );
|
||||
+static void sock_destroy_ifchange_q( struct sock *sock );
|
||||
|
||||
static int sock_get_poll_events( struct fd *fd );
|
||||
static void sock_poll_event( struct fd *fd, int event );
|
||||
@@ -539,7 +545,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
@@ -529,7 +535,8 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
switch(code)
|
||||
{
|
||||
case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
- /* intentional fallthrough, not yet supported */
|
||||
+ error = sock_add_ifchange( sock, async_data );
|
||||
+ break;
|
||||
+ sock_add_ifchange( sock, async_data );
|
||||
+ return 0;
|
||||
default:
|
||||
error = STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
@@ -625,6 +632,7 @@ static void sock_destroy( struct object *obj )
|
||||
set_error( STATUS_NOT_SUPPORTED );
|
||||
return 0;
|
||||
@@ -610,6 +617,7 @@ static void sock_destroy( struct object *obj )
|
||||
|
||||
free_async_queue( sock->read_q );
|
||||
free_async_queue( sock->write_q );
|
||||
@ -49,7 +49,7 @@ index 05fc38b..20d022f 100644
|
||||
if (sock->event) release_object( sock->event );
|
||||
if (sock->fd)
|
||||
{
|
||||
@@ -651,6 +659,8 @@ static void init_sock(struct sock *sock)
|
||||
@@ -636,6 +644,8 @@ static void init_sock(struct sock *sock)
|
||||
sock->deferred = NULL;
|
||||
sock->read_q = NULL;
|
||||
sock->write_q = NULL;
|
||||
@ -58,37 +58,37 @@ index 05fc38b..20d022f 100644
|
||||
memset( sock->errors, 0, sizeof(sock->errors) );
|
||||
}
|
||||
|
||||
@@ -939,6 +949,86 @@ static void sock_set_error(void)
|
||||
@@ -924,6 +934,81 @@ static void sock_set_error(void)
|
||||
set_error( sock_get_ntstatus( errno ) );
|
||||
}
|
||||
|
||||
+/* add interface change notification to a socket */
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
+static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
+{
|
||||
+ struct async_queue *ifchange_q = NULL;
|
||||
+ struct async *async;
|
||||
+ int error;
|
||||
+
|
||||
+ error = sock_get_ifchange_q( sock, &ifchange_q );
|
||||
+ if (error != STATUS_PENDING)
|
||||
+ return error;
|
||||
+ if (!(ifchange_q = sock_get_ifchange_q( sock )))
|
||||
+ return;
|
||||
+
|
||||
+ if (!(async = create_async( current, ifchange_q, async_data )))
|
||||
+ {
|
||||
+ if (!async_queued( ifchange_q ))
|
||||
+ sock_destroy_ifchange_q( sock );
|
||||
+
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ release_object( async );
|
||||
+ return error;
|
||||
+ set_error( STATUS_PENDING );
|
||||
+}
|
||||
+
|
||||
+/* stub ifchange object */
|
||||
+static int get_ifchange( struct object **obj )
|
||||
+static struct object *get_ifchange( void )
|
||||
+{
|
||||
+ return STATUS_NOT_SUPPORTED;
|
||||
+ set_error( STATUS_NOT_SUPPORTED );
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* stub ifchange add socket to list */
|
||||
@ -97,21 +97,16 @@ index 05fc38b..20d022f 100644
|
||||
+}
|
||||
+
|
||||
+/* create a new ifchange queue for a specific socket or, if one already exists, reuse the existing one */
|
||||
+static int sock_get_ifchange_q( struct sock *sock, struct async_queue **async_queue )
|
||||
+static struct async_queue *sock_get_ifchange_q( struct sock *sock )
|
||||
+{
|
||||
+ struct object *ifchange = NULL;
|
||||
+ struct fd *fd;
|
||||
+ int error;
|
||||
+
|
||||
+ if (sock->ifchange_q) /* reuse existing ifchange_q for this socket */
|
||||
+ {
|
||||
+ *async_queue = sock->ifchange_q;
|
||||
+ return STATUS_PENDING;
|
||||
+ }
|
||||
+ return sock->ifchange_q;
|
||||
+
|
||||
+ error = get_ifchange( &ifchange );
|
||||
+ if (error != STATUS_PENDING)
|
||||
+ return error;
|
||||
+ if (!(ifchange = get_ifchange()))
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* create the ifchange notification queue */
|
||||
+ fd = ifchange->ops->get_fd( ifchange );
|
||||
@ -120,14 +115,14 @@ index 05fc38b..20d022f 100644
|
||||
+ if (!sock->ifchange_q)
|
||||
+ {
|
||||
+ release_object( ifchange );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* add the socket to the ifchange notification list */
|
||||
+ ifchange_add_sock( ifchange, sock );
|
||||
+ sock->ifchange_obj = ifchange;
|
||||
+ *async_queue = sock->ifchange_q;
|
||||
+ return error;
|
||||
+ return sock->ifchange_q;
|
||||
+}
|
||||
+
|
||||
+/* destroy an existing ifchange queue for a specific socket */
|
@ -1,14 +1,14 @@
|
||||
From 45dfbd2ddb5ca2c64fcfd56392be9c55513abc4b Mon Sep 17 00:00:00 2001
|
||||
From c93a05ca0114b76c542f251de60b8c009e4a72b0 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:23:02 -0600
|
||||
Subject: server: Add delayed processing for socket-specific ioctl().
|
||||
Date: Tue, 6 May 2014 08:44:59 -0600
|
||||
Subject: server: Add blocked support for SIO_ADDRESS_LIST_CHANGE ioctl().
|
||||
|
||||
---
|
||||
server/event.c | 13 +++++++++++++
|
||||
server/named_pipe.c | 13 -------------
|
||||
server/object.h | 1 +
|
||||
server/sock.c | 19 +++++++++++++++++--
|
||||
4 files changed, 31 insertions(+), 15 deletions(-)
|
||||
server/sock.c | 26 ++++++++++++++++++++------
|
||||
4 files changed, 34 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/server/event.c b/server/event.c
|
||||
index 4d3c562..0daa5b2 100644
|
||||
@ -71,44 +71,78 @@ index bb3ff21..bad162f 100644
|
||||
extern struct keyed_event *get_keyed_event_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern void pulse_event( struct event *event );
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 3eb1bdf..05fc38b 100644
|
||||
index ad20a69..a8a5ac3 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -523,17 +523,32 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
@@ -112,7 +112,7 @@ struct sock
|
||||
};
|
||||
|
||||
static void sock_dump( struct object *obj, int verbose );
|
||||
-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data );
|
||||
static int sock_signaled( struct object *obj, struct wait_queue_entry *entry );
|
||||
static struct fd *sock_get_fd( struct object *obj );
|
||||
static void sock_destroy( struct object *obj );
|
||||
@@ -529,14 +529,27 @@ obj_handle_t sock_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *a
|
||||
int blocking, const void *data, data_size_t size )
|
||||
{
|
||||
struct sock *sock = get_fd_user( fd );
|
||||
+ obj_handle_t wait_handle = 0;
|
||||
+ async_data_t new_data;
|
||||
+ int error;
|
||||
|
||||
assert( sock->obj.ops == &sock_ops );
|
||||
|
||||
+ if (blocking)
|
||||
+ {
|
||||
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
|
||||
+ new_data = *async_data;
|
||||
+ new_data.event = wait_handle;
|
||||
+ async_data = &new_data;
|
||||
+ }
|
||||
switch(code)
|
||||
{
|
||||
case WS_SIO_ADDRESS_LIST_CHANGE:
|
||||
/* intentional fallthrough, not yet supported */
|
||||
default:
|
||||
- set_error( STATUS_NOT_SUPPORTED );
|
||||
- sock_add_ifchange( sock, async_data );
|
||||
- return 0;
|
||||
+ error = STATUS_NOT_SUPPORTED;
|
||||
+ break;
|
||||
}
|
||||
+ set_error( error );
|
||||
+ if (error == STATUS_PENDING)
|
||||
+ if (blocking)
|
||||
+ {
|
||||
+ if (!(wait_handle = alloc_wait_event( current->process ))) return 0;
|
||||
+ new_data = *async_data;
|
||||
+ new_data.event = wait_handle;
|
||||
+ async_data = &new_data;
|
||||
+ }
|
||||
+ if (!sock_add_ifchange( sock, async_data ) && wait_handle)
|
||||
+ {
|
||||
+ close_handle( current->process, wait_handle );
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return wait_handle;
|
||||
+ close_handle( current->process, wait_handle );
|
||||
+ return 0;
|
||||
default:
|
||||
set_error( STATUS_NOT_SUPPORTED );
|
||||
return 0;
|
||||
@@ -935,13 +948,13 @@ static void sock_set_error(void)
|
||||
}
|
||||
|
||||
static void sock_queue_async( struct fd *fd, const async_data_t *data, int type, int count )
|
||||
/* add interface change notification to a socket */
|
||||
-static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
+static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data )
|
||||
{
|
||||
struct async_queue *ifchange_q = NULL;
|
||||
struct async *async;
|
||||
|
||||
if (!(ifchange_q = sock_get_ifchange_q( sock )))
|
||||
- return;
|
||||
+ return FALSE;
|
||||
|
||||
if (!(async = create_async( current, ifchange_q, async_data )))
|
||||
{
|
||||
@@ -949,11 +962,12 @@ static void sock_add_ifchange( struct sock *sock, const async_data_t *async_data
|
||||
sock_destroy_ifchange_q( sock );
|
||||
|
||||
set_error( STATUS_NO_MEMORY );
|
||||
- return;
|
||||
+ return FALSE;
|
||||
}
|
||||
|
||||
release_object( async );
|
||||
set_error( STATUS_PENDING );
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
/* stub ifchange object */
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -1,14 +1,14 @@
|
||||
From 85d0475a493be336c340f25cab9895846e202f26 Mon Sep 17 00:00:00 2001
|
||||
From 55c83dc866e2d0e2cdc15b976b6d818a03ef4b89 Mon Sep 17 00:00:00 2001
|
||||
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
|
||||
Date: Thu, 3 Apr 2014 09:26:34 -0600
|
||||
Date: Tue, 6 May 2014 08:49:52 -0600
|
||||
Subject: server: Implement the interface change notification object.
|
||||
|
||||
---
|
||||
server/sock.c | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 198 insertions(+), 2 deletions(-)
|
||||
server/sock.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 203 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 20d022f..82464f2 100644
|
||||
index a8a5ac3..2af9acc 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -43,6 +43,10 @@
|
||||
@ -22,11 +22,12 @@ index 20d022f..82464f2 100644
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
@@ -972,15 +976,207 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data
|
||||
return error;
|
||||
@@ -970,16 +974,212 @@ static int sock_add_ifchange( struct sock *sock, const async_data_t *async_data
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-/* stub ifchange object */
|
||||
-static struct object *get_ifchange( void )
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+
|
||||
+/* only keep one ifchange object around, all sockets waiting for wakeups will look to it */
|
||||
@ -162,7 +163,7 @@ index 20d022f..82464f2 100644
|
||||
+}
|
||||
+
|
||||
+static void ifchange_reselect_async( struct fd *fd, struct async_queue *queue )
|
||||
+{
|
||||
{
|
||||
+ /* do nothing, this object is about to disappear */
|
||||
+}
|
||||
+
|
||||
@ -170,8 +171,8 @@ index 20d022f..82464f2 100644
|
||||
+
|
||||
+/* we only need one of these interface notification objects, all of the sockets dependent upon
|
||||
+ * it will wake up when a notification event occurs */
|
||||
static int get_ifchange( struct object **obj )
|
||||
{
|
||||
+ static struct object *get_ifchange( void )
|
||||
+ {
|
||||
+#ifdef HAVE_LINUX_RTNETLINK_H
|
||||
+ struct ifchange *ifchange;
|
||||
+ struct sockaddr_nl addr;
|
||||
@ -180,14 +181,16 @@ index 20d022f..82464f2 100644
|
||||
+ if (ifchange_object)
|
||||
+ {
|
||||
+ /* increment the refcount for each socket that uses the ifchange object */
|
||||
+ *obj = grab_object( ifchange_object );
|
||||
+ return STATUS_PENDING;
|
||||
+ return grab_object( ifchange_object );
|
||||
+ }
|
||||
+
|
||||
+ /* create the socket we need for processing interface change notifications */
|
||||
+ unix_fd = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
|
||||
+ if (unix_fd == -1)
|
||||
+ return sock_get_ntstatus( errno );
|
||||
+ {
|
||||
+ sock_set_error();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ fcntl( unix_fd, F_SETFL, O_NONBLOCK ); /* make socket nonblocking */
|
||||
+ memset( &addr, 0, sizeof(addr) );
|
||||
+ addr.nl_family = AF_NETLINK;
|
||||
@ -196,27 +199,30 @@ index 20d022f..82464f2 100644
|
||||
+ if (bind( unix_fd, (struct sockaddr *)&addr, sizeof(addr) ) == -1)
|
||||
+ {
|
||||
+ close( unix_fd );
|
||||
+ return sock_get_ntstatus( errno );
|
||||
+ sock_set_error();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ if (!(ifchange = alloc_object( &ifchange_ops )))
|
||||
+ {
|
||||
+ close( unix_fd );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ list_init( &ifchange->sockets );
|
||||
+ if (!(ifchange->fd = create_anonymous_fd( &ifchange_fd_ops, unix_fd, &ifchange->obj, 0 )))
|
||||
+ {
|
||||
+ release_object( ifchange );
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ set_error( STATUS_NO_MEMORY );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ set_fd_events( ifchange->fd, POLLIN ); /* enable read wakeup on the file descriptor */
|
||||
+
|
||||
+ /* the ifchange object is now successfully configured */
|
||||
+ ifchange_object = &ifchange->obj;
|
||||
+ *obj = &ifchange->obj;
|
||||
+ return STATUS_PENDING;
|
||||
+ return &ifchange->obj;
|
||||
+#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
set_error( STATUS_NOT_SUPPORTED );
|
||||
return NULL;
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user