summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-24 11:35:29 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-24 11:35:29 +0100
commit7361db1995bd0f733c4a562857d0d3ae0c4c2b49 (patch)
treea5d412c0d6e7acee187db7ec96150ada981343a6
parent8bf60bbd1de2a329340e88d3fb31ea30e83eed8f (diff)
downloadhittpd-7361db1995bd0f733c4a562857d0d3ae0c4c2b49.tar.gz
hittpd-7361db1995bd0f733c4a562857d0d3ae0c4c2b49.tar.xz
hittpd-7361db1995bd0f733c4a562857d0d3ae0c4c2b49.zip
write_client: when sendfile(2) fails, try pread/write.
Some filesystems don't support sendfile, either due to bugs
or other reasons.

Found by Érico Nogueira.
-rw-r--r--hittpd.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/hittpd.c b/hittpd.c
index 9ddd2c4..3bc6bc6 100644
--- a/hittpd.c
+++ b/hittpd.c
@@ -854,7 +854,21 @@ write_client(int i)
 	ssize_t w = 0;
 
 	if (data->stream_fd >= 0) {
-#ifndef __linux__
+#ifdef __linux__
+		w = sendfile(sockfd, data->stream_fd,
+		    &(data->off), data->last - data->off);
+		if (data->off == data->last) {
+			finish_response(i);
+			return;
+		} else if (w == 0) {
+			close_connection(i);  // file was truncated!
+			return;
+		} else if (w > 0) {
+			return;
+		}
+
+		/* use default code when sendfile failed with w < 0 */
+#endif
 		char buf[16*4096];
 		ssize_t n = pread(data->stream_fd, buf, sizeof buf, data->off);
 		if (n < 0) {
@@ -872,14 +886,6 @@ write_client(int i)
 			else if (w == 0)
 				close_connection(i);  // file was truncated!
 		}
-#else
-		w = sendfile(sockfd, data->stream_fd,
-		    &(data->off), data->last - data->off);
-		if (data->off == data->last)
-			finish_response(i);
-		else if (w == 0)
-			close_connection(i);  // file was truncated!
-#endif
 	} else if (data->buf) {
 		if (data->off == data->last) {
 			finish_response(i);