commit 5022cec769294a488cbb65c7ad81fb78978631e1
parent 0f9d6e9946afc5fce3f6cec62c43fec091f6ca4d
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 19 Dec 2010 18:54:44 +0000
support for sendfile with offset
Diffstat:
6 files changed, 75 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
@@ -1,3 +1,6 @@
+Sun Dec 19 19:54:15 CET 2010
+ Added 'MHD_create_response_from_fd_at_offset'. -CG
+
Sun Dec 19 15:16:16 CET 2010
Fixing --enable and --disable configure options to behave properly. -CG
diff --git a/doc/microhttpd.texi b/doc/microhttpd.texi
@@ -1287,11 +1287,37 @@ header information and then it can be used any number of times.
@table @var
@item size
-size of the data portion of the response, @code{-1} for unknown;
+size of the data portion of the response (should be smaller or equal to the
+size of the file)
+
+@item fd
+file descriptor referring to a file on disk with the data; will be
+closed when response is destroyed; note that 'fd' must be an actual
+file descriptor (not a pipe or socket) since MHD might use 'sendfile'
+or 'seek' on it
+@end table
+
+Return @mynull{} on error (i.e. invalid arguments, out of memory).
+@end deftypefun
+
+
+@deftypefun {struct MHD_Response *} MHD_create_response_from_fd_at_offset (uint64_t size, int fd, off_t offset)
+Create a response object. The response object can be extended with
+header information and then it can be used any number of times.
+
+@table @var
+@item size
+size of the data portion of the response (number of bytes to transmit from the
+file starting at offset).
@item fd
file descriptor referring to a file on disk with the data; will be
-closed when response is destroyed
+closed when response is destroyed; note that 'fd' must be an actual
+file descriptor (not a pipe or socket) since MHD might use 'sendfile'
+or 'seek' on it
+
+@item offset
+offset to start reading from in the file
@end table
Return @mynull{} on error (i.e. invalid arguments, out of memory).
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
@@ -701,7 +701,7 @@ send_param_adapter (struct MHD_Connection *connection,
(-1 != (fd = connection->response->fd)) )
{
/* can use sendfile */
- offset = (off_t) connection->response_write_position;
+ offset = (off_t) connection->response_write_position + connection->response->fd_off;
ret = sendfile (connection->socket_fd,
fd,
&offset,
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
@@ -229,6 +229,11 @@ struct MHD_Response
uint64_t data_start;
/**
+ * Offset to start reading from when using 'fd'.
+ */
+ off_t fd_off;
+
+ /**
* Size of data.
*/
size_t data_size;
diff --git a/src/daemon/response.c b/src/daemon/response.c
@@ -273,7 +273,7 @@ file_reader (void *cls, uint64_t pos, char *buf, size_t max)
int ret;
pthread_mutex_lock (&response->mutex);
- (void) lseek (response->fd, pos, SEEK_SET);
+ (void) lseek (response->fd, pos + response->fd_off, SEEK_SET);
ret = read (response->fd, buf, max);
pthread_mutex_unlock (&response->mutex);
return ret;
@@ -301,10 +301,12 @@ free_callback (void *cls)
*
* @param size size of the data portion of the response
* @param fd file descriptor referring to a file on disk with the data
+ * @param off offset to start reading from in the file
* @return NULL on error (i.e. invalid arguments, out of memory)
*/
-struct MHD_Response *MHD_create_response_from_fd (size_t size,
- int fd)
+struct MHD_Response *MHD_create_response_from_fd_at_offset (size_t size,
+ int fd,
+ off_t offset)
{
struct MHD_Response *ret;
@@ -316,11 +318,29 @@ struct MHD_Response *MHD_create_response_from_fd (size_t size,
if (ret == NULL)
return NULL;
ret->fd = fd;
+ ret->fd_off = offset;
ret->crc_cls = ret;
return ret;
}
+
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
+ * @param fd file descriptor referring to a file on disk with the data
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+struct MHD_Response *MHD_create_response_from_fd (size_t size,
+ int fd)
+{
+ return MHD_create_response_from_fd_at_offset (size, fd, 0);
+}
+
+
/**
* Create a response object. The response object can be extended with
* header information and then be used any number of times.
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
@@ -1201,6 +1201,21 @@ struct MHD_Response *MHD_create_response_from_data (size_t size,
struct MHD_Response *MHD_create_response_from_fd (size_t size,
int fd);
+
+/**
+ * Create a response object. The response object can be extended with
+ * header information and then be used any number of times.
+ *
+ * @param size size of the data portion of the response
+ * @param fd file descriptor referring to a file on disk with the data; will be closed when response is destroyed
+ * @param off offset to start reading from in the file
+ * @return NULL on error (i.e. invalid arguments, out of memory)
+ */
+struct MHD_Response *MHD_create_response_from_fd_at_offset (size_t size,
+ int fd,
+ off_t offset);
+
+
/**
* Destroy a response object and associated resources. Note that
* libmicrohttpd may keep some of the resources around if the response