/pidgin/main: 451ed08be0b9: Fix purple_xfer_write() during do_tr...
Jakub Adam
jakub.adam at ktknet.cz
Mon Apr 18 22:54:56 EDT 2016
Changeset: 451ed08be0b9003154d1e0dd0e5305d17757efb8
Author: Jakub Adam <jakub.adam at ktknet.cz>
Date: 2016-04-07 15:07 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/451ed08be0b9
Description:
Fix purple_xfer_write() during do_transfer()
Consider sending a small (say 10 bytes) file in do_transfer().
First, the buffer is filled in purple_xfer_read_file(), which also calls
purple_xfer_set_bytes_sent(); because the file is small, bytes sent now
equals the file size. Later in purple_xfer_write(), the size of
the write buffer is adjusted so that it's not bigger than the remaining
portion of the file being sent - but at that point
purple_xfer_get_bytes_remaining() already returns 0, nothing is written
and the file transfer gets stuck.
As I understant it, the meaning of buffer size adjustment in
purple_xfer_write() is to ensure that external protocol plugin which
handles file transfer input and output on its own can't by accident send
more data than the size of the file. In do_transfer(), though, that
check is redundant and can be skipped.
diffstat:
libpurple/xfer.c | 41 ++++++++++++++++++++++++++---------------
1 files changed, 26 insertions(+), 15 deletions(-)
diffs (65 lines):
diff --git a/libpurple/xfer.c b/libpurple/xfer.c
--- a/libpurple/xfer.c
+++ b/libpurple/xfer.c
@@ -1205,27 +1205,38 @@ purple_xfer_read(PurpleXfer *xfer, gucha
return r;
}
+static gssize
+do_write(PurpleXfer *xfer, const guchar *buffer, gsize size)
+{
+ PurpleXferPrivate *priv = PURPLE_XFER_GET_PRIVATE(xfer);
+ gssize r;
+
+ g_return_val_if_fail(priv != NULL, 0);
+ g_return_val_if_fail(buffer != NULL, 0);
+ g_return_val_if_fail(size != 0, 0);
+
+ if (priv->ops.write != NULL) {
+ r = (priv->ops.write)(buffer, size, xfer);
+ } else {
+ r = write(priv->fd, buffer, size);
+ if (r < 0 && errno == EAGAIN)
+ r = 0;
+ }
+
+ return r;
+}
+
gssize
purple_xfer_write(PurpleXfer *xfer, const guchar *buffer, gsize size)
{
PurpleXferPrivate *priv = PURPLE_XFER_GET_PRIVATE(xfer);
- gssize r, s;
-
- g_return_val_if_fail(priv != NULL, 0);
- g_return_val_if_fail(buffer != NULL, 0);
- g_return_val_if_fail(size != 0, 0);
+ gssize s;
+
+ g_return_val_if_fail(priv != NULL, 0);
s = MIN((gssize)purple_xfer_get_bytes_remaining(xfer), (gssize)size);
- if (priv->ops.write != NULL) {
- r = (priv->ops.write)(buffer, s, xfer);
- } else {
- r = write(priv->fd, buffer, s);
- if (r < 0 && errno == EAGAIN)
- r = 0;
- }
-
- return r;
+ return do_write(xfer, buffer, s);
}
gboolean
@@ -1405,7 +1416,7 @@ do_transfer(PurpleXfer *xfer)
result = priv->buffer->len;
}
- r = purple_xfer_write(xfer, buffer, result);
+ r = do_write(xfer, buffer, result);
if (r == -1) {
purple_xfer_cancel_remote(xfer);
More information about the Commits
mailing list