s4:socket: use a socket_wrapper aware function to auto close the fd event for sockets
authorStefan Metzmacher <metze@samba.org>
Sat, 3 Jan 2009 11:47:24 +0000 (12:47 +0100)
committerStefan Metzmacher <metze@samba.org>
Sat, 3 Jan 2009 18:58:53 +0000 (19:58 +0100)
metze

source4/auth/kerberos/krb5_init_context.c
source4/lib/socket/socket.c
source4/lib/socket/socket.h
source4/libcli/ldap/ldap_client.c
source4/smbd/service_stream.c

index 2f0a2317a0a8ae0d0974c6736c3bb912307b2093..6830bb7189bdce75b9e764dfe8309d6f3343a6e5 100644 (file)
@@ -284,11 +284,12 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
                 * drop) and mark as AUTOCLOSE along with the fde */
 
                /* Ths is equivilant to EVENT_FD_READABLE(smb_krb5->fde) */
-               smb_krb5->fde = event_add_fd(ev, smb_krb5->sock, 
-                                            socket_get_fd(smb_krb5->sock), 
-                                            EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
-                                            smb_krb5_socket_handler, smb_krb5);
+               smb_krb5->fde = tevent_add_fd(ev, smb_krb5->sock,
+                                             socket_get_fd(smb_krb5->sock),
+                                             TEVENT_FD_READ,
+                                             smb_krb5_socket_handler, smb_krb5);
                /* its now the job of the event layer to close the socket */
+               tevent_fd_set_close_fn(smb_krb5->fde, socket_tevent_fd_close_fn);
                socket_set_flags(smb_krb5->sock, SOCKET_FLAG_NOCLOSE);
 
                event_add_timed(ev, smb_krb5, 
index 26cdac99a3dfe7bd48dab5b2ecece75f8f774ffa..9d30e0a77ef7f87aa893b2bd0ad2d1a2248b1b19 100644 (file)
@@ -37,6 +37,15 @@ static int socket_destructor(struct socket_context *sock)
        return 0;
 }
 
+_PUBLIC_ void socket_tevent_fd_close_fn(struct tevent_context *ev,
+                                       struct tevent_fd *fde,
+                                       int fd,
+                                       void *private_data)
+{
+       /* this might be the socket_wrapper swrap_close() */
+       close(fd);
+}
+
 _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socket_ops *ops,
                                         struct socket_context **new_sock, 
                                         enum socket_type type, uint32_t flags)
index 7a27e3070b7efedab85a4d894d08c970dc21c728..e9338127c4b398a219bb0270f41a687496922581 100644 (file)
@@ -21,6 +21,7 @@
 #define _SAMBA_SOCKET_H
 
 struct tevent_context;
+struct tevent_fd;
 struct socket_context;
 
 enum socket_type {
@@ -205,6 +206,11 @@ NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx, const char *server_address,
 void set_socket_options(int fd, const char *options);
 void socket_set_flags(struct socket_context *socket, unsigned flags);
 
+void socket_tevent_fd_close_fn(struct tevent_context *ev,
+                              struct tevent_fd *fde,
+                              int fd,
+                              void *private_data);
+
 extern bool testnonblock;
 
 #endif /* _SAMBA_SOCKET_H */
index 18784135cc58297b4ae4919247ba8a5bf0191026..8c6810399741952e7776f2d5794db0f48783958b 100644 (file)
@@ -387,14 +387,15 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
                                  struct ldap_connection *conn) 
 {
        /* setup a handler for events on this socket */
-       conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, 
-                                      socket_get_fd(conn->sock), 
-                                      EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn);
+       conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
+                                       socket_get_fd(conn->sock),
+                                       TEVENT_FD_READ, ldap_io_handler, conn);
        if (conn->event.fde == NULL) {
                composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
                return;
        }
 
+       tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
        socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
 
        talloc_steal(conn, conn->sock);
index ef98919f937339d23be580a9278ce66484d55fdd..a5642c258ff159d1d86f1ab970b0451a0dd3bf55 100644 (file)
@@ -258,6 +258,7 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
        NTSTATUS status;
        struct stream_socket *stream_socket;
        struct socket_address *socket_address;
+       struct tevent_fd *fde;
        int i;
 
        stream_socket = talloc_zero(event_context, struct stream_socket);
@@ -322,20 +323,24 @@ NTSTATUS stream_setup_socket(struct tevent_context *event_context,
                return status;
        }
 
-       /* By specifying EVENT_FD_AUTOCLOSE below, we indicate that we
-        * will close the socket using the events system.  This avoids
-        * nasty interactions with waiting for talloc to close the socket. */
-
-       socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
-
        /* Add the FD from the newly created socket into the event
         * subsystem.  it will call the accept handler whenever we get
         * new connections */
 
-       event_add_fd(event_context, stream_socket->sock, 
-                    socket_get_fd(stream_socket->sock), 
-                    EVENT_FD_READ|EVENT_FD_AUTOCLOSE, 
-                    stream_accept_handler, stream_socket);
+       fde = tevent_add_fd(event_context, stream_socket->sock,
+                           socket_get_fd(stream_socket->sock),
+                           TEVENT_FD_READ,
+                           stream_accept_handler, stream_socket);
+       if (!fde) {
+               DEBUG(0,("Failed to setup fd event\n"));
+               talloc_free(stream_socket);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* we let events system to the close on the socket. This avoids
+        * nasty interactions with waiting for talloc to close the socket. */
+       tevent_fd_set_close_fn(fde, socket_tevent_fd_close_fn);
+       socket_set_flags(stream_socket->sock, SOCKET_FLAG_NOCLOSE);
 
        stream_socket->private          = talloc_reference(stream_socket, private);
        stream_socket->ops              = stream_ops;