/* implements thrift_transport_write */ gboolean thrift_socket_write (ThriftTransport *transport, const gpointer buf, const guint32 len, GError **error) { gint ret = 0; guint sent = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); g_return_val_if_fail (socket->sd != 0, FALSE); while (sent < len) { ret = send (socket->sd, buf + sent, len - sent, 0); if (ret < 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND, "failed to send %d bytes - %s", len, strerror(errno)); return FALSE; } sent += ret; } return TRUE; }
/* implements thrift_transport_open */ gboolean thrift_socket_open (ThriftTransport *transport, GError **error) { struct hostent *hp = NULL; struct sockaddr_in pin; int err; #if defined(HAVE_GETHOSTBYNAME_R) struct hostent he; char buf[1024]; #endif ThriftSocket *tsocket = THRIFT_SOCKET (transport); g_return_val_if_fail (tsocket->sd == 0, FALSE); /* lookup the destination host */ #if defined(HAVE_GETHOSTBYNAME_R) if (gethostbyname_r (tsocket->hostname, &he, buf, 1024, &hp, &err) != 0 || hp == NULL) #else if ((hp = gethostbyname (tsocket->hostname)) == NULL && (err = h_errno)) #endif { /* host lookup failed, bail out with an error */ g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_HOST, "host lookup failed for %s:%d - %s", tsocket->hostname, tsocket->port, hstrerror (err)); return FALSE; } /* create a socket structure */ memset (&pin, 0, sizeof(pin)); pin.sin_family = AF_INET; pin.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; pin.sin_port = htons (tsocket->port); /* create the socket */ if ((tsocket->sd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "failed to create socket for host %s:%d - %s", tsocket->hostname, tsocket->port, strerror(errno)); return FALSE; } /* open a connection */ if (connect (tsocket->sd, (struct sockaddr *) &pin, sizeof(pin)) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CONNECT, "failed to connect to host %s:%d - %s", tsocket->hostname, tsocket->port, strerror(errno)); return FALSE; } return TRUE; }
/* implements thrift_transport_close */ gboolean thrift_socket_close (ThriftTransport *transport, GError **error) { ThriftSocket *socket = THRIFT_SOCKET (transport); if (close (socket->sd) == -1) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_CLOSE, "unable to close socket - %s", strerror(errno)); return FALSE; } socket->sd = 0; return TRUE; }
/* property accessor */ void thrift_socket_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { THRIFT_UNUSED_VAR (pspec); ThriftSocket *socket = THRIFT_SOCKET (object); switch (property_id) { case PROP_THRIFT_SOCKET_HOSTNAME: g_value_set_string (value, socket->hostname); break; case PROP_THRIFT_SOCKET_PORT: g_value_set_uint (value, socket->port); break; } }
/* destructor */ static void thrift_socket_finalize (GObject *object) { ThriftSocket *socket = THRIFT_SOCKET (object); if (socket->hostname != NULL) { g_free (socket->hostname); } socket->hostname = NULL; if (socket->sd != 0) { close (socket->sd); } socket->sd = 0; }
/* overrides thrift_transport_peek */ gboolean thrift_socket_peek (ThriftTransport *transport, GError **error) { gboolean result = FALSE; guint8 buf; int r; int errno_copy; ThriftSocket *socket = THRIFT_SOCKET (transport); if (thrift_socket_is_open (transport)) { r = recv (socket->sd, &buf, 1, MSG_PEEK); if (r == -1) { errno_copy = errno; #if defined __FreeBSD__ || defined __MACH__ /* FreeBSD returns -1 and ECONNRESET if the socket was closed by the other side */ if (errno_copy == ECONNRESET) { thrift_socket_close (transport, error); } else { #endif g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET, "failed to peek at socket - %s", strerror (errno_copy)); #if defined __FreeBSD__ || defined __MACH__ } #endif } else if (r > 0) { result = TRUE; } } return result; }
/* implements thrift_transport_read */ gint32 thrift_socket_read (ThriftTransport *transport, gpointer buf, guint32 len, GError **error) { gint ret = 0; guint got = 0; ThriftSocket *socket = THRIFT_SOCKET (transport); while (got < len) { ret = recv (socket->sd, buf, len, 0); if (ret < 0) { g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE, "failed to read %d bytes - %s", len, strerror(errno)); return -1; } got += ret; } return got; }
/* implements thrift_transport_is_open */ gboolean thrift_socket_is_open (ThriftTransport *transport) { ThriftSocket *socket = THRIFT_SOCKET (transport); return socket->sd != 0; }