/** * Create a socket and connect it to an address. * * @saddr: Inet socket address specification * @errp: set on error * * Returns: -1 on error, file descriptor on success. */ int inet_connect_saddr(InetSocketAddress *saddr, Error **errp) { Error *local_err = NULL; struct addrinfo *res, *e; int sock = -1; res = inet_parse_connect_saddr(saddr, errp); if (!res) { return -1; } for (e = res; e != NULL; e = e->ai_next) { error_free(local_err); local_err = NULL; sock = inet_connect_addr(e, &local_err); if (sock >= 0) { break; } } if (sock < 0) { error_propagate(errp, local_err); } freeaddrinfo(res); return sock; }
/** * Create a socket and connect it to an address. * * @saddr: Inet socket address specification * @errp: set on error * @callback: callback function for non-blocking connect * @opaque: opaque for callback function * * Returns: -1 on error, file descriptor on success. * * If @callback is non-null, the connect is non-blocking. If this * function succeeds, callback will be called when the connection * completes, with the file descriptor on success, or -1 on error. */ int inet_connect_saddr(InetSocketAddress *saddr, NonBlockingConnectHandler *callback, void *opaque, Error **errp) { Error *local_err = NULL; struct addrinfo *res, *e; int sock = -1; bool in_progress; ConnectState *connect_state = NULL; res = inet_parse_connect_saddr(saddr, errp); if (!res) { return -1; } if (callback != NULL) { connect_state = g_malloc0(sizeof(*connect_state)); connect_state->addr_list = res; connect_state->callback = callback; connect_state->opaque = opaque; } for (e = res; e != NULL; e = e->ai_next) { error_free(local_err); local_err = NULL; if (connect_state != NULL) { connect_state->current_addr = e; } sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); if (sock >= 0) { break; } } if (sock < 0) { error_propagate(errp, local_err); } else if (in_progress) { /* wait_for_connect() will do the rest */ return sock; } else { if (callback) { callback(sock, NULL, opaque); } } g_free(connect_state); freeaddrinfo(res); return sock; }