/pidgin/main: 451ed08be0b9: Fix purple_xfer_write() during do_tr...
Jakub Adam <[email protected]>
| Newsgroups | gmane.comp.gnome.gaim.cvs |
|---|---|
| Message-ID | <[email protected]> |
Changeset: 451ed08be0b9003154d1e0dd0e5305d17757efb8 Author: Jakub Adam <[email protected]> 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); _______________________________________________ Commits mailing list [email protected] https://pidgin.im/cgi-bin/mailman/listinfo/commits