From bb0bbf3a88932e5a32ac3055a16109fa613e575a Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Mon, 12 Nov 2012 19:23:58 +0100 Subject: [PATCH] do the output buffering ourselves; this improves performance a lot --- listdir.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/listdir.c b/listdir.c index 9f1afda..6d58431 100644 --- a/listdir.c +++ b/listdir.c @@ -11,9 +11,19 @@ #include #include #include +#include + +// 64k RAM aren't really that much, and it should speed things up significantly +#define OBULEN (64*1024) +static char outbuf[OBULEN] = "Status: 200 here's your listing" + "\nX-Frame-Options: DENY" + "\nContent-Type: text/plain;charset=utf8" + "\n\n"; int main() { - FASTOUTPUT + //FASTOUTPUT + prctl(PR_SET_DUMPABLE, 1); // FIXME XXX potential security problem; disable later! + if (chdir("/")) senderr("chdir / failed", MYFAULT); char *encpath = getenv("QUERY_STRING"); login_and_setup(); // will clear the environment @@ -40,29 +50,35 @@ int main() { senderr(errstr, NOTMYFAULT); } + // ok, let's do fast output! // The directory was opened successfully - send our success header. - puts("Status: 200 here's your listing"); - puts("X-Frame-Options: DENY"); - puts("Content-Type: text/plain;charset=utf8"); - puts(""); + char *p = outbuf+strlen(outbuf); // send one line per file + #define LINE_LENGTH_LIMIT (NAME_MAX*2+1+FMT_ULONG+1+FMT_ULONG+1) struct dirent *dent; - char linedata[NAME_MAX*2+1+FMT_ULONG+1+FMT_ULONG+1]; while ((dent = readdir(dir)) != NULL) { + if (p+LINE_LENGTH_LIMIT >= outbuf+OBULEN) { + // Whoah, that's a big directory! + // Flush the pipe. + write(1, outbuf, p-outbuf); + // And reuse the buffer. + p = outbuf; + } struct stat st; // if we can't really see the file anyway, skip it if (lstat(dent->d_name, &st)) continue; //printf("%s %lu %u\n", encfilename, (unsigned long)st.st_size, (unsigned int)st.st_mode); size_t name_len = strlen(dent->d_name); - hex(linedata, (unsigned char *)dent->d_name, name_len); - char *p = linedata+name_len*2; + hex(p, (unsigned char *)dent->d_name, name_len); + p += name_len*2; *(p++) = ' '; p += fmt_ulong(p, (unsigned long)st.st_size); *(p++) = ' '; p += fmt_ulong(p, (unsigned int)st.st_mode); *(p++) = '\n'; - *p = 0; - fputs(linedata, stdout); } + + // final pipe flush + write(1, outbuf, p-outbuf); } -- 2.20.1