Signed-off-by: Zebediah Figura z.figura12@gmail.com --- This patch, together with the next, creates a pseudo-fd object and subsequently replaces it with a newly created anonymous unix-based fd object. This is done on the model of accept_into_socket().
server/sock.c | 63 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 23 deletions(-)
diff --git a/server/sock.c b/server/sock.c index 115448574ee..0448519df2a 100644 --- a/server/sock.c +++ b/server/sock.c @@ -542,6 +542,8 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
assert( sock->obj.ops == &sock_ops );
+ if (get_unix_fd( fd ) == -1) return 0; + switch(code) { case WS_SIO_ADDRESS_LIST_CHANGE: @@ -631,14 +633,19 @@ static void sock_destroy( struct object *obj ) } }
-static void init_sock(struct sock *sock) +static struct sock *create_socket(void) { - sock->state = 0; + struct sock *sock; + + if (!(sock = alloc_object( &sock_ops ))) return NULL; + sock->fd = NULL; + sock->state = 0; sock->mask = 0; sock->hmask = 0; sock->pmask = 0; sock->polling = 0; sock->flags = 0; + sock->proto = 0; sock->type = 0; sock->family = 0; sock->event = NULL; @@ -652,12 +659,11 @@ static void init_sock(struct sock *sock) init_async_queue( &sock->write_q ); init_async_queue( &sock->ifchange_q ); memset( sock->errors, 0, sizeof(sock->errors) ); + return sock; }
-/* create a new and unconnected socket */ -static struct object *create_socket( int family, int type, int protocol, unsigned int flags ) +static int init_socket( struct sock *sock, int family, int type, int protocol, unsigned int flags ) { - struct sock *sock; int sockfd;
sockfd = socket( family, type, protocol ); @@ -665,15 +671,9 @@ static struct object *create_socket( int family, int type, int protocol, unsigne { if (errno == EINVAL) set_win32_error( WSAESOCKTNOSUPPORT ); else set_win32_error( sock_get_error( errno )); - return NULL; + return -1; } fcntl(sockfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ - if (!(sock = alloc_object( &sock_ops ))) - { - close( sockfd ); - return NULL; - } - init_sock( sock ); sock->state = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0; sock->flags = flags; sock->proto = protocol; @@ -683,12 +683,11 @@ static struct object *create_socket( int family, int type, int protocol, unsigne if (!(sock->fd = create_anonymous_fd( &sock_fd_ops, sockfd, &sock->obj, (flags & WSA_FLAG_OVERLAPPED) ? 0 : FILE_SYNCHRONOUS_IO_NONALERT ))) { - release_object( sock ); - return NULL; + return -1; } sock_reselect( sock ); clear_error(); - return &sock->obj; + return 0; }
/* accepts a socket and inits it */ @@ -720,6 +719,8 @@ static struct sock *accept_socket( obj_handle_t handle ) if (!sock) return NULL;
+ if (get_unix_fd( sock->fd ) == -1) return NULL; + if ( sock->deferred ) { acceptsock = sock->deferred; @@ -732,14 +733,13 @@ static struct sock *accept_socket( obj_handle_t handle ) release_object( sock ); return NULL; } - if (!(acceptsock = alloc_object( &sock_ops ))) + if (!(acceptsock = create_socket())) { close( acceptfd ); release_object( sock ); return NULL; }
- init_sock( acceptsock ); /* newly created socket gets the same properties of the listening socket */ acceptsock->state = FD_WINE_CONNECTED|FD_READ|FD_WRITE; if (sock->state & FD_WINE_NONBLOCKING) @@ -773,6 +773,9 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock ) { int acceptfd; struct fd *newfd; + + if (get_unix_fd( sock->fd ) == -1) return FALSE; + if ( sock->deferred ) { newfd = dup_fd_object( sock->deferred->fd, 0, 0, @@ -1213,8 +1216,15 @@ static struct object *socket_device_lookup_name( struct object *obj, struct unic static struct object *socket_device_open_file( struct object *obj, unsigned int access, unsigned int sharing, unsigned int options ) { - set_error( STATUS_NOT_IMPLEMENTED ); - return NULL; + struct sock *sock; + + if (!(sock = create_socket())) return NULL; + if (!(sock->fd = alloc_pseudo_fd( &sock_fd_ops, &sock->obj, options ))) + { + release_object( sock ); + return NULL; + } + return &sock->obj; }
struct object *create_socket_device( struct object *root, const struct unicode_str *name ) @@ -1225,13 +1235,14 @@ struct object *create_socket_device( struct object *root, const struct unicode_s /* create a socket */ DECL_HANDLER(create_socket) { - struct object *obj; + struct sock *sock;
reply->handle = 0; - if ((obj = create_socket( req->family, req->type, req->protocol, req->flags )) != NULL) + if ((sock = create_socket()) != NULL) { - reply->handle = alloc_handle( current->process, obj, req->access, req->attributes ); - release_object( obj ); + if (!init_socket( sock, req->family, req->type, req->protocol, req->flags )) + reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes ); + release_object( sock ); } }
@@ -1284,6 +1295,7 @@ DECL_HANDLER(set_socket_event)
if (!(sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_WRITE_ATTRIBUTES, &sock_ops))) return; + if (get_unix_fd( sock->fd ) == -1) return; old_event = sock->event; sock->mask = req->mask; sock->hmask &= ~req->mask; /* re-enable held events */ @@ -1316,6 +1328,7 @@ DECL_HANDLER(get_socket_event)
if (!(sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_READ_ATTRIBUTES, &sock_ops ))) return; + if (get_unix_fd( sock->fd ) == -1) return; reply->mask = sock->mask; reply->pmask = sock->pmask; reply->state = sock->state; @@ -1348,6 +1361,8 @@ DECL_HANDLER(enable_socket_event) FILE_WRITE_ATTRIBUTES, &sock_ops))) return;
+ if (get_unix_fd( sock->fd ) == -1) return; + /* for event-based notification, windows erases stale events */ sock->pmask &= ~req->mask;
@@ -1386,6 +1401,8 @@ DECL_HANDLER(get_socket_info) sock = (struct sock *)get_handle_obj( current->process, req->handle, FILE_READ_ATTRIBUTES, &sock_ops ); if (!sock) return;
+ if (get_unix_fd( sock->fd ) == -1) return; + reply->family = sock->family; reply->type = sock->type; reply->protocol = sock->proto;