void bufadd(buffy *thebuf, char *toadd, int len) { if (thebuf->len+len>BUFMAX) { bufshift(thebuf, len); } memcpy(thebuf->data+thebuf->len, toadd, len); thebuf->len = thebuf->len + len; }
int edg_wll_plain_read_full( edg_wll_PlainConnection *conn, void *outbuf, size_t outbufsz, struct timeval *to) { size_t total = 0; if ( conn->bufUse > 0 ) { size_t len = (conn->bufUse < outbufsz) ? conn->bufUse : outbufsz; memcpy(outbuf, conn->buf, len); /* fuj outbufsz = len; */ bufshift(conn, len); total += len; } while ( total < outbufsz ) { int ct = edg_wll_plain_read(conn, outbuf+total, outbufsz-total, to); if ( ct < 0) return ct; total += ct; } return total; }
int edg_wll_plain_read( edg_wll_PlainConnection *conn, void *outbuf, size_t outbufsz, struct timeval *to) { int ct, toread = 0; struct pollfd pollfds[1]; int polltime = 0; struct timeval timeout, before, after; if ( conn->bufSize == 0 ) { if ( !(conn->buf = malloc(BUFSIZ)) ) return -1; conn->bufSize = BUFSIZ; conn->bufUse = 0; } if ( to ) { memcpy(&timeout, to, sizeof(timeout)); gettimeofday(&before, NULL); } errno = 0; if ( conn->bufUse > 0 ) goto cleanup; toread = 0; do { pollfds[0].fd = conn->sock; pollfds[0].events = POLLIN; polltime = to ? (timeout.tv_sec*1000+timeout.tv_usec/1000) : INFTIM; switch (poll(pollfds, 1, polltime)) { case 0: errno = ETIMEDOUT; goto cleanup; break; case -1: goto cleanup; break; default: if (!(pollfds[0].revents & POLLIN)) { errno = EIO; goto cleanup; break; } } if ( conn->bufUse == conn->bufSize ) { char *tmp = realloc(conn->buf, conn->bufSize+BUFSIZ); if ( !tmp ) return -1; conn->buf = tmp; conn->bufSize += BUFSIZ; } toread = conn->bufSize - conn->bufUse; if ( (ct = read(conn->sock, conn->buf+conn->bufUse, toread)) < 0 ) { if ( errno == EINTR ) continue; goto cleanup; } if ( ct == 0 && conn->bufUse == 0 && errno == 0 ) { errno = ENOTCONN; goto cleanup; } conn->bufUse += ct; } while ( ct == toread ); cleanup: if ( to ) { gettimeofday(&after, NULL); tv_sub(after, before); tv_sub(*to, after); if ( to->tv_sec < 0 ) to->tv_sec = to->tv_usec = 0; } if ( errno == ECONNRESET) errno = ENOTCONN; if ( errno ) return -1; if ( conn->bufUse > 0 ) { size_t len = (conn->bufUse < outbufsz) ? conn->bufUse : outbufsz; memcpy(outbuf, conn->buf, len); /* no use outbufsz = len; */ bufshift(conn, len); return len; } return 0; }