static int _mongoc_stream_socket_close (mongoc_stream_t *stream) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *) stream; int ret; ENTRY; BSON_ASSERT (ss); if (ss->sock) { ret = mongoc_socket_close (ss->sock); RETURN (ret); } RETURN (0); }
int mock_server_run (mock_server_t *server) { struct sockaddr_in saddr; mongoc_stream_t *stream; mongoc_thread_t thread; mongoc_socket_t *ssock; mongoc_socket_t *csock; void **closure; int optval; bson_return_val_if_fail (server, -1); bson_return_val_if_fail (!server->sock, -1); MONGOC_INFO ("Starting mock server on port %d.", server->port); ssock = mongoc_socket_new (AF_INET, SOCK_STREAM, 0); if (!ssock) { perror("Failed to create socket."); return -1; } optval = 1; mongoc_socket_setsockopt (ssock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval); memset (&saddr, 0, sizeof saddr); saddr.sin_family = AF_INET; saddr.sin_port = htons(server->port); /* * TODO: Parse server->address. */ saddr.sin_addr.s_addr = htonl (INADDR_ANY); if (-1 == mongoc_socket_bind (ssock, (struct sockaddr *)&saddr, sizeof saddr)) { perror("Failed to bind socket"); return -1; } if (-1 == mongoc_socket_listen (ssock, 10)) { perror("Failed to put socket into listen mode"); return 3; } server->sock = ssock; mongoc_mutex_lock (&server->mutex); mongoc_cond_signal (&server->cond); mongoc_mutex_unlock (&server->mutex); for (;;) { csock = mongoc_socket_accept (server->sock, -1); if (!csock) { perror ("Failed to accept client socket"); break; } stream = mongoc_stream_socket_new (csock); closure = bson_malloc0 (sizeof(void*) * 2); closure[0] = server; closure[1] = stream; mongoc_thread_create (&thread, mock_server_worker, closure); } mongoc_socket_close (server->sock); server->sock = NULL; return 0; }
int mongoc_socket_connect (mongoc_socket_t *sock, /* IN */ const struct sockaddr *addr, /* IN */ mongoc_socklen_t addrlen, /* IN */ int64_t expire_at) /* IN */ { bool try_again = false; bool failed = false; int ret; int optval; /* getsockopt parameter types vary, we check in CheckCompiler.m4 */ mongoc_socklen_t optlen = (mongoc_socklen_t) sizeof optval; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (addr); BSON_ASSERT (addrlen); ret = connect (sock->sd, addr, addrlen); #ifdef _WIN32 if (ret == SOCKET_ERROR) { #else if (ret == -1) { #endif _mongoc_socket_capture_errno (sock); failed = true; try_again = _mongoc_socket_errno_is_again (sock); } if (failed && try_again) { if (_mongoc_socket_wait (sock, POLLOUT, expire_at)) { optval = -1; ret = getsockopt ( sock->sd, SOL_SOCKET, SO_ERROR, (char *) &optval, &optlen); if ((ret == 0) && (optval == 0)) { RETURN (0); } else { errno = sock->errno_ = optval; } } RETURN (-1); } else if (failed) { RETURN (-1); } else { RETURN (0); } } /* *-------------------------------------------------------------------------- * * mongoc_socket_destroy -- * * Cleanup after a mongoc_socket_t structure, possibly closing * underlying sockets. * * Returns: * None. * * Side effects: * @sock is freed and should be considered invalid. * *-------------------------------------------------------------------------- */ void mongoc_socket_destroy (mongoc_socket_t *sock) /* IN */ { if (sock) { mongoc_socket_close (sock); bson_free (sock); } } /* *-------------------------------------------------------------------------- * * mongoc_socket_listen -- * * Listen for incoming requests with a backlog up to @backlog. * * If @backlog is zero, a sensible default will be chosen. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_listen (mongoc_socket_t *sock, /* IN */ unsigned int backlog) /* IN */ { int ret; ENTRY; BSON_ASSERT (sock); if (backlog == 0) { backlog = 10; } ret = listen (sock->sd, backlog); _mongoc_socket_capture_errno (sock); RETURN (ret); }