changeset 9798:255596f41014

[gaim-migrate @ 10666] This is patch number 1002252 by Joe Shaw. He writes: If you start a file transfer with a yahoo user and then unplug the network, wait a couple minutes, and plug it back in, a minute or so later the gaim UI will completely freeze, eventually consume all your memory and crash. This is because ft.c:transfer_cb() does not correctly handle the case in which both READ and WRITE conditions are coming in, and because the yahoo_xfer_read() and yahoo_xfer_write() functions are incorrectly returning 0 on errors instead of -1. Since transfer_cb() is getting both conditions, it only checks READ first and gets back 0 bytes (because the connection has been hung up). 0 is not explicitly handled, so nothing is done and we get ourselves into an infinite loop. committer: Tailor Script <tailor@pidgin.im>
author Tim Ringenbach <marv@pidgin.im>
date Sat, 21 Aug 2004 02:02:25 +0000
parents 62eb9fe24692
children f4adac0ef359
files src/ft.c src/protocols/yahoo/yahoo_filexfer.c
diffstat 2 files changed, 11 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/ft.c	Fri Aug 20 22:05:18 2004 +0000
+++ b/src/ft.c	Sat Aug 21 02:02:25 2004 +0000
@@ -666,7 +666,7 @@
 	GaimXferUiOps *ui_ops;
 	GaimXfer *xfer = (GaimXfer *)data;
 	char *buffer = NULL;
-	ssize_t r;
+	ssize_t r = 0;
 
 	if (condition & GAIM_INPUT_READ) {
 		r = gaim_xfer_read(xfer, &buffer);
@@ -677,13 +677,14 @@
 			return;
 		}
 	}
-	else {
+
+	if (condition & GAIM_INPUT_WRITE) {
 		size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096);
 
 		/* this is so the prpl can keep the connection open
 		   if it needs to for some odd reason. */
 		if (s == 0) {
-			if(xfer->watcher) {
+			if (xfer->watcher) {
 				gaim_input_remove(xfer->watcher);
 				xfer->watcher = 0;
 			}
--- a/src/protocols/yahoo/yahoo_filexfer.c	Fri Aug 20 22:05:18 2004 +0000
+++ b/src/protocols/yahoo/yahoo_filexfer.c	Sat Aug 21 02:02:25 2004 +0000
@@ -253,11 +253,11 @@
 
 	if (len <= 0) {
 		if ((gaim_xfer_get_size(xfer) > 0) &&
-		   (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer)))
+		    (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))) {
 			gaim_xfer_set_completed(xfer, TRUE);
-		else
-			gaim_xfer_cancel_remote(xfer);
-		return 0;
+			return 0;
+		} else
+			return -1;
 	}
 
 
@@ -302,10 +302,10 @@
 	struct yahoo_xfer_data *xd = xfer->data;
 
 	if (!xd)
-		return 0;
+		return -1;
 
 	if (gaim_xfer_get_type(xfer) != GAIM_XFER_SEND) {
-		return 0;
+		return -1;
 	}
 
 	len = write(xfer->fd, buffer, size);
@@ -314,7 +314,7 @@
 		if (gaim_xfer_get_bytes_sent(xfer) >= gaim_xfer_get_size(xfer))
 			gaim_xfer_set_completed(xfer, TRUE);
 		if ((errno != EAGAIN) && (errno != EINTR))
-			gaim_xfer_cancel_remote(xfer);
+			return -1;
 		return 0;
 	}