Adding overload for fread() and fwrite() functions http://patch-tracker.debian.org/patch/misc/dl/trickle/1.07-9/trickle-overload.c --- ./trickle-overload.c +++ ./trickle-overload.c @@ -144,6 +144,9 @@ DECLARE(dup2, int, (int, int)); DECLARE(sendfile, ssize_t, (int, int, off_t *, size_t)); #endif +DECLARE(fread, size_t, (void *, size_t, size_t, FILE *)); +DECLARE(fwrite, size_t, (const void *, size_t, size_t, FILE *)); + static int delay(int, ssize_t *, short); static struct timeval *getdelay(struct sockdesc *, ssize_t *, short); static void update(int, ssize_t, short); @@ -225,6 +228,9 @@ trickle_init(void) GETADDR(sendfile); #endif + GETADDR(fread); + GETADDR(fwrite); + /* XXX pthread test */ /* if ((dh = dlopen("/usr/lib/libpthread.so.1.0", RTLD_LAZY)) == NULL) */ /* errx(1, "[trickle] Failed to open libpthread"); */ @@ -302,7 +308,9 @@ socket(int domain, int type, int protocol) domain, type, protocol, sock); #endif /* DEBUG */ - if (sock != -1 && domain == AF_INET && type == SOCK_STREAM) { + if (sock != -1 + && (domain == AF_INET || domain == AF_INET6) + && type == SOCK_STREAM) { if ((sd = calloc(1, sizeof(*sd))) == NULL) return (-1); if ((sd->stat = bwstat_new()) == NULL) { @@ -426,7 +434,7 @@ select_shift(struct delayhead *dhead, struct timeval *inittv, } int -_select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, +select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *__timeout) { struct sockdesc *sd; @@ -522,7 +530,7 @@ _select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, #define POLL_WRMASK (POLLOUT | POLLWRNORM | POLLWRBAND) #define POLL_RDMASK (POLLIN | /* POLLNORM | */ POLLPRI | POLLRDNORM | POLLRDBAND) -#if defined(__linux__) || (defined(__svr4__) && defined(__sun__)) || defined(__OpenBSD__) +#if defined(__linux__) || (defined(__svr4__) && defined(__sun__)) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__) int poll(struct pollfd *fds, nfds_t nfds, int __timeout) #elif defined(__FreeBSD__) @@ -1027,6 +1035,68 @@ sendfile(int out_fd, int in_fd, off_t *offset, size_t count) } #endif /* HAVE_SENDFILE */ +size_t +fread(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret = -1; + size_t xnbytes = size * nmemb; + int eagain; + + INIT; + + if (!(eagain = delay(fileno(stream), &xnbytes, TRICKLE_RECV) + == TRICKLE_WOULDBLOCK)) { + ret = (*libc_fread)(ptr, size, nmemb, stream); +#ifdef DEBUG + safe_printv(0, "[DEBUG] fread(%d, *, %d) = %d", fileno(stream), + xnbytes, ret); + } else { + safe_printv(0, "[DEBUG] delaying fread(%d, *, %d) = %d", + fileno(stream), xnbytes, ret); +#endif /* DEBUG */ + } + + update(fileno(stream), ret, TRICKLE_RECV); + + if (eagain) { + ret = -1; + errno = EAGAIN; + } + + return (ret); +} + +size_t +fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t ret = -1; + size_t xlen = size * nmemb; + int eagain; + + INIT; + + if (!(eagain = delay(fileno(stream), &xlen, TRICKLE_SEND) + == TRICKLE_WOULDBLOCK)) { + ret = (*libc_fwrite)(ptr, size, nmemb, stream); +#ifdef DEBUG + safe_printv(0, "[DEBUG] fwrite(%d, *, %d) = %d", fileno(stream), + xlen, ret); + } else { + safe_printv(0, "[DEBUG] delaying fwrite(%d, *, %d)", + fileno(stream), xlen); +#endif /* DEBUG */ + } + + update(fileno(stream), ret, TRICKLE_SEND); + + if (eagain) { + errno = EAGAIN; + ret = -1; + } + + return (ret); +} + static int delay(int sock, ssize_t *len, short which) {