/** * We get called here from directly following a call to connect(2). * In order to determine if we've errored out or succeeded must call * getsockopt. */ static void uv__tcp_connect(uv_handle_t* handle) { int error; socklen_t errorsize = sizeof(int); assert(handle->fd >= 0); uv_req_t* req = handle->connect_req; assert(req); if (handle->delayed_error) { /* To smooth over the differences between unixes errors that * were reported synchronously on the first connect can be delayed * until the next tick--which is now. */ error = handle->delayed_error; handle->delayed_error = 0; } else { /* Normal situation: we need to get the socket error from the kernel. */ getsockopt(handle->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize); } if (!error) { ev_io_start(EV_DEFAULT_ &handle->read_watcher); /* Successful connection */ handle->connect_req = NULL; uv_connect_cb connect_cb = req->cb; if (connect_cb) { connect_cb(req, 0); } } else if (error == EINPROGRESS) { /* Still connecting. */ return; } else { /* Error */ uv_err_t err = uv_err_new(handle, error); handle->connect_req = NULL; uv_connect_cb connect_cb = req->cb; if (connect_cb) { connect_cb(req, -1); } uv_close(handle); } }
static int run_test(int inprocess) { uv_process_t process; uv_thread_t tid; int r; if (inprocess) { r = uv_thread_create(&tid, ipc_send_recv_helper_threadproc, (void *) 42); ASSERT(r == 0); uv_sleep(1000); r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1); ASSERT(r == 0); uv_pipe_connect(&ctx.connect_req, &ctx.channel, TEST_PIPENAME_3, connect_cb); } else { spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper"); connect_cb(&ctx.connect_req, 0); } r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(r == 0); ASSERT(recv_cb_count == 2); if (inprocess) { r = uv_thread_join(&tid); ASSERT(r == 0); } return 0; }
static void udp_can_write(gpointer data, gint source, PurpleInputCondition cond) { PurpleConnection *gc; qq_data *qd; socklen_t len; int error=0, ret; gc = (PurpleConnection *) data; g_return_if_fail(gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; purple_debug_info("proxy", "Connected.\n"); /* * getsockopt after a non-blocking connect returns -1 if something is * really messed up (bad descriptor, usually). Otherwise, it returns 0 and * error holds what connect would have returned if it blocked until now. * Thus, error == 0 is success, error == EINPROGRESS means "try again", * and anything else is a real error. * * (error == EINPROGRESS can happen after a select because the kernel can * be overly optimistic sometimes. select is just a hint that you might be * able to do something.) */ len = sizeof(error); ret = getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len); if (ret == 0 && error == EINPROGRESS) return; /* we'll be called again later */ purple_input_remove(qd->udp_can_write_handler); qd->udp_can_write_handler = 0; if (ret < 0 || error != 0) { if(ret != 0) error = errno; close(source); purple_debug_error("proxy", "getsockopt SO_ERROR check: %s\n", g_strerror(error)); connect_cb(gc, -1, _("Unable to connect")); return; } connect_cb(gc, source, NULL); }
int DeviceProxy_Callback::connect(int timeout) { int rv = 0; if(connect_cb) rv = connect_cb(timeout); if(rv == 0) p_is_connected = true; // No connect method - assume always connected return rv; }
static void udp_host_resolved(GSList *hosts, gpointer data, const char *error_message) { PurpleConnection *gc; qq_data *qd; struct sockaddr server_addr; int addr_size; gint fd = -1; int flags; gc = (PurpleConnection *) data; g_return_if_fail(gc != NULL && gc->proto_data != NULL); qd = (qq_data *) gc->proto_data; /* udp_query_data must be set as NULL. * Otherwise purple_dnsquery_destroy in qq_disconnect cause glib double free error */ qd->udp_query_data = NULL; if (!hosts || !hosts->data) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to resolve hostname")); return; } addr_size = GPOINTER_TO_INT(hosts->data); hosts = g_slist_remove(hosts, hosts->data); memcpy(&server_addr, hosts->data, addr_size); g_free(hosts->data); hosts = g_slist_remove(hosts, hosts->data); while(hosts) { hosts = g_slist_remove(hosts, hosts->data); g_free(hosts->data); hosts = g_slist_remove(hosts, hosts->data); } fd = socket(PF_INET, SOCK_DGRAM, 0); if (fd < 0) { purple_debug_error("QQ", "Unable to create socket: %s\n", g_strerror(errno)); return; } /* we use non-blocking mode to speed up connection */ flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags | O_NONBLOCK); #ifndef _WIN32 fcntl(fd, F_SETFD, FD_CLOEXEC); #endif /* From Unix-socket-FAQ: http://www.faqs.org/faqs/unix-faq/socket/ * * If a UDP socket is unconnected, which is the normal state after a * bind() call, then send() or write() are not allowed, since no * destination is available; only sendto() can be used to send data. * * Calling connect() on the socket simply records the specified address * and port number as being the desired communications partner. That * means that send() or write() are now allowed; they use the destination * address and port given on the connect call as the destination of packets. */ if (connect(fd, &server_addr, addr_size) >= 0) { purple_debug_info("QQ", "Connected.\n"); flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); connect_cb(gc, fd, NULL); return; } /* [EINPROGRESS] * The socket is marked as non-blocking and the connection cannot be * completed immediately. It is possible to select for completion by * selecting the socket for writing. * [EINTR] * A signal interrupted the call. * The connection is established asynchronously. */ if ((errno == EINPROGRESS) || (errno == EINTR)) { purple_debug_warning( "QQ", "Connect in asynchronous mode.\n"); qd->udp_can_write_handler = purple_input_add(fd, PURPLE_INPUT_WRITE, udp_can_write, gc); return; } purple_debug_error("QQ", "Connection failed: %s\n", g_strerror(errno)); close(fd); }