changeset 15685:f99e06ae143e

merge of '29edb52ee278b20f6e1569192934bd2f83482536' and '8cf2cdc881f4a61b4c926ece09b604053f37351f'
author Ethan Blanton <elb@pidgin.im>
date Fri, 23 Feb 2007 16:26:47 +0000
parents 14d85ee22d78 (diff) 58392653a1bd (current diff)
children 7639029f1bf4
files libpurple/util.c
diffstat 6 files changed, 70 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/console/gntgaim.c	Fri Feb 23 16:25:32 2007 +0000
+++ b/console/gntgaim.c	Fri Feb 23 16:26:47 2007 +0000
@@ -148,7 +148,8 @@
 	g_timeout_add,
 	g_source_remove,
 	gnt_input_add,
-	g_source_remove
+	g_source_remove,
+	NULL /* input_get_error */
 };
 
 static GaimEventLoopUiOps *
--- a/libpurple/eventloop.c	Fri Feb 23 16:25:32 2007 +0000
+++ b/libpurple/eventloop.c	Fri Feb 23 16:26:47 2007 +0000
@@ -23,6 +23,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include "eventloop.h"
+#include "internal.h"
 
 static GaimEventLoopUiOps *eventloop_ui_ops = NULL;
 
@@ -58,6 +59,27 @@
 	return ops->input_remove(tag);
 }
 
+int
+gaim_input_get_error(int fd, int *error)
+{
+	GaimEventLoopUiOps *ops = gaim_eventloop_get_ui_ops();
+
+	if (ops->input_get_error)
+	{
+		errno = 0;
+		int ret = ops->input_get_error(fd, error);
+		errno = *error;
+		return ret;
+	}
+	else
+	{
+		socklen_t len;
+		len = sizeof(*error);
+
+		return getsockopt(fd, SOL_SOCKET, SO_ERROR, error, &len);
+	}
+}
+
 void
 gaim_eventloop_set_ui_ops(GaimEventLoopUiOps *ops)
 {
--- a/libpurple/eventloop.h	Fri Feb 23 16:25:32 2007 +0000
+++ b/libpurple/eventloop.h	Fri Feb 23 16:26:47 2007 +0000
@@ -71,6 +71,16 @@
 	 * @see gaim_input_remove, g_source_remove
 	 */
 	gboolean (*input_remove)(guint handle);
+	
+	
+	/**
+	 * Get the current error status for an input.
+	 * Implementation of this UI op is optional. Implement it if the UI's sockets
+	 * or event loop needs to customize determination of socket error status.
+	 * @see gaim_input_get_error, getsockopt
+	 */
+	int (*input_get_error)(int fd, int *error);
+
 };
 
 /**************************************************************************/
@@ -119,7 +129,22 @@
  * @param handle The handle of the input handler. Note that this is the return
  * value from gaim_input_add, <i>not</i> the file descriptor.
  */
-gboolean gaim_input_remove(guint handle);
+guint gaim_input_remove(guint handle);
+
+/**
+ * Get the current error status for an input.
+ * The return value and error follow getsockopt() with a level of SOL_SOCKET and an
+ * option name of SO_ERROR, and this is how the error is determined if the UI does not
+ * implement the input_get_error UI op.
+ *
+ * @param fd        The input file descriptor.
+ * @param errno		A pointer to an int which on return will have the error, or 0 if no error.
+ *
+ * @return 0 if there is no error; -1 if there is an error, in which case errno will be set.
+ */
+int
+gaim_input_get_error(int fd, int *errno);
+
 
 /*@}*/
 
