示例#1
0
文件: ycht.c 项目: Distrotech/pidgin
static void ycht_packet_send_write_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	YchtConn *ycht = data;
	int ret, writelen;
	const gchar *output = NULL;

	writelen = purple_circular_buffer_get_max_read(ycht->txbuf);

	if (writelen == 0) {
		purple_input_remove(ycht->tx_handler);
		ycht->tx_handler = 0;
		return;
	}

	output = purple_circular_buffer_get_output(ycht->txbuf);

	ret = write(ycht->fd, output, writelen);

	if (ret < 0 && errno == EAGAIN)
		return;
	else if (ret <= 0) {
		/* TODO: error handling */
/*
		gchar *tmp = g_strdup_printf(_("Lost connection with server: %s"),
				g_strerror(errno));
		purple_connection_error(purple_account_get_connection(irc->account),
			      PURPLE_CONNECTION_ERROR_NETWORK_ERROR, tmp);
		g_free(tmp);
*/
		return;
	}

	purple_circular_buffer_mark_read(ycht->txbuf, ret);

}
示例#2
0
static gboolean
purple_circular_buffer_real_mark_read(PurpleCircularBuffer *buffer,
                                      gsize len)
{
	PurpleCircularBufferPrivate *priv = NULL;
	GObject *obj;

	g_return_val_if_fail(purple_circular_buffer_get_max_read(buffer) >= len, FALSE);

	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);

	priv->output += len;
	priv->bufused -= len;

	/* wrap to the start if we're at the end */
	if ((gsize)(priv->output - priv->buffer) == priv->buflen)
		priv->output = priv->buffer;

	obj = G_OBJECT(buffer);
	g_object_freeze_notify(obj);
	g_object_notify_by_pspec(obj, properties[PROP_BUFFER_USED]);
	g_object_notify_by_pspec(obj, properties[PROP_OUTPUT]);
	g_object_thaw_notify(obj);

	return TRUE;
}
/**
 * @param source When this function is called as a callback source is
 *        set to the fd that triggered the callback.  But this function
 *        is also called directly from flap_connection_send_byte_stream(),
 *        in which case source will be -1.  So don't use source--use
 *        conn->gsc or conn->fd instead.
 */
static void
send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	FlapConnection *conn;
	int writelen, ret;
	const gchar *output = NULL;

	conn = data;
	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
	output = purple_circular_buffer_get_output(conn->buffer_outgoing);

	if (writelen == 0)
	{
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		return;
	}

	if (conn->gsc)
		ret = purple_ssl_write(conn->gsc, output, writelen);
	else
		ret = send(conn->fd, output, writelen, 0);
	if (ret <= 0)
	{
		if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
			/* No worries */
			return;

		/* Error! */
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		if (conn->gsc) {
			purple_ssl_close(conn->gsc);
			conn->gsc = NULL;
		} else {
			close(conn->fd);
			conn->fd = -1;
		}
		flap_connection_schedule_destroy(conn,
				OSCAR_DISCONNECT_LOST_CONNECTION, g_strerror(errno));
		return;
	}

	purple_circular_buffer_mark_read(conn->buffer_outgoing, ret);
}
示例#4
0
文件: peer.c 项目: Distrotech/pidgin
static void
send_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	PeerConnection *conn;
	gsize writelen;
	gssize wrotelen;
	const gchar *output = NULL;

	conn = data;
	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);

	if (writelen == 0)
	{
		purple_input_remove(conn->watcher_outgoing);
		conn->watcher_outgoing = 0;
		/*
		 * The buffer is currently empty, so reset the current input
		 * and output positions to the start of the buffer.  We do
		 * this so that the next chunk of data that we put into the
		 * buffer can be read back out of the buffer in one fell swoop.
		 * Otherwise it gets fragmented and we have to read from the
		 * second half of the buffer than go back and read the rest of
		 * the chunk from the first half.
		 *
		 * We're using TCP, which is a stream based protocol, so this
		 * isn't supposed to matter.  However, experience has shown
		 * that at least the proxy file transfer code in AIM 6.1.41.2
		 * requires that the entire OFT frame arrive all at once.  If
		 * the frame is fragmented then AIM freaks out and aborts the
		 * file transfer.  Somebody should teach those guys how to
		 * write good TCP code.
		 */
		purple_circular_buffer_reset(conn->buffer_outgoing);
		return;
	}

	output = purple_circular_buffer_get_output(conn->buffer_outgoing);

	wrotelen = send(conn->fd, output, writelen, 0);
	if (wrotelen <= 0)
	{
		if (wrotelen < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
			/* No worries */
			return;

		if (conn->ready)
		{
			purple_input_remove(conn->watcher_outgoing);
			conn->watcher_outgoing = 0;
			close(conn->fd);
			conn->fd = -1;
			peer_connection_schedule_destroy(conn,
					OSCAR_DISCONNECT_LOST_CONNECTION, NULL);
		}
		else
		{
			/*
			 * This could happen when unable to send a negotiation
			 * frame to a peer proxy server.
			 */
			peer_connection_trynext(conn);
		}
		return;
	}

	purple_circular_buffer_mark_read(conn->buffer_outgoing, wrotelen);
	conn->lastactivity = time(NULL);
}