From ff7e536bf5a42aef0eb51bc6f120b42842466e0f Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Mon, 13 Aug 2012 17:00:42 -0700 Subject: [PATCH] rspreload: Support sendfile Handle users calling sendfile with an rsocket. Signed-off-by: Sean Hefty --- src/preload.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/preload.c b/src/preload.c index 8b86415f..9b71c77e 100644 --- a/src/preload.c +++ b/src/preload.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #include #include #include +#include #include #include @@ -84,6 +86,7 @@ struct socket_calls { void *optval, socklen_t *optlen); int (*fcntl)(int socket, int cmd, ... /* arg */); int (*dup2)(int oldfd, int newfd); + ssize_t (*sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); }; static struct socket_calls real; @@ -276,6 +279,7 @@ static void init_preload(void) real.getsockopt = dlsym(RTLD_NEXT, "getsockopt"); real.fcntl = dlsym(RTLD_NEXT, "fcntl"); real.dup2 = dlsym(RTLD_NEXT, "dup2"); + real.sendfile = dlsym(RTLD_NEXT, "sendfile"); rs.socket = dlsym(RTLD_DEFAULT, "rsocket"); rs.bind = dlsym(RTLD_DEFAULT, "rbind"); @@ -1009,3 +1013,23 @@ int dup2(int oldfd, int newfd) atomic_inc(&oldfdi->refcnt); return newfd; } + +ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) +{ + void *file_addr; + int fd; + size_t ret; + + if (fd_get(out_fd, &fd) != fd_rsocket) + return real.sendfile(fd, in_fd, offset, count); + + file_addr = mmap(NULL, count, PROT_READ, 0, in_fd, offset ? *offset : 0); + if (file_addr == (void *) -1) + return -1; + + len = rsend(fd, file_addr, count); + if ((len > 0) && offset) + lseek(in_fd, len, SEEK_CUR); + munmap(file_addr, count); + return ret; +} -- 2.45.2