diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2023-03-27 02:12:20 -0400 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2023-03-27 02:24:50 -0400 |
commit | e1391bf8b7c67f3525f425b8226e172e6a94aa1b (patch) | |
tree | 157c5756f80bece74a28340e30d493ea19eca818 /src/fdevent.c | |
parent | 5f5e87f518bfdabb1a6b8ba7164c60f17902a2f5 (diff) | |
download | lighttpd-git-e1391bf8b7c67f3525f425b8226e172e6a94aa1b.tar.gz |
[core] permit shell HERE docs to specify config
e.g.
/usr/sbin/lighttpd -D -f <(cat <<END
server.document-root = "/web/"
END
)
x-ref:
https://www.reddit.com/r/bash/comments/11wysi0/combining_heredocs_with_process_substitution/
Diffstat (limited to 'src/fdevent.c')
-rw-r--r-- | src/fdevent.c | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/src/fdevent.c b/src/fdevent.c index e1b7dddf..c4037645 100644 --- a/src/fdevent.c +++ b/src/fdevent.c @@ -610,31 +610,75 @@ fdevent_load_file (const char * const fn, off_t *lim, log_error_st *errh, void * off_t sz = 0; char *buf = NULL; do { + #if 0 + /* /dev/fd/ and /proc/self/fd/ might be special-cased, but then would + * be close()d at end of func before returning. Then again, that might + * be desirable since otherwise those fds do not have FD_CLOEXEC set. */ + fd = 0 == memcmp(fn, "/dev/fd/", sizeof("/dev/fd/")-1) + ? atoi(fn + sizeof("/dev/fd/")-1) + : 0 == memcmp(fn, "/proc/self/fd/", sizeof("/proc/self/fd/")-1) + ? atoi(fn + sizeof("/proc/self/fd/")-1) + : fdevent_open_cloexec(fn, 1, O_RDONLY, 0); /*(1: follows symlinks)*/ + #else fd = fdevent_open_cloexec(fn, 1, O_RDONLY, 0); /*(1: follows symlinks)*/ + #endif if (fd < 0) break; struct stat st; if (0 != fstat(fd, &st)) break; - if ((sizeof(off_t) > sizeof(size_t) && st.st_size >= (off_t)~(size_t)0u) - || (*lim != 0 && st.st_size >= *lim)) { - errno = EOVERFLOW; - break; - } - - sz = st.st_size; - buf = malloc_fn((size_t)sz+1);/*+1 trailing '\0' for str funcs on data*/ - if (NULL == buf) break; - - if (sz) { - ssize_t rd = 0; - off_t off = 0; - do { - rd = read(fd, buf+off, (size_t)(sz-off)); - } while (rd > 0 ? (off += rd) != sz : rd < 0 && errno == EINTR); - if (off != sz) { /*(file truncated?)*/ - if (rd >= 0) errno = EIO; + if (S_ISREG(st.st_mode)) { + sz = st.st_size; + if ((sizeof(off_t) > sizeof(size_t) && sz >= (off_t)~(size_t)0u) + || (*lim != 0 && sz >= *lim)) { + errno = EOVERFLOW; break; } + buf = malloc_fn((size_t)sz+1); /* +1 trailing '\0' for str funcs */ + if (NULL == buf) break; + + if (sz) { + ssize_t rd = 0; + off_t off = 0; + do { + rd = read(fd, buf+off, (size_t)(sz-off)); + } while (rd > 0 ? (off += rd) != sz : rd < 0 && errno == EINTR); + if (off != sz) { /*(file truncated?)*/ + if (rd >= 0) errno = EIO; + break; + } + } + } + else { + /* attempt to read from non-regular file + * e.g. FIFO/pipe from shell HERE doc (turns into e.g. "/dev/fd/63") + * Note: read() might block! */ + #ifndef _WIN32 + #ifdef O_NONBLOCK + /*(else read() might err EAGAIN Resource temporarily unavailable)*/ + fcntl(fd, F_SETFL, (O_RDONLY | FDEVENT_O_FLAGS) & ~O_NONBLOCK); + #endif + #endif + ssize_t rd; + off_t bsz = 0; + if (*lim == 0) + *lim = 32*1024*1024; /* set arbitrary limit, if not specified */ + do { + if (bsz <= sz+2) { + if (bsz == *lim) { rd = -1; errno = EOVERFLOW; break; } + bsz = bsz ? (bsz << 1) : 65536; + if (bsz > *lim) bsz = *lim; + char *nbuf = malloc_fn((size_t)bsz); + if (NULL == nbuf) { rd = -1; break; } + if (buf) { + memcpy(nbuf, buf, sz); + ck_memzero(buf, (size_t)sz); + free_fn(buf); + } + buf = nbuf; + } + rd = read(fd, buf+sz, (size_t)(bsz-sz-1)); + } while (rd > 0 ? (sz += rd) : rd < 0 && errno == EINTR); + if (rd != 0) break; } buf[sz] = '\0'; |