socklen_t salen;
uint16_t port;
int wait_usec;
+ struct tevent_req *connect_subreq;
};
static void open_socket_out_connected(struct tevent_req *subreq);
-static int open_socket_out_state_destructor(struct open_socket_out_state *s)
+static void open_socket_out_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
{
- if (s->fd != -1) {
- close(s->fd);
+ struct open_socket_out_state *state =
+ tevent_req_data(req, struct open_socket_out_state);
+
+ /*
+ * Make sure that the async_connect_send subreq has a chance to reset
+ * fcntl before the socket goes away.
+ */
+ TALLOC_FREE(state->connect_subreq);
+
+ if (req_state == TEVENT_REQ_DONE) {
+ /*
+ * we keep the socket open for the caller to use
+ */
+ return;
+ }
+
+ if (state->fd != -1) {
+ close(state->fd);
+ state->fd = -1;
}
- return 0;
}
/****************************************************************************
int timeout)
{
char addr[INET6_ADDRSTRLEN];
- struct tevent_req *result, *subreq;
+ struct tevent_req *result;
struct open_socket_out_state *state;
NTSTATUS status;
status = map_nt_error_from_unix(errno);
goto post_status;
}
- talloc_set_destructor(state, open_socket_out_state_destructor);
+
+ tevent_req_set_cleanup_fn(result, open_socket_out_cleanup);
if (!tevent_req_set_endtime(
result, ev, timeval_current_ofs_msec(timeout))) {
print_sockaddr(addr, sizeof(addr), &state->ss);
DEBUG(3,("Connecting to %s at port %u\n", addr, (unsigned int)port));
- subreq = async_connect_send(state, state->ev, state->fd,
- (struct sockaddr *)&state->ss,
- state->salen, NULL, NULL, NULL);
- if ((subreq == NULL)
+ state->connect_subreq = async_connect_send(
+ state, state->ev, state->fd, (struct sockaddr *)&state->ss,
+ state->salen, NULL, NULL, NULL);
+ if ((state->connect_subreq == NULL)
|| !tevent_req_set_endtime(
- subreq, state->ev,
+ state->connect_subreq, state->ev,
timeval_current_ofs(0, state->wait_usec))) {
goto fail;
}
- tevent_req_set_callback(subreq, open_socket_out_connected, result);
+ tevent_req_set_callback(state->connect_subreq,
+ open_socket_out_connected, result);
return result;
post_status:
ret = async_connect_recv(subreq, &sys_errno);
TALLOC_FREE(subreq);
+ state->connect_subreq = NULL;
if (ret == 0) {
tevent_req_done(req);
return;