diff --git a/.gitignore b/.gitignore index 5ddf8cbe..ad0ed0d7 100644 --- a/.gitignore +++ b/.gitignore @@ -43,7 +43,6 @@ m4/ missing mod_ssi_exprparser.c mod_ssi_exprparser.h -proc_open scgi-responder sconsbuild/ stamp-h1 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63c872d5..70f614e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -604,7 +604,6 @@ add_executable(lighttpd configfile.c configparser.c request.c - proc_open.c ${COMMON_SRC} ) set(L_INSTALL_TARGETS ${L_INSTALL_TARGETS} lighttpd) diff --git a/src/Makefile.am b/src/Makefile.am index 4bff06bf..b662b69f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ AM_CFLAGS = $(FAM_CFLAGS) $(LIBUNWIND_CFLAGS) -noinst_PROGRAMS=proc_open test_buffer test_base64 test_configfile test_request +noinst_PROGRAMS=test_buffer test_base64 test_configfile test_request sbin_PROGRAMS=lighttpd lighttpd-angel LEMON=$(top_builddir)/src/lemon$(BUILD_EXEEXT) @@ -84,7 +84,7 @@ src = server.c response.c connections.c \ inet_ntop_cache.c \ network.c \ network_write.c \ - configfile.c configparser.c proc_open.c + configfile.c configparser.c lib_LTLIBRARIES = @@ -397,7 +397,7 @@ hdr = server.h base64.h buffer.h network.h log.h http_kv.h keyvalue.h \ rand.h \ sys-endian.h sys-mmap.h sys-socket.h sys-strings.h \ mod_cml.h mod_cml_funcs.h \ - safe_memclear.h sock_addr.h splaytree.h proc_open.h status_counter.h \ + safe_memclear.h sock_addr.h splaytree.h status_counter.h \ mod_magnet_cache.h @@ -511,10 +511,6 @@ lighttpd_LDFLAGS = -export-dynamic endif -proc_open_SOURCES = proc_open.c buffer.c -proc_open_LDADD = $(LIBUNWIND_LIBS) -proc_open_CPPFLAGS= -DDEBUG_PROC_OPEN - test_buffer_SOURCES = test_buffer.c buffer.c test_buffer_LDADD = $(LIBUNWIND_LIBS) diff --git a/src/SConscript b/src/SConscript index 44c228ee..ffcbb3df 100644 --- a/src/SConscript +++ b/src/SConscript @@ -83,7 +83,7 @@ src = Split("server.c response.c connections.c \ inet_ntop_cache.c \ network.c \ network_write.c \ - configfile.c configparser.c request.c proc_open.c") + configfile.c configparser.c request.c") lemon = env.Program('lemon', 'lemon.c', LIBS = GatherLibs(env)) diff --git a/src/array.c b/src/array.c index ba67acf0..cd88ac05 100644 --- a/src/array.c +++ b/src/array.c @@ -4,7 +4,6 @@ #include "buffer.h" #include -#include #include #include @@ -317,6 +316,10 @@ int array_is_kvstring(array *a) { return 1; } + + +#include + void array_print_indent(int depth) { int i; for (i = 0; i < depth; i ++) { diff --git a/src/configfile.c b/src/configfile.c index b53c162f..c3405439 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -7,7 +7,6 @@ #include "configparser.h" #include "configfile.h" -#include "proc_open.h" #include "request.h" #include "stat_cache.h" @@ -1103,9 +1102,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * return 1; } else if (t->offset < t->size) { - fprintf(stderr, "%s.%d: %d, %s\n", - __FILE__, __LINE__, - tid, token->ptr); + log_error_write(srv, __FILE__, __LINE__, "Dsb", tid, ",", token); } return 0; } @@ -1261,9 +1258,10 @@ static char* getCWD(void) { int config_parse_cmd(server *srv, config_t *context, const char *cmd) { tokenizer_t t; - int ret; + int ret = 0; + FILE *fp; buffer *source; - buffer *out; + buffer *out = srv->tmp_buf; char *oldpwd; if (NULL == (oldpwd = getCWD())) { @@ -1282,19 +1280,38 @@ int config_parse_cmd(server *srv, config_t *context, const char *cmd) { } source = buffer_init_string(cmd); - out = buffer_init(); - if (0 != proc_open_buffer(cmd, NULL, out, NULL)) { - log_error_write(srv, __FILE__, __LINE__, "sbss", - "opening", source, "failed:", strerror(errno)); + fp = popen(cmd, "r"); + if (NULL == fp) { + log_error_write(srv, __FILE__, __LINE__, "SSss", + "popen \"", cmd, "\"failed:", strerror(errno)); ret = -1; - } else { + } + else { + size_t rd; + buffer_string_set_length(out, 0); + do { + rd = fread(buffer_string_prepare_append(out, 1023), 1, 1023, fp); + buffer_commit(out, rd); + } while (0 != rd && !ferror(fp)); + if (0 != rd || !feof(fp)) { + log_error_write(srv, __FILE__, __LINE__, "SSss", + "fread \"", cmd, "\"failed:", strerror(errno)); + ret = -1; + } + if (0 != pclose(fp)) { + log_error_write(srv, __FILE__, __LINE__, "SSss", + "pclose \"", cmd, "\"failed:", strerror(errno)); + ret = -1; + } + } + + if (-1 != ret) { tokenizer_init(&t, source, CONST_BUF_LEN(out)); ret = config_parse(srv, context, &t); } buffer_free(source); - buffer_free(out); if (0 != chdir(oldpwd)) { log_error_write(srv, __FILE__, __LINE__, "sss", "cannot change directory to", oldpwd, strerror(errno)); diff --git a/src/data_array.c b/src/data_array.c index b375276f..6c5a617b 100644 --- a/src/data_array.c +++ b/src/data_array.c @@ -3,7 +3,6 @@ #include "array.h" #include -#include #include static data_unset *data_array_copy(const data_unset *s) { diff --git a/src/meson.build b/src/meson.build index eb19a496..05c66ff0 100644 --- a/src/meson.build +++ b/src/meson.build @@ -585,7 +585,6 @@ main_src = [ 'inet_ntop_cache.c', 'network_write.c', 'network.c', - 'proc_open.c', 'request.c', 'response.c', 'server.c', diff --git a/src/proc_open.c b/src/proc_open.c deleted file mode 100644 index 17224297..00000000 --- a/src/proc_open.c +++ /dev/null @@ -1,411 +0,0 @@ -#include "first.h" - -#include "proc_open.h" - -#include -#include -#include -#include - -#ifdef WIN32 -# include -# include -#else -# include -# include -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - - -#ifdef WIN32 -/* {{{ win32 stuff */ -# define SHELLENV "ComSpec" -# define SECURITY_DC , SECURITY_ATTRIBUTES *security -# define SECURITY_CC , security -# define pipe(pair) (CreatePipe(&pair[0], &pair[1], security, 2048L) ? 0 : -1) -static inline HANDLE dup_handle(HANDLE src, BOOL inherit, BOOL closeorig) -{ - HANDLE copy, self = GetCurrentProcess(); - - if (!DuplicateHandle(self, src, self, ©, 0, inherit, DUPLICATE_SAME_ACCESS | - (closeorig ? DUPLICATE_CLOSE_SOURCE : 0))) - return NULL; - return copy; -} -# define close_descriptor(fd) CloseHandle(fd) -static void pipe_close_parent(pipe_t *p) { - /* don't let the child inherit the parent side of the pipe */ - p->parent = dup_handle(p->parent, FALSE, TRUE); -} -static void pipe_close_child(pipe_t *p) { - close_descriptor(p->child); - p->fd = _open_osfhandle((long)p->parent, - (p->fd == 0 ? O_RDONLY : O_WRONLY)|O_BINARY); -} -/* }}} */ -#else /* WIN32 */ -/* {{{ unix way */ -# define SHELLENV "SHELL" -# define SECURITY_DC -# define SECURITY_CC -# define close_descriptor(fd) close(fd) -static void pipe_close_parent(pipe_t *p) { - /* don't close stdin */ - close_descriptor(p->parent); - if (dup2(p->child, p->fd) != p->fd) { - perror("pipe_child dup2"); - } else { - close_descriptor(p->child); - p->child = p->fd; - } -} -static void pipe_close_child(pipe_t *p) { - close_descriptor(p->child); - p->fd = p->parent; -} -/* }}} */ -#endif /* WIN32 */ - -/* {{{ pipe_close */ -static void pipe_close(pipe_t *p) { - close_descriptor(p->parent); - close_descriptor(p->child); -#ifdef WIN32 - close(p->fd); -#endif -} -/* }}} */ -/* {{{ pipe_open */ -static int pipe_open(pipe_t *p, int fd SECURITY_DC) { - descriptor_t newpipe[2]; - - if (0 != pipe(newpipe)) { - fprintf(stderr, "can't open pipe"); - return -1; - } - if (0 == fd) { - p->parent = newpipe[1]; /* write */ - p->child = newpipe[0]; /* read */ - } else { - p->parent = newpipe[0]; /* read */ - p->child = newpipe[1]; /* write */ - } - p->fd = fd; - - return 0; -} -/* }}} */ - -/* {{{ proc_open_pipes */ -static int proc_open_pipes(proc_handler_t *proc SECURITY_DC) { - if (pipe_open(&(proc->in), 0 SECURITY_CC) != 0) { - return -1; - } - if (pipe_open(&(proc->out), 1 SECURITY_CC) != 0) { - return -1; - } - if (pipe_open(&(proc->err), 2 SECURITY_CC) != 0) { - return -1; - } - return 0; -} -/* }}} */ -/* {{{ proc_close_pipes */ -static void proc_close_pipes(proc_handler_t *proc) { - pipe_close(&proc->in); - pipe_close(&proc->out); - pipe_close(&proc->err); -} -/* }}} */ -/* {{{ proc_close_parents */ -static void proc_close_parents(proc_handler_t *proc) { - pipe_close_parent(&proc->in); - pipe_close_parent(&proc->out); - pipe_close_parent(&proc->err); -} -/* }}} */ -/* {{{ proc_close_childs */ -static void proc_close_childs(proc_handler_t *proc) { - pipe_close_child(&proc->in); - pipe_close_child(&proc->out); - pipe_close_child(&proc->err); -} -/* }}} */ - -#ifdef WIN32 -/* {{{ proc_close */ -int proc_close(proc_handler_t *proc) { - proc_pid_t child = proc->child; - DWORD wstatus; - - proc_close_pipes(proc); - WaitForSingleObject(child, INFINITE); - GetExitCodeProcess(child, &wstatus); - CloseHandle(child); - - return wstatus; -} -/* }}} */ -/* {{{ proc_open */ -int proc_open(proc_handler_t *proc, const char *command) { - PROCESS_INFORMATION pi; - STARTUPINFO si; - BOOL procok; - SECURITY_ATTRIBUTES security; - const char *shell = NULL; - const char *windir = NULL; - buffer *cmdline; - - if (NULL == (shell = getenv(SHELLENV)) && - NULL == (windir = getenv("SystemRoot")) && - NULL == (windir = getenv("windir"))) { - fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV); - return -1; - } - - /* we use this to allow the child to inherit handles */ - memset(&security, 0, sizeof(security)); - security.nLength = sizeof(security); - security.bInheritHandle = TRUE; - security.lpSecurityDescriptor = NULL; - - if (proc_open_pipes(proc, &security) != 0) { - return -1; - } - proc_close_parents(proc); - - memset(&si, 0, sizeof(si)); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESTDHANDLES; - si.hStdInput = proc->in.child; - si.hStdOutput = proc->out.child; - si.hStdError = proc->err.child; - - memset(&pi, 0, sizeof(pi)); - - cmdline = buffer_init(); - if (shell) { - buffer_append_string(cmdline, shell); - } else { - buffer_append_string(cmdline, windir); - buffer_append_string_len(cmdline, CONST_STR_LEN("\\system32\\cmd.exe")); - } - buffer_append_string_len(cmdline, CONST_STR_LEN(" /c ")); - buffer_append_string(cmdline, command); - procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE, - NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); - - if (FALSE == procok) { - fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr); - buffer_free(cmdline); - return -1; - } - buffer_free(cmdline); - - proc->child = pi.hProcess; - CloseHandle(pi.hThread); - - proc_close_childs(proc); - - return 0; -} -/* }}} */ -#else /* WIN32 */ -/* {{{ proc_close */ -int proc_close(proc_handler_t *proc) { - pid_t child = proc->child; - int wstatus; - pid_t wait_pid; - - proc_close_pipes(proc); - - do { - wait_pid = waitpid(child, &wstatus, 0); - } while (wait_pid == -1 && errno == EINTR); - - if (wait_pid == -1) { - return -1; - } else { - if (WIFEXITED(wstatus)) - wstatus = WEXITSTATUS(wstatus); - } - - return wstatus; -} -/* }}} */ -/* {{{ proc_open */ -int proc_open(proc_handler_t *proc, const char *command) { - pid_t child; - const char *shell; - - if (NULL == (shell = getenv(SHELLENV))) { - shell = "/bin/sh"; - } - - if (proc_open_pipes(proc) != 0) { - return -1; - } - - /* the unix way */ - - child = fork(); - - if (child == 0) { - /* this is the child process */ - - /* close those descriptors that we just opened for the parent stuff, - * dup new descriptors into required descriptors and close the original - * cruft - */ - proc_close_parents(proc); - - execl(shell, shell, "-c", command, (char *)NULL); - fprintf(stderr, "failed to execute shell: %s -c %s: %s\n", shell, command, strerror(errno)); - _exit(127); - - } else if (child < 0) { - fprintf(stderr, "failed to forking"); - proc_close(proc); - return -1; - - } else { - proc->child = child; - proc_close_childs(proc); - return 0; - } -} -/* }}} */ -#endif /* WIN32 */ - -/* {{{ proc_read_fd_to_buffer */ -static void proc_read_fd_to_buffer(int fd, buffer *b) { - ssize_t s; - - for (;;) { - buffer_string_prepare_append(b, 1024); - if ((s = read(fd, (void *)(b->ptr + buffer_string_length(b)), buffer_string_space(b))) <= 0) { - break; - } - buffer_commit(b, s); - } -} -/* }}} */ -/* {{{ proc_open_buffer */ -int proc_open_buffer(const char *command, buffer *in, buffer *out, buffer *err) { - proc_handler_t proc; - - if (proc_open(&proc, command) != 0) { - return -1; - } - - if (in) { - if (write(proc.in.fd, CONST_BUF_LEN(in)) < 0) { - perror("error writing pipe"); - return -1; - } - } - pipe_close(&proc.in); - - if (out) { - proc_read_fd_to_buffer(proc.out.fd, out); - } - pipe_close(&proc.out); - - if (err) { - proc_read_fd_to_buffer(proc.err.fd, err); - } else { - buffer *tmp = buffer_init(); - proc_read_fd_to_buffer(proc.err.fd, tmp); - if (!buffer_string_is_empty(tmp) && write(2, CONST_BUF_LEN(tmp)) < 0) { - perror("error writing pipe"); - buffer_free(tmp); - return -1; - } - buffer_free(tmp); - } - pipe_close(&proc.err); - - proc_close(&proc); - - return 0; -} -/* }}} */ - -/* {{{ test */ -#ifdef DEBUG_PROC_OPEN -int main(void) { - proc_handler_t proc; - buffer *in = buffer_init(), *out = buffer_init(), *err = buffer_init(); - int wstatus; - -#define FREE() do { \ - buffer_free(in); \ - buffer_free(out); \ - buffer_free(err); \ -} while (0) - -#define RESET() do { \ - buffer_reset(in); \ - buffer_reset(out); \ - buffer_reset(err); \ - wstatus = proc_close(&proc); \ - if (0&&wstatus != 0) { \ - fprintf(stdout, "exitstatus %d\n", wstatus); \ - return __LINE__ - 200; \ - } \ -} while (0) - -#define ERROR_OUT() do { \ - fprintf(stdout, "failed opening proc\n"); \ - wstatus = proc_close(&proc); \ - fprintf(stdout, "exitstatus %d\n", wstatus); \ - FREE(); \ - return __LINE__ - 300; \ -} while (0) - -#ifdef WIN32 -#define CMD_CAT "pause" -#else -#define CMD_CAT "cat" -#endif - - do { - fprintf(stdout, "test: echo 123 without read\n"); - if (proc_open(&proc, "echo 321") != 0) { - ERROR_OUT(); - } - close_descriptor(proc.in.parent); - close_descriptor(proc.out.parent); - close_descriptor(proc.err.parent); - RESET(); - - fprintf(stdout, "test: echo 321 with read\n"); fflush(stdout); - if (proc_open_buffer("echo 321", NULL, out, err) != 0) { - ERROR_OUT(); - } - fprintf(stdout, "result: ->%s<-\n\n", out->ptr); fflush(stdout); - RESET(); - - fprintf(stdout, "test: echo 123 | " CMD_CAT "\n"); fflush(stdout); - buffer_copy_string_len(in, CONST_STR_LEN("123\n")); - if (proc_open_buffer(CMD_CAT, in, out, err) != 0) { - ERROR_OUT(); - } - fprintf(stdout, "result: ->%s<-\n\n", out->ptr); fflush(stdout); - RESET(); - } while (0); - -#undef RESET -#undef ERROR_OUT - - fprintf(stdout, "ok\n"); - - FREE(); - return 0; -} -#endif /* DEBUG_PROC_OPEN */ -/* }}} */ - diff --git a/src/proc_open.h b/src/proc_open.h deleted file mode 100644 index e4b022bf..00000000 --- a/src/proc_open.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LI_PROC_OPEN_H -#define LI_PROC_OPEN_H -#include "first.h" - -#include "buffer.h" - -#ifdef WIN32 -#include -typedef HANDLE descriptor_t; -typedef HANDLE proc_pid_t; -#else -typedef int descriptor_t; -typedef pid_t proc_pid_t; -#endif - -typedef struct { - descriptor_t parent, child; - int fd; -} pipe_t; - -typedef struct { - pipe_t in, out, err; - proc_pid_t child; -} proc_handler_t; - -int proc_close(proc_handler_t *ht); -int proc_open(proc_handler_t *ht, const char *command); -int proc_open_buffer(const char *command, buffer *in, buffer *out, buffer *err); - -#endif