bool net::socket::connect(type type, const socket_address& addr, int timeout) { // Create socket. if (!create(addr.ss_family, type)) { return false; } // Connect. if ((::connect(_M_fd, reinterpret_cast<const struct sockaddr*>(&addr), addr.size()) < 0) && (errno != EINPROGRESS)) { close(); return false; } if (timeout != 0) { if (!wait_writable(timeout)) { close(); return false; } int error; if ((!get_socket_error(error)) || (error != 0)) { close(); return false; } } return true; }
bool net::socket::listen(const socket_address& addr) { // Create socket. if (!create(addr.ss_family, STREAM)) { return false; } // Reuse address. int optval = 1; if (setsockopt(_M_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) < 0) { close(); return false; } // Bind. if (bind(_M_fd, reinterpret_cast<const struct sockaddr*>(&addr), addr.size()) < 0) { if (addr.ss_family == AF_UNIX) { unlink(reinterpret_cast<const local_address*>(&addr)->sun_path); } close(); return false; } // Listen. if (::listen(_M_fd, BACKLOG) < 0) { if (addr.ss_family == AF_UNIX) { unlink(reinterpret_cast<const local_address*>(&addr)->sun_path); } close(); return false; } if (addr.ss_family == AF_UNIX) { unlink(reinterpret_cast<const local_address*>(&addr)->sun_path); } return true; }