{
char cvtbuf[2048];
size_t bufsize;
+ size_t ret;
/* in many cases we can go direct */
if (cd->direct) {
while (*inbytesleft > 0) {
char *bufp1 = cvtbuf;
const char *bufp2 = cvtbuf;
+ size_t inbytesleft_tmp;
+ const char *inbuf_tmp;
+ inbuf_tmp = *inbuf;
+ inbytesleft_tmp = *inbytesleft;
bufsize = sizeof(cvtbuf);
if (cd->pull(cd->cd_pull,
- inbuf, inbytesleft, &bufp1, &bufsize) == -1
+ &inbuf_tmp, &inbytesleft_tmp, &bufp1, &bufsize) == -1
&& errno != E2BIG) return -1;
bufsize = sizeof(cvtbuf) - bufsize;
if (cd->push(cd->cd_push,
&bufp2, &bufsize,
- outbuf, outbytesleft) == -1) return -1;
+ outbuf, outbytesleft) == -1)
+ {
+ if (errno != E2BIG) {
+ return -1;
+ }
+
+ /*
+ * push returned E2BIG:
+ * re-run the pull operation with adapted
+ * bufsize to get the correct inbytesleft count
+ */
+
+ inbuf_tmp = *inbuf;
+ inbytesleft_tmp = *inbytesleft;
+ bufsize = sizeof(cvtbuf) - bufsize;
+
+ ret = cd->pull(cd->cd_pull,
+ &inbuf_tmp, &inbytesleft_tmp,
+ &bufp1, &bufsize);
+
+ if (ret != -1 || errno != E2BIG) {
+ DEBUG(0, ("Interal error: expected E2BIG from "
+ "pull, when retrying pull to get "
+ "proper inbytesleft. Don't know what "
+ "to do.\n"));
+ errno = EFAULT;
+ return -1;
+ }
+
+ *inbytesleft = inbytesleft_tmp;
+ *inbuf = inbuf_tmp;
+
+ return -1;
+ }
+
+ *inbytesleft = inbytesleft_tmp;
+ *inbuf = inbuf_tmp;
}
return 0;