cgi-io: use splice() to stream backup archive
authorJo-Philipp Wich <jo@mein.io>
Fri, 13 Sep 2019 07:17:58 +0000 (09:17 +0200)
committerJohn Crispin <john@phrozen.org>
Fri, 13 Sep 2019 11:05:09 +0000 (13:05 +0200)
This improves the I/O performance when outputting large backups.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Makefile
src/main.c

index eaf03b40d9dd2cd7ff34c16b279e936ebbd4009a..211360905c245f12cbd0217076ae1b7236ac59a7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=cgi-io
-PKG_RELEASE:=11
+PKG_RELEASE:=12
 
 PKG_LICENSE:=GPL-2.0-or-later
 
index d19277d6a49a65cd98bee80263fcccde19724b0c..ca157584225c5a01b2a9d7856bfd117f622504d0 100644 (file)
@@ -16,6 +16,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#define _GNU_SOURCE /* splice(), SPLICE_F_MORE */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
@@ -736,7 +738,6 @@ main_backup(int argc, char **argv)
        int len;
        int status;
        int fds[2];
-       char buf[4096];
        char datestr[16] = { 0 };
        char hostname[64] = { 0 };
        char *fields[] = { "sessionid", NULL };
@@ -768,7 +769,6 @@ main_backup(int argc, char **argv)
                return -1;
 
        default:
-               fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL) | O_NONBLOCK);
                now = time(NULL);
                strftime(datestr, sizeof(datestr) - 1, "%Y-%m-%d", localtime(&now));
 
@@ -780,15 +780,13 @@ main_backup(int argc, char **argv)
                printf("Content-Disposition: attachment; "
                       "filename=\"backup-%s-%s.tar.gz\"\r\n\r\n", hostname, datestr);
 
-               do {
-                       waitpid(pid, &status, 0);
+               fflush(stdout);
 
-                       while ((len = read(fds[0], buf, sizeof(buf))) > 0) {
-                               fwrite(buf, len, 1, stdout);
-                               fflush(stdout);
-                       }
+               do {
+                       len = splice(fds[0], NULL, 1, NULL, 4096, SPLICE_F_MORE);
+               } while (len > 0);
 
-               } while (!WIFEXITED(status));
+               waitpid(pid, &status, 0);
 
                close(fds[0]);
                close(fds[1]);