--- a/libpurple/proxy.c	Fri Feb 23 16:25:32 2007 +0000
+++ b/libpurple/proxy.c	Fri Feb 23 16:26:47 2007 +0000
@@ -386,14 +386,14 @@
 socket_ready_cb(gpointer data, gint source, GaimInputCondition cond)
 {
 	GaimProxyConnectData *connect_data = data;
-	socklen_t len;
 	int error = 0;
 	int ret;
 
-	gaim_debug_info("proxy", "Connected.\n");
+	gaim_debug_info("proxy", "Connected to %s:%d.\n",
+					connect_data->host, connect_data->port);
 
 	/*
-	 * getsockopt after a non-blocking connect returns -1 if something is
+	 * gaim_input_get_error 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",
@@ -403,17 +403,21 @@
 	 * be overly optimistic sometimes. select is just a hint that you might be
 	 * able to do something.)
 	 */
-	len = sizeof(error);
-	ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	ret = gaim_input_get_error(connect_data->fd, &error);
 
-	if (ret == 0 && error == EINPROGRESS)
+	if (ret == 0 && error == EINPROGRESS) {
 		/* No worries - we'll be called again later */
 		/* TODO: Does this ever happen? */
+		gaim_debug_info("proxy", "(ret == 0 && error == EINPROGRESS)");
 		return;
+	}
 
 	if (ret != 0 || error != 0) {
 		if (ret != 0)
 			error = errno;
+		gaim_debug_info("proxy", "Error connecting to %s:%d (%s).\n",
+						connect_data->host, connect_data->port, strerror(error));
+
 		gaim_proxy_connect_data_disconnect(connect_data, strerror(error));
 		return;
 	}
@@ -466,14 +470,12 @@
 		/*
 		 * The connection happened IMMEDIATELY... strange, but whatever.
 		 */
-		socklen_t len;
 		int error = ETIMEDOUT;
 		int ret;
 
 		gaim_debug_info("proxy", "Connected immediately.\n");
 
-		len = sizeof(error);
-		ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+		ret = gaim_input_get_error(connect_data->fd, &error);
 		if ((ret != 0) || (error != 0))
 		{
 			if (ret != 0)
@@ -783,13 +785,13 @@
 {
 	GString *request;
 	GaimProxyConnectData *connect_data;
-	socklen_t len;
 	int error = ETIMEDOUT;
 	int ret;
 
-	gaim_debug_info("proxy", "Connected.\n");
+	connect_data = data;
 
-	connect_data = data;
+	gaim_debug_info("proxy", "Connected to %s:%d.\n",
+		connect_data->host, connect_data->port);
 
 	if (connect_data->inpa > 0)
 	{
@@ -797,8 +799,7 @@
 		connect_data->inpa = 0;
 	}
 
-	len = sizeof(error);
-	ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	ret = gaim_input_get_error(connect_data->fd, &error);
 	if ((ret != 0) || (error != 0))
 	{
 		if (ret != 0)
@@ -947,7 +948,6 @@
 	unsigned char packet[9];
 	struct hostent *hp;
 	GaimProxyConnectData *connect_data = data;
-	socklen_t len;
 	int error = ETIMEDOUT;
 	int ret;
 
@@ -959,8 +959,7 @@
 		connect_data->inpa = 0;
 	}
 
-	len = sizeof(error);
-	ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	ret = gaim_input_get_error(connect_data->fd, &error);
 	if ((ret != 0) || (error != 0))
 	{
 		if (ret != 0)
@@ -1515,7 +1514,6 @@
 	unsigned char buf[5];
 	int i;
 	GaimProxyConnectData *connect_data = data;
-	socklen_t len;
 	int error = ETIMEDOUT;
 	int ret;
 
@@ -1527,8 +1525,7 @@
 		connect_data->inpa = 0;
 	}
 
-	len = sizeof(error);
-	ret = getsockopt(connect_data->fd, SOL_SOCKET, SO_ERROR, &error, &len);
+	ret = gaim_input_get_error(connect_data->fd, &error);
 	if ((ret != 0) || (error != 0))
 	{
 		if (ret != 0)
--- a/libpurple/util.c	Fri Feb 23 16:25:32 2007 +0000
+++ b/libpurple/util.c	Fri Feb 23 16:26:47 2007 +0000
@@ -4146,3 +4146,4 @@
 	signal(SIGXFSZ, SIG_DFL);	/* 25: exceeded file size limit */	
 #endif /* HAVE_SIGNAL_H */
 #endif /* !_WIN32 */
+}
--- a/pidgin/gtkeventloop.c	Fri Feb 23 16:25:32 2007 +0000
+++ b/pidgin/gtkeventloop.c	Fri Feb 23 16:26:47 2007 +0000
@@ -118,7 +118,8 @@
 	g_timeout_add,
 	g_source_remove,
 	pidgin_input_add,
-	g_source_remove
+	g_source_remove,
+	NULL /* input_get_error */
 };
 
 GaimEventLoopUiOps *