diff --git a/configure b/configure index 5209704..11e16ac 100755 --- a/configure +++ b/configure @@ -18220,7 +18220,7 @@ fi done -for ac_header in dlfcn.h ltdl.h sys/mman.h +for ac_header in dlfcn.h ltdl.h sys/mman.h sys/uio.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -18296,7 +18296,7 @@ _ACEOF fi done -for ac_func in isatty mmap munmap +for ac_func in isatty mmap munmap readv writev do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index 87cd3b7..b0f26f7 100644 --- a/configure.ac +++ b/configure.ac @@ -120,7 +120,7 @@ dnl check header files. AC_HEADER_STDC AC_CHECK_HEADERS([stddef.h wchar.h wctype.h errno.h signal.h fcntl.h dirent.h]) AC_CHECK_HEADERS([time.h sys/time.h utime.h spawn.h execinfo.h ucontext.h]) -AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h]) +AC_CHECK_HEADERS([dlfcn.h ltdl.h sys/mman.h sys/uio.h]) dnl check data types dnl AC_CHECK_TYPE([wchar_t], @@ -136,7 +136,7 @@ AC_CHECK_FUNCS([backtrace backtrace_symbols]) AC_CHECK_FUNCS([makecontext swapcontext getcontext setcontext]) AC_CHECK_FUNCS([clock_nanosleep nanosleep usleep]) AC_CHECK_FUNCS([snprintf _vsnprintf _vsnwprintf]) -AC_CHECK_FUNCS([isatty mmap munmap]) +AC_CHECK_FUNCS([isatty mmap munmap readv writev]) save_LIBS="$LIBS" AC_SEARCH_LIBS([dlopen], [dl dld], [ diff --git a/lib/hcl-cfg.h.in b/lib/hcl-cfg.h.in index dd346c7..8f7f1ca 100644 --- a/lib/hcl-cfg.h.in +++ b/lib/hcl-cfg.h.in @@ -117,6 +117,9 @@ /* Define to 1 if you have the `quadmath_snprintf' function. */ #undef HAVE_QUADMATH_SNPRINTF +/* Define to 1 if you have the `readv' function. */ +#undef HAVE_READV + /* Define to 1 if you have the `roundq' function. */ #undef HAVE_ROUNDQ @@ -183,6 +186,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + /* Define to 1 if you have the `tanhq' function. */ #undef HAVE_TANHQ @@ -213,6 +219,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H +/* Define to 1 if you have the `writev' function. */ +#undef HAVE_WRITEV + /* Define to 1 if you have the `_vsnprintf' function. */ #undef HAVE__VSNPRINTF diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 79d48e4..2686b36 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -32,8 +32,9 @@ #include #include -#define TOKEN_NAME_ALIGN 64 -#define WID_MAP_ALIGN 512 +#define HCL_SERVER_TOKEN_NAME_ALIGN 64 +#define HCL_SERVER_WID_MAP_ALIGN 512 +#define HCL_SERVER_PROTO_REPLY_BUF_SIZE 1300 #if defined(_WIN32) # include @@ -86,6 +87,9 @@ # if defined(HAVE_SYS_MMAN_H) # include # endif +# if defined(HAVE_SYS_UIO_H) +# include +# endif # include # include @@ -93,7 +97,6 @@ # include # include # include -# include # include #endif @@ -183,8 +186,6 @@ enum hcl_server_proto_req_state_t HCL_SERVER_PROTO_REQ_IN_BLOCK_LEVEL }; -#define HCL_SERVER_PROTO_REPLY_BUF_SIZE 1300 - enum hcl_server_proto_reply_type_t { HCL_SERVER_PROTO_REPLY_SIMPLE = 0, @@ -1278,7 +1279,7 @@ static HCL_INLINE int add_token_char (hcl_server_proto_t* proto, hcl_ooch_t c) hcl_ooch_t* tmp; hcl_oow_t capa; - capa = HCL_ALIGN_POW2(proto->tok.len + 1, TOKEN_NAME_ALIGN); + capa = HCL_ALIGN_POW2(proto->tok.len + 1, HCL_SERVER_TOKEN_NAME_ALIGN); tmp = (hcl_ooch_t*)HCL_MMGR_REALLOC(proto->worker->server->mmgr, proto->tok.ptr, capa * HCL_SIZEOF(*tmp)); if (!tmp) { @@ -1582,6 +1583,18 @@ int hcl_server_proto_handle_request (hcl_server_proto_t* proto) case HCL_SERVER_PROTO_TOKEN_SCRIPT: { hcl_oop_t obj; + hcl_ooci_t c; + + /* do a special check bypassing get_token(). it checks if the script contents + * come on the same line as .SCRIPT */ + GET_CHAR_TO (proto, c); + while (is_spacechar(c)) GET_CHAR_TO (proto, c); + if (c == HCL_OOCI_EOF || c == '\n') + { + HCL_LOG0 (proto->hcl, SERVER_LOGMASK_ERROR, "No contents on the .SCRIPT line\n"); + return -1; + } + UNGET_LAST_CHAR (proto); if (proto->req.state == HCL_SERVER_PROTO_REQ_IN_TOP_LEVEL) hcl_reset(proto->hcl); @@ -1785,7 +1798,7 @@ static HCL_INLINE int prepare_to_acquire_wid (hcl_server_t* server) HCL_ASSERT (server->dummy_hcl, server->wid_map.free_first == HCL_SERVER_WID_INVALID); HCL_ASSERT (server->dummy_hcl, server->wid_map.free_last == HCL_SERVER_WID_INVALID); - new_capa = HCL_ALIGN_POW2(server->wid_map.capa + 1, WID_MAP_ALIGN); + new_capa = HCL_ALIGN_POW2(server->wid_map.capa + 1, HCL_SERVER_WID_MAP_ALIGN); if (new_capa > HCL_SERVER_WID_MAX) { if (server->wid_map.capa >= HCL_SERVER_WID_MAX) @@ -2029,7 +2042,6 @@ void hcl_server_logufmt (hcl_server_t* server, unsigned int mask, const hcl_uch_ va_end (ap); } - static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* bfmt, ...) { hcl_t* hcl = server->dummy_hcl; diff --git a/lib/main.c b/lib/main.c index 2a16528..623a2ff 100644 --- a/lib/main.c +++ b/lib/main.c @@ -144,6 +144,12 @@ struct xtn_t int logfd; unsigned int logmask; int logfd_istty; + + struct + { + hcl_bch_t buf[4096]; + hcl_oow_t len; + } logbuf; int reader_istty; @@ -511,7 +517,7 @@ static void free_heap (hcl_t* hcl, void* ptr) #endif } -static int write_all (int fd, const char* ptr, hcl_oow_t len) +static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len) { while (len > 0) { @@ -545,6 +551,71 @@ static int write_all (int fd, const char* ptr, hcl_oow_t len) return 0; } + +static int write_log (hcl_t* hcl, const hcl_bch_t* ptr, hcl_oow_t len) +{ + xtn_t* xtn; + + xtn = hcl_getxtn(hcl); + + while (len > 0) + { + if (xtn->logbuf.len > 0) + { + hcl_oow_t rcapa, cplen; + + rcapa = HCL_COUNTOF(xtn->logbuf.buf) - xtn->logbuf.len; + cplen = (len >= rcapa)? rcapa: len; + + memcpy (&xtn->logbuf.buf[xtn->logbuf.len], ptr, cplen); + xtn->logbuf.len += cplen; + ptr += cplen; + len -= cplen; + + if (xtn->logbuf.len >= HCL_COUNTOF(xtn->logbuf.buf)) + { + int n; + n = write_all(xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len); + xtn->logbuf.len = 0; + if (n <= -1) return -1; + } + } + else + { + hcl_oow_t rcapa; + + rcapa = HCL_COUNTOF(xtn->logbuf.buf); + if (len >= rcapa) + { + if (write_all(xtn->logfd, ptr, rcapa) <= -1) return -1; + ptr += rcapa; + len -= rcapa; + } + else + { + memcpy (xtn->logbuf.buf, ptr, len); + xtn->logbuf.len += len; + ptr += len; + len -= len; + + } + } + } + + return 0; +} + +static void flush_log (hcl_t* hcl) +{ + xtn_t* xtn; + xtn = hcl_getxtn(hcl); + if (xtn->logbuf.len > 0) + { + write_all (xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len); + xtn->logbuf.len = 0; + } +} + static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len) { hcl_bch_t buf[256]; @@ -604,14 +675,14 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl tslen = 25; } #endif - write_all (logfd, ts, tslen); + write_log (hcl, ts, tslen); } if (xtn->logfd_istty) { - if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); - else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); - else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); + if (mask & HCL_LOG_FATAL) write_log (hcl, "\x1B[1;31m", 7); + else if (mask & HCL_LOG_ERROR) write_log (hcl, "\x1B[1;32m", 7); + else if (mask & HCL_LOG_WARN) write_log (hcl, "\x1B[1;33m", 7); } #if defined(HCL_OOCH_IS_UCH) @@ -633,7 +704,7 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl HCL_ASSERT (hcl, ucslen > 0); /* if this fails, the buffer size must be increased */ /* attempt to write all converted characters */ - if (write_all (logfd, buf, bcslen) <= -1) break; + if (write_log (hcl, buf, bcslen) <= -1) break; if (n == 0) break; else @@ -649,13 +720,15 @@ static void log_write (hcl_t* hcl, unsigned int mask, const hcl_ooch_t* msg, hcl } } #else - write_all (logfd, msg, len); + write_log (hcl, msg, len); #endif if (xtn->logfd_istty) { - if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); + if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_log (hcl, "\x1B[0m", 4); } + + flush_log (hcl); } diff --git a/lib/main2.c b/lib/main2.c index fe74ddc..640da59 100644 --- a/lib/main2.c +++ b/lib/main2.c @@ -43,6 +43,9 @@ #if defined(HAVE_SIGNAL_H) # include #endif +#if defined(HAVE_SYS_UIO_H) +# include +#endif #include #include @@ -55,6 +58,12 @@ struct server_xtn_t int logfd; unsigned int logmask; int logfd_istty; + + struct + { + hcl_bch_t buf[4096]; + hcl_oow_t len; + } logbuf; }; /* ========================================================================= */ @@ -83,7 +92,7 @@ static hcl_mmgr_t sys_mmgr = }; /* ========================================================================= */ -static int write_all (int fd, const char* ptr, hcl_oow_t len) +static int write_all (int fd, const hcl_bch_t* ptr, hcl_oow_t len) { while (len > 0) { @@ -117,6 +126,70 @@ static int write_all (int fd, const char* ptr, hcl_oow_t len) return 0; } + +static int write_log (hcl_server_t* server, const hcl_bch_t* ptr, hcl_oow_t len) +{ + server_xtn_t* xtn; + + + xtn = hcl_server_getxtn(server); + + while (len > 0) + { + if (xtn->logbuf.len > 0) + { + hcl_oow_t rcapa, cplen; + + rcapa = HCL_COUNTOF(xtn->logbuf.buf) - xtn->logbuf.len; + cplen = (len >= rcapa)? rcapa: len; + + memcpy (&xtn->logbuf.buf[xtn->logbuf.len], ptr, cplen); + xtn->logbuf.len += cplen; + ptr += cplen; + len -= cplen; + + if (xtn->logbuf.len >= HCL_COUNTOF(xtn->logbuf.buf)) + { + write_all(xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len); + xtn->logbuf.len = 0; + } + } + else + { + hcl_oow_t rcapa; + + rcapa = HCL_COUNTOF(xtn->logbuf.buf); + if (len >= rcapa) + { + write_all (xtn->logfd, ptr, rcapa); + ptr += rcapa; + len -= rcapa; + } + else + { + memcpy (xtn->logbuf.buf, ptr, len); + xtn->logbuf.len += len; + ptr += len; + len -= len; + + } + } + } + + return 0; +} + +static void flush_log (hcl_server_t* server) +{ + server_xtn_t* xtn; + xtn = hcl_server_getxtn(server); + if (xtn->logbuf.len > 0) + { + write_all (xtn->logfd, xtn->logbuf.buf, xtn->logbuf.len); + xtn->logbuf.len = 0; + } +} + static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, const hcl_ooch_t* msg, hcl_oow_t len) { hcl_bch_t buf[256]; @@ -154,7 +227,6 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c size_t tslen; struct tm tm, *tmp; - now = time(NULL); tmp = localtime_r (&now, &tm); @@ -170,21 +242,21 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c } /* TODO: less write system calls by having a buffer */ - write_all (logfd, ts, tslen); + write_log (server, ts, tslen); if (wid != HCL_SERVER_WID_INVALID) { /* TODO: check if the underlying snprintf support %zd */ tslen = snprintf (ts, sizeof(ts), "[%zu] ", wid); - write_all (logfd, ts, tslen); + write_log (server, ts, tslen); } } if (xtn->logfd_istty) { - if (mask & HCL_LOG_FATAL) write_all (logfd, "\x1B[1;31m", 7); - else if (mask & HCL_LOG_ERROR) write_all (logfd, "\x1B[1;32m", 7); - else if (mask & HCL_LOG_WARN) write_all (logfd, "\x1B[1;33m", 7); + if (mask & HCL_LOG_FATAL) write_log (server, "\x1B[1;31m", 7); + else if (mask & HCL_LOG_ERROR) write_log (server, "\x1B[1;32m", 7); + else if (mask & HCL_LOG_WARN) write_log (server, "\x1B[1;33m", 7); } #if defined(HCL_OOCH_IS_UCH) @@ -207,7 +279,7 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c /*assert (ucslen > 0);*/ /* attempt to write all converted characters */ - if (write_all(logfd, buf, bcslen) <= -1) break; + if (write_log(server, buf, bcslen) <= -1) break; if (n == 0) break; else @@ -223,13 +295,15 @@ static void log_write (hcl_server_t* server, hcl_oow_t wid, unsigned int mask, c } } #else - write_all (logfd, msg, len); + write_log (server, msg, len); #endif if (xtn->logfd_istty) { - if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_all (logfd, "\x1B[0m", 4); + if (mask & (HCL_LOG_FATAL | HCL_LOG_ERROR | HCL_LOG_WARN)) write_log (server, "\x1B[0m", 4); } + + flush_log (server); } /* ========================================================================= */