exported hcl_seterrbfmtv(), hcl_seterrufmtv()

added hcl_server_seterrbfmt(), hcl_server_seterrufmt(), hcl_server_seterrbfmtv(), hcl_server_seterrufmtv()
added socket address conversion functions
This commit is contained in:
2018-03-14 14:40:05 +00:00
parent 72fe88548f
commit 25b71a4800
21 changed files with 1891 additions and 264 deletions

View File

@ -43,6 +43,7 @@ pkglib_LTLIBRARIES = libhcl.la
libhcl_la_SOURCES = \
hcl-prv.h \
logfmtv.h \
sa-utl.h \
bigint.c \
comp.c \
debug.c \
@ -69,12 +70,14 @@ libhcl_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcl_la_LIBADD = $(LIBADD_LIB_COMMON)
libhcl_la_DEPENDENCIES =
if ENABLE_HCLS
pkglib_LTLIBRARIES += libhcls.la
libhcls_la_SOURCES = hcl-s.c hcl-s.h
libhcls_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhcls_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcls_la_LIBADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS)
libhcls_la_DEPENDENCIES =
endif
if ENABLE_STATIC_MODULE
libhcl_la_LIBADD += -lhcl-arr
@ -94,6 +97,7 @@ if ENABLE_STATIC_MODULE
hcl_DEPENDENCIES = libhcl.la
endif
if ENABLE_HCLS
bin_PROGRAMS += hcls
hcls_SOURCES = main2.c
hcls_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
@ -102,6 +106,7 @@ hcls_LDADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS) -lhcl -lhcls #-ldyncall_s
if ENABLE_STATIC_MODULE
hcls_DEPENDENCIES = libhcl.la libhcls.la
endif
endif
install-data-hook:
@echo "#ifndef _HCL_CFG_H_" > "$(DESTDIR)$(pkgincludedir)/hcl-cfg.h"

View File

@ -90,18 +90,21 @@ build_triplet = @build@
host_triplet = @host@
@ENABLE_LIBLTDL_TRUE@am__append_1 = $(LTDL_LIBS)
@ENABLE_LIBLTDL_FALSE@am__append_2 = $(DL_LIBS)
@ENABLE_STATIC_MODULE_TRUE@am__append_3 = -lhcl-arr -lhcl-dic \
@ENABLE_HCLS_TRUE@am__append_3 = libhcls.la
@ENABLE_STATIC_MODULE_TRUE@am__append_4 = -lhcl-arr -lhcl-dic \
@ENABLE_STATIC_MODULE_TRUE@ -lhcl-str
@ENABLE_STATIC_MODULE_TRUE@am__append_4 = $(abs_builddir)/../mod/libhcl-arr.la \
@ENABLE_STATIC_MODULE_TRUE@am__append_5 = $(abs_builddir)/../mod/libhcl-arr.la \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libhcl-dic.la \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libhcl-str.la
bin_PROGRAMS = hcl$(EXEEXT) hcls$(EXEEXT)
bin_PROGRAMS = hcl$(EXEEXT) $(am__EXEEXT_1)
@ENABLE_STATIC_MODULE_FALSE@hcl_DEPENDENCIES = $(am__DEPENDENCIES_4)
@ENABLE_STATIC_MODULE_FALSE@hcls_DEPENDENCIES = $(am__DEPENDENCIES_4) \
@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1)
@ENABLE_HCLS_TRUE@am__append_6 = hcls
@ENABLE_HCLS_TRUE@@ENABLE_STATIC_MODULE_FALSE@hcls_DEPENDENCIES = $(am__DEPENDENCIES_4) \
@ENABLE_HCLS_TRUE@@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1)
subdir = lib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_namespace.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_sign.m4 \
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
$(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/ax_pthread.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@ -164,18 +167,22 @@ am__v_lt_1 =
libhcl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libhcl_la_LDFLAGS) $(LDFLAGS) -o $@
am_libhcls_la_OBJECTS = libhcls_la-hcl-s.lo
am__libhcls_la_SOURCES_DIST = hcl-s.c hcl-s.h
@ENABLE_HCLS_TRUE@am_libhcls_la_OBJECTS = libhcls_la-hcl-s.lo
libhcls_la_OBJECTS = $(am_libhcls_la_OBJECTS)
libhcls_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libhcls_la_LDFLAGS) $(LDFLAGS) -o $@
@ENABLE_HCLS_TRUE@am_libhcls_la_rpath = -rpath $(pkglibdir)
@ENABLE_HCLS_TRUE@am__EXEEXT_1 = hcls$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_hcl_OBJECTS = hcl-main.$(OBJEXT)
hcl_OBJECTS = $(am_hcl_OBJECTS)
hcl_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(hcl_LDFLAGS) $(LDFLAGS) -o $@
am_hcls_OBJECTS = hcls-main2.$(OBJEXT)
am__hcls_SOURCES_DIST = main2.c
@ENABLE_HCLS_TRUE@am_hcls_OBJECTS = hcls-main2.$(OBJEXT)
hcls_OBJECTS = $(am_hcls_OBJECTS)
hcls_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -216,8 +223,8 @@ am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libhcl_la_SOURCES) $(libhcls_la_SOURCES) $(hcl_SOURCES) \
$(hcls_SOURCES)
DIST_SOURCES = $(libhcl_la_SOURCES) $(libhcls_la_SOURCES) \
$(hcl_SOURCES) $(hcls_SOURCES)
DIST_SOURCES = $(libhcl_la_SOURCES) $(am__libhcls_la_SOURCES_DIST) \
$(hcl_SOURCES) $(am__hcls_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@ -392,6 +399,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@ -423,7 +431,7 @@ pkginclude_HEADERS = \
hcl-utl.h \
hcl.h
pkglib_LTLIBRARIES = libhcl.la libhcls.la
pkglib_LTLIBRARIES = libhcl.la $(am__append_3)
libhcl_la_SOURCES = \
hcl-prv.h \
logfmtv.h \
@ -451,23 +459,23 @@ libhcl_la_SOURCES = \
libhcl_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhcl_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcl_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_3)
libhcl_la_DEPENDENCIES = $(am__append_4)
libhcls_la_SOURCES = hcl-s.c hcl-s.h
libhcls_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
libhcls_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libhcls_la_LIBADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS)
libhcls_la_DEPENDENCIES =
libhcl_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_4)
libhcl_la_DEPENDENCIES = $(am__append_5)
@ENABLE_HCLS_TRUE@libhcls_la_SOURCES = hcl-s.c hcl-s.h
@ENABLE_HCLS_TRUE@libhcls_la_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
@ENABLE_HCLS_TRUE@libhcls_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
@ENABLE_HCLS_TRUE@libhcls_la_LIBADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS)
@ENABLE_HCLS_TRUE@libhcls_la_DEPENDENCIES =
hcl_SOURCES = main.c
hcl_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
hcl_LDFLAGS = $(LDFLAGS_LIB_COMMON)
hcl_LDADD = $(LIBADD_LIB_COMMON) -lhcl #-ldyncall_s
@ENABLE_STATIC_MODULE_TRUE@hcl_DEPENDENCIES = libhcl.la
hcls_SOURCES = main2.c
hcls_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
hcls_LDFLAGS = $(LDFLAGS_LIB_COMMON)
hcls_LDADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS) -lhcl -lhcls #-ldyncall_s
@ENABLE_STATIC_MODULE_TRUE@hcls_DEPENDENCIES = libhcl.la libhcls.la
@ENABLE_HCLS_TRUE@hcls_SOURCES = main2.c
@ENABLE_HCLS_TRUE@hcls_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)
@ENABLE_HCLS_TRUE@hcls_LDFLAGS = $(LDFLAGS_LIB_COMMON)
@ENABLE_HCLS_TRUE@hcls_LDADD = $(LIBADD_LIB_COMMON) $(PTHREAD_LIBS) -lhcl -lhcls #-ldyncall_s
@ENABLE_HCLS_TRUE@@ENABLE_STATIC_MODULE_TRUE@hcls_DEPENDENCIES = libhcl.la libhcls.la
all: hcl-cfg.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@ -557,7 +565,7 @@ libhcl.la: $(libhcl_la_OBJECTS) $(libhcl_la_DEPENDENCIES) $(EXTRA_libhcl_la_DEPE
$(AM_V_CCLD)$(libhcl_la_LINK) -rpath $(pkglibdir) $(libhcl_la_OBJECTS) $(libhcl_la_LIBADD) $(LIBS)
libhcls.la: $(libhcls_la_OBJECTS) $(libhcls_la_DEPENDENCIES) $(EXTRA_libhcls_la_DEPENDENCIES)
$(AM_V_CCLD)$(libhcls_la_LINK) -rpath $(pkglibdir) $(libhcls_la_OBJECTS) $(libhcls_la_LIBADD) $(LIBS)
$(AM_V_CCLD)$(libhcls_la_LINK) $(am_libhcls_la_rpath) $(libhcls_la_OBJECTS) $(libhcls_la_LIBADD) $(LIBS)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \

View File

@ -264,6 +264,9 @@
/* MB_LEN_MAX */
#undef HCL_MBLEN_MAX
/* offsetof(struct sockaddr, sa_family) */
#undef HCL_OFFSETOF_SA_FAMILY
/* Author */
#undef HCL_PACKAGE_AUTHOR
@ -285,6 +288,12 @@
/* Patch level */
#undef HCL_PACKAGE_VERSION_PATCH
/* PATH_MAX */
#undef HCL_PATH_MAX
/* Define if sa_family_t is signed */
#undef HCL_SA_FAMILY_T_IS_SIGNED
/* sizeof(char) */
#undef HCL_SIZEOF_CHAR
@ -315,9 +324,30 @@
/* sizeof(off_t) */
#undef HCL_SIZEOF_OFF_T
/* sizeof(sa_family_t) */
#undef HCL_SIZEOF_SA_FAMILY_T
/* sizeof(short) */
#undef HCL_SIZEOF_SHORT
/* sizeof(socklen_t) */
#undef HCL_SIZEOF_SOCKLEN_T
/* sizeof(struct sockaddr_dl) */
#undef HCL_SIZEOF_STRUCT_SOCKADDR_DL
/* sizeof(struct sockaddr_in) */
#undef HCL_SIZEOF_STRUCT_SOCKADDR_IN
/* sizeof(struct sockaddr_in6) */
#undef HCL_SIZEOF_STRUCT_SOCKADDR_IN6
/* sizeof(struct sockaddr_ll) */
#undef HCL_SIZEOF_STRUCT_SOCKADDR_LL
/* sizeof(struct sockaddr_un) */
#undef HCL_SIZEOF_STRUCT_SOCKADDR_UN
/* sizeof(void*) */
#undef HCL_SIZEOF_VOID_P
@ -348,6 +378,9 @@
/* sizeof(__uint128_t) */
#undef HCL_SIZEOF___UINT128_T
/* Define if socklen_t is signed */
#undef HCL_SOCKLEN_T_IS_SIGNED
/* Unicode character type size */
#undef HCL_UNICODE_SIZE
@ -357,6 +390,9 @@
/* The size of `MB_LEN_MAX', as computed by valueof. */
#undef NUMVALOF_MB_LEN_MAX
/* The size of `PATH_MAX', as computed by valueof. */
#undef NUMVALOF_PATH_MAX
/* Name of package */
#undef PACKAGE
@ -418,9 +454,30 @@
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
/* The size of `sa_family_t', as computed by sizeof. */
#undef SIZEOF_SA_FAMILY_T
/* The size of `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* The size of `socklen_t', as computed by sizeof. */
#undef SIZEOF_SOCKLEN_T
/* The size of `struct sockaddr_dl', as computed by sizeof. */
#undef SIZEOF_STRUCT_SOCKADDR_DL
/* The size of `struct sockaddr_in', as computed by sizeof. */
#undef SIZEOF_STRUCT_SOCKADDR_IN
/* The size of `struct sockaddr_in6', as computed by sizeof. */
#undef SIZEOF_STRUCT_SOCKADDR_IN6
/* The size of `struct sockaddr_ll', as computed by sizeof. */
#undef SIZEOF_STRUCT_SOCKADDR_LL
/* The size of `struct sockaddr_un', as computed by sizeof. */
#undef SIZEOF_STRUCT_SOCKADDR_UN
/* The size of `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P

View File

@ -29,7 +29,6 @@
#include "hcl.h"
#include "hcl-utl.h"
#include <stdarg.h>
/* you can define this to either 1 or 2 */
#define HCL_BCODE_LONG_PARAM_SIZE 2
@ -661,25 +660,6 @@ typedef hcl_ooi_t (*hcl_outbfmt_t) (
extern "C" {
#endif
/* ========================================================================= */
/* err.c */
/* ========================================================================= */
void hcl_seterrbfmtv (
hcl_t* hcl,
hcl_errnum_t errnum,
const hcl_bch_t* fmt,
va_list ap
);
void hcl_seterrufmtv (
hcl_t* hcl,
hcl_errnum_t errnum,
const hcl_uch_t* fmt,
va_list ap
);
/* ========================================================================= */
/* heap.c */
/* ========================================================================= */

View File

@ -28,13 +28,8 @@
#include "hcl-prv.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <locale.h>
#include <assert.h>
#if defined(_WIN32)
# include <windows.h>
@ -95,7 +90,6 @@
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <pthread.h>
# include <sys/uio.h>
# include <poll.h>
@ -129,13 +123,6 @@
# endif
#endif
typedef union sck_addr_t sck_addr_t;
union sck_addr_t
{
struct sockaddr_in in4;
struct sockaddr_in6 in6;
};
typedef struct bb_t bb_t;
struct bb_t
{
@ -259,12 +246,6 @@ struct hcl_server_t
hcl_errnum_t errnum;
struct
{
union
{
hcl_ooch_t ooch[2048];
hcl_bch_t bch[2048];
hcl_uch_t uch[2048];
} tmpbuf;
hcl_ooch_t buf[2048];
hcl_oow_t len;
} errmsg;
@ -275,8 +256,9 @@ struct hcl_server_t
unsigned int trait;
unsigned int logmask;
hcl_oow_t worker_stack_size;
hcl_oow_t worker_idle_timeout;
hcl_ntime_t worker_idle_timeout;
hcl_oow_t actor_heap_size;
hcl_ntime_t actor_max_runtime;
} cfg;
struct
@ -431,7 +413,7 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg)
}
else if (n >= 1) break;
/* TOOD: idle timeout check - compute idling time and check it against server->cfg.idle_timeout */
/* TOOD: idle timeout check - compute idling time and check it against server->cfg.worker_idle_timeout */
}
x = recv(bb->fd, &bb->buf[bb->len], HCL_COUNTOF(bb->buf) - bb->len, 0);
@ -911,30 +893,62 @@ static void vm_checkbc (hcl_t* hcl, hcl_oob_t bcode)
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
if (xtn->proto->worker->server->stopreq) hcl_abort(hcl);
/* TODO: check how to this vm has been running. too long? abort it */
/* TODO: check if the worker connection is ok? if not, abort it */
/* check agains xtn->proto->worker->server->cfg.actor_max_runtime */
}
/*
static void gc_hcl (hcl_t* hcl)
{
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
}
static void fini_hcl (hcl_t* hcl)
{
worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl);
if (xtn->logfd >= 0)
{
close (xtn->logfd);
xtn->logfd = -1;
xtn->logfd_istty = 0;
}
}
*/
/* ========================================================================= */
union sockaddr_t
{
struct sockaddr_in in4;
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
struct sockaddr_in6 in6;
#endif
};
typedef union sockaddr_t sockaddr_t;
#undef char_t
#undef oocs_t
#undef str_to_ipv4
#undef str_to_ipv6
#undef str_to_sockaddr
#define ooch_t hcl_bch_t
#define oocs_t hcl_bcs_t
#define str_to_ipv4 bchars_to_ipv4
#define str_to_ipv6 bchars_to_ipv6
#define str_to_sockaddr bchars_to_sockaddr
#include "sa-utl.h"
#undef ooch_t
#undef oocs_t
#undef str_to_ipv4
#undef str_to_ipv6
#undef str_to_sockaddr
#define ooch_t hcl_uch_t
#define oocs_t hcl_ucs_t
#define str_to_ipv4 uchars_to_ipv4
#define str_to_ipv6 uchars_to_ipv6
#define str_to_sockaddr uchars_to_sockaddr
#include "sa-utl.h"
/* ========================================================================= */
#define HCL_SERVER_PROTO_LOG_MASK (HCL_LOG_ERROR | HCL_LOG_APP)
hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_t* worker)
@ -1044,8 +1058,10 @@ static int write_reply_chunk (hcl_server_proto_t* proto)
/*nwritten = writev(proto->worker->sck, (const struct iovec*)&iov[index], count - index);*/
if (nwritten <= -1)
{
/* error occurred inside the worker thread shouldn't affect the error information
* in the server object. so here, i just log a message */
hcl_logbfmt (proto->hcl, HCL_SERVER_PROTO_LOG_MASK, "sendmsg failure on %d - %hs\n", proto->worker->sck, strerror(errno));
return -1;
return -1;
}
while (index < count && (size_t)nwritten >= iov[index].iov_len)
@ -1591,7 +1607,7 @@ static void free_worker (hcl_server_worker_t* worker)
static void add_hcl_server_worker_to_server (hcl_server_t* server, hcl_server_worker_state_t wstate, hcl_server_worker_t* worker)
{
assert (worker->server == server);
HCL_ASSERT (server->dummy_hcl, worker->server == server);
if (server->worker_list[wstate].tail)
{
@ -1615,7 +1631,7 @@ static void zap_worker_in_server (hcl_server_t* server, hcl_server_worker_t* wor
{
hcl_server_worker_state_t wstate;
assert (worker->server == server);
HCL_ASSERT (server->dummy_hcl, worker->server == server);
wstate = worker->state;
if (worker->prev_worker) worker->prev_worker->next_worker = worker->next_worker;
@ -1637,7 +1653,7 @@ static void* worker_main (void* ctx)
pthread_sigmask (SIG_BLOCK, &set, HCL_NULL);
worker->thr = pthread_self();
worker->proto = hcl_server_proto_open(0, worker); /* TODO: get this from argumen */
worker->proto = hcl_server_proto_open(0, worker);
if (!worker->proto)
{
free_worker (worker);
@ -1711,9 +1727,71 @@ void hcl_server_logufmt (hcl_server_t* server, unsigned int mask, const hcl_uch_
va_end (ap);
}
int hcl_server_start (hcl_server_t* server, const char* addrs)
static void set_err_with_syserr (hcl_server_t* server, int syserr, const char* bfmt, ...)
{
sck_addr_t srv_addr;
hcl_t* hcl = server->dummy_hcl;
hcl_errnum_t errnum;
hcl_oow_t tmplen, tmplen2;
va_list ap;
static hcl_bch_t b_dash[] = { ' ', '-', ' ', '\0' };
static hcl_uch_t u_dash[] = { ' ', '-', ' ', '\0' };
if (hcl->shuterr) return;
errnum = hcl_syserr_to_errnum(syserr);
if (hcl->vmprim.syserrstrb)
{
hcl->vmprim.syserrstrb (hcl, syserr, hcl->errmsg.tmpbuf.bch, HCL_COUNTOF(hcl->errmsg.tmpbuf.bch));
va_start (ap, bfmt);
hcl_seterrbfmtv (hcl, errnum, bfmt, ap);
va_end (ap);
#if defined(HCL_OOCH_IS_BCH)
hcl->errmsg.len += hcl_copybcstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, b_dash);
hcl->errmsg.len += hcl_copybcstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, hcl->errmsg.tmpbuf.bch);
#else
hcl->errmsg.len += hcl_copyucstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, u_dash);
tmplen = hcl_countbcstr(hcl->errmsg.tmpbuf.bch);
tmplen2 = HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len;
hcl_convbtouchars (hcl, hcl->errmsg.tmpbuf.bch, &tmplen, &hcl->errmsg.buf[hcl->errmsg.len], &tmplen2);
hcl->errmsg.len += tmplen2; /* ignore conversion errors */
#endif
}
else
{
HCL_ASSERT (hcl, hcl->vmprim.syserrstru != HCL_NULL);
hcl->vmprim.syserrstru (hcl, syserr, hcl->errmsg.tmpbuf.uch, HCL_COUNTOF(hcl->errmsg.tmpbuf.uch));
va_start (ap, bfmt);
hcl_seterrbfmtv (hcl, errnum, bfmt, ap);
va_end (ap);
#if defined(HCL_OOCH_IS_BCH)
hcl->errmsg.len += hcl_copybcstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, b_dash);
tmplen = hcl_countucstr(hcl->errmsg.tmpbuf.uch);
tmplen2 = HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len;
hcl_convutobchars (hcl, hcl->errmsg.tmpbuf.uch, &tmplen, &hcl->errmsg.buf[hcl->errmsg.len], &tmplen2);
hcl->errmsg.len += tmplen2; /* ignore conversion errors */
#else
hcl->errmsg.len += hcl_copyucstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, u_dash);
hcl->errmsg.len += hcl_copyucstr (&hcl->errmsg.buf[hcl->errmsg.len], HCL_COUNTOF(hcl->errmsg.buf) - hcl->errmsg.len, hcl->errmsg.tmpbuf.uch);
#endif
}
server->errnum = errnum;
hcl_copyoochars (server->errmsg.buf, server->dummy_hcl->errmsg.buf, HCL_COUNTOF(server->errmsg.buf));
server->errmsg.len = server->dummy_hcl->errmsg.len;
}
int hcl_server_start (hcl_server_t* server, const hcl_bch_t* addrs)
{
sockaddr_t srv_addr;
int srv_fd, sck_fam;
int optval;
socklen_t srv_len;
@ -1722,36 +1800,13 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
/* TODO: interprete 'addrs' as a command-separated address list
* 192.168.1.1:20,[::1]:20,127.0.0.1:345
*/
HCL_MEMSET (&srv_addr, 0, HCL_SIZEOF(srv_addr));
if (inet_pton(AF_INET6, addrs, &srv_addr.in6.sin6_addr) != 1)
{
if (inet_pton(AF_INET, addrs, &srv_addr.in4.sin_addr) != 1)
{
fprintf (stderr, "cannot open convert server address %s - %s\n", addrs, strerror(errno));
return -1;
}
else
{
srv_addr.in4.sin_family = AF_INET;
srv_addr.in4.sin_port = htons(8888); /* TODO: change it */
srv_len = HCL_SIZEOF(srv_addr.in4);
sck_fam = AF_INET;
}
}
else
{
srv_addr.in6.sin6_family = AF_INET6;
srv_addr.in6.sin6_port = htons(8888); /* TODO: change it */
srv_len = HCL_SIZEOF(srv_addr.in6);
sck_fam = AF_INET6;
}
sck_fam = bchars_to_sockaddr(server, addrs, hcl_countbcstr(addrs), &srv_addr, &srv_len);
if (sck_fam <= -1) return -1;
srv_fd = socket(sck_fam, SOCK_STREAM, 0);
if (srv_fd == -1)
{
int xerrno = errno;
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot open server socket - %s\n", strerror(xerrno));
set_err_with_syserr (server, errno, "unable to open server socket");
return -1;
}
@ -1760,18 +1815,14 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
if (bind(srv_fd, (struct sockaddr*)&srv_addr, srv_len) == -1)
{
int xerrno = errno;
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot bind server socket %d - %s\n", srv_fd, strerror(xerrno));
set_err_with_syserr (server, errno, "unable to bind server socket %d", srv_fd);
close (srv_fd);
return -1;
}
if (listen (srv_fd, 128) == -1)
if (listen(srv_fd, 128) == -1)
{
int xerrno = errno;
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot listen on server socket %d - %s\n", srv_fd, strerror(xerrno));
set_err_with_syserr (server, errno, "unable to listen on server socket %d", srv_fd);
close (srv_fd);
return -1;
}
@ -1782,7 +1833,7 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
server->stopreq = 0;
while (!server->stopreq)
{
sck_addr_t cli_addr;
sockaddr_t cli_addr;
int cli_fd;
socklen_t cli_len;
pthread_t thr;
@ -1795,12 +1846,7 @@ int hcl_server_start (hcl_server_t* server, const char* addrs)
cli_fd = accept(srv_fd, (struct sockaddr*)&cli_addr, &cli_len);
if (cli_fd == -1)
{
if (errno != EINTR || !server->stopreq)
{
int xerrno = errno;
hcl_server_seterrnum (server, hcl_syserr_to_errnum(xerrno));
hcl_server_logbfmt (server, HCL_SERVER_PROTO_LOG_MASK, "cannot accept worker on socket %d - %s\n", srv_fd, strerror(xerrno));
}
if (errno != EINTR || !server->stopreq) set_err_with_syserr (server, errno, "unable to accept worker on socket %d", srv_fd);
break;
}
@ -1838,11 +1884,18 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
case HCL_SERVER_WORKER_STACK_SIZE:
server->cfg.worker_stack_size = *(hcl_oow_t*)value;
return 0;
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
server->cfg.worker_idle_timeout = *(hcl_ntime_t*)value;
return 0;
case HCL_SERVER_ACTOR_HEAP_SIZE:
server->cfg.actor_heap_size = *(hcl_oow_t*)value;
return 0;
case HCL_SERVER_ACTOR_MAX_RUNTIME:
server->cfg.actor_max_runtime = *(hcl_ntime_t*)value;
return 0;
}
hcl_server_seterrnum (server, HCL_EINVAL);
@ -1864,10 +1917,18 @@ int hcl_server_getoption (hcl_server_t* server, hcl_server_option_t id, void* va
case HCL_SERVER_WORKER_STACK_SIZE:
*(hcl_oow_t*)value = server->cfg.worker_stack_size;
return 0;
case HCL_SERVER_WORKER_IDLE_TIMEOUT:
*(hcl_ntime_t*)value = server->cfg.worker_idle_timeout;
return 0;
case HCL_SERVER_ACTOR_HEAP_SIZE:
*(hcl_oow_t*)value = server->cfg.actor_heap_size;
return 0;
case HCL_SERVER_ACTOR_MAX_RUNTIME:
*(hcl_ntime_t*)value = server->cfg.actor_max_runtime;
return 0;
};
hcl_server_seterrnum (server, HCL_EINVAL);
@ -1916,3 +1977,31 @@ void hcl_server_seterrnum (hcl_server_t* server, hcl_errnum_t errnum)
server->errnum = errnum;
server->errmsg.len = 0;
}
void hcl_server_seterrbfmt (hcl_server_t* server, hcl_errnum_t errnum, const hcl_bch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_seterrbfmtv (server->dummy_hcl, errnum, fmt, ap);
va_end (ap);
HCL_ASSERT (server->dummy_hcl, HCL_COUNTOF(server->errmsg.buf) == HCL_COUNTOF(server->dummy_hcl->errmsg.buf));
server->errnum = errnum;
hcl_copyoochars (server->errmsg.buf, server->dummy_hcl->errmsg.buf, HCL_COUNTOF(server->errmsg.buf));
server->errmsg.len = server->dummy_hcl->errmsg.len;
}
void hcl_server_seterrufmt (hcl_server_t* server, hcl_errnum_t errnum, const hcl_uch_t* fmt, ...)
{
va_list ap;
va_start (ap, fmt);
hcl_seterrufmtv (server->dummy_hcl, errnum, fmt, ap);
va_end (ap);
HCL_ASSERT (server->dummy_hcl, HCL_COUNTOF(server->errmsg.buf) == HCL_COUNTOF(server->dummy_hcl->errmsg.buf));
server->errnum = errnum;
hcl_copyoochars (server->errmsg.buf, server->dummy_hcl->errmsg.buf, HCL_COUNTOF(server->errmsg.buf));
server->errmsg.len = server->dummy_hcl->errmsg.len;
}

View File

@ -38,7 +38,9 @@ enum hcl_server_option_t
HCL_SERVER_TRAIT,
HCL_SERVER_LOG_MASK,
HCL_SERVER_WORKER_STACK_SIZE,
HCL_SERVER_ACTOR_HEAP_SIZE
HCL_SERVER_WORKER_IDLE_TIMEOUT,
HCL_SERVER_ACTOR_HEAP_SIZE,
HCL_SERVER_ACTOR_MAX_RUNTIME
};
typedef enum hcl_server_option_t hcl_server_option_t;
@ -86,8 +88,8 @@ HCL_EXPORT void hcl_server_close (
);
HCL_EXPORT int hcl_server_start (
hcl_server_t* server,
const char* addrs
hcl_server_t* server,
const hcl_bch_t* addrs
);
HCL_EXPORT void hcl_server_stop (
@ -129,11 +131,33 @@ HCL_EXPORT hcl_errnum_t hcl_server_geterrnum (
hcl_server_t* server
);
HCL_EXPORT const hcl_ooch_t* hcl_server_geterrstr (
hcl_server_t* server
);
HCL_EXPORT const hcl_ooch_t* hcl_server_geterrmsg (
hcl_server_t* server
);
HCL_EXPORT void hcl_server_seterrnum (
hcl_server_t* server,
hcl_errnum_t errnum
);
HCL_EXPORT void hcl_server_seterrbfmt (
hcl_server_t* server,
hcl_errnum_t errnum,
const hcl_bch_t* fmt,
...
);
HCL_EXPORT void hcl_server_seterrufmt (
hcl_server_t* server,
hcl_errnum_t errnum,
const hcl_uch_t* fmt,
...
);
HCL_EXPORT void hcl_server_logbfmt (
hcl_server_t* server,
unsigned int mask,

View File

@ -1471,6 +1471,20 @@ HCL_EXPORT void hcl_seterrufmt (
...
);
HCL_EXPORT void hcl_seterrbfmtv (
hcl_t* hcl,
hcl_errnum_t errnum,
const hcl_bch_t* fmt,
va_list ap
);
HCL_EXPORT void hcl_seterrufmtv (
hcl_t* hcl,
hcl_errnum_t errnum,
const hcl_uch_t* fmt,
va_list ap
);
HCL_EXPORT const hcl_ooch_t* hcl_geterrstr (
hcl_t* hcl
);

View File

@ -426,7 +426,7 @@ hcl_ooi_t hcl_logbfmtv (hcl_t* hcl, int mask, const hcl_bch_t* fmt, va_list ap)
fo.putch = put_logch;
fo.putcs = put_logcs;
x = _logbfmtv (hcl, fmt, &fo, ap);
x = _logbfmtv(hcl, fmt, &fo, ap);
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
{
@ -463,7 +463,7 @@ hcl_ooi_t hcl_logufmtv (hcl_t* hcl, int mask, const hcl_uch_t* fmt, va_list ap)
fo.putch = put_logch;
fo.putcs = put_logcs;
x = _logufmtv (hcl, fmt, &fo, ap);
x = _logufmtv(hcl, fmt, &fo, ap);
if (hcl->log.len > 0 && hcl->log.ptr[hcl->log.len - 1] == '\n')
{

View File

@ -234,7 +234,7 @@ static void log_write (hcl_server_t* server, int wid, unsigned int mask, const h
}
}
#else
write_all (logfd, vmsg, len);
write_all (logfd, msg, len);
#endif
if (xtn->logfd_istty)
@ -310,7 +310,7 @@ static int handle_logopt (hcl_server_t* server, const hcl_bch_t* str)
{
/* i duplicate this string for open() below as open() doesn't
* accept a length-bounded string */
xstr = strdup (str);
xstr = strdup(str);
if (!xstr)
{
fprintf (stderr, "ERROR: out of memory in duplicating %s\n", str);

362
lib/sa-utl.h Normal file
View File

@ -0,0 +1,362 @@
static int str_to_ipv4 (const ooch_t* str, hcl_oow_t len, struct in_addr* inaddr)
{
const ooch_t* end;
int dots = 0, digits = 0;
hcl_uint32_t acc = 0, addr = 0;
ooch_t c;
end = str + len;
do
{
if (str >= end)
{
if (dots < 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
break;
}
c = *str++;
if (c >= '0' && c <= '9')
{
if (digits > 0 && acc == 0) return -1;
acc = acc * 10 + (c - '0');
if (acc > 255) return -1;
digits++;
}
else if (c == '.')
{
if (dots >= 3 || digits == 0) return -1;
addr = (addr << 8) | acc;
dots++; acc = 0; digits = 0;
}
else return -1;
}
while (1);
inaddr->s_addr = hcl_hton32(addr);
return 0;
}
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
static int str_to_ipv6 (const ooch_t* src, hcl_oow_t len, struct in6_addr* inaddr)
{
hcl_uint8_t* tp, * endp, * colonp;
const ooch_t* curtok;
ooch_t ch;
int saw_xdigit;
unsigned int val;
const ooch_t* src_end;
src_end = src + len;
HCL_MEMSET (inaddr, 0, HCL_SIZEOF(*inaddr));
tp = &inaddr->s6_addr[0];
endp = &inaddr->s6_addr[HCL_COUNTOF(inaddr->s6_addr)];
colonp = HCL_NULL;
/* Leading :: requires some special handling. */
if (src < src_end && *src == ':')
{
src++;
if (src >= src_end || *src != ':') return -1;
}
curtok = src;
saw_xdigit = 0;
val = 0;
while (src < src_end)
{
int v1;
ch = *src++;
if (ch >= '0' && ch <= '9')
v1 = ch - '0';
else if (ch >= 'A' && ch <= 'F')
v1 = ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
v1 = ch - 'a' + 10;
else v1 = -1;
if (v1 >= 0)
{
val <<= 4;
val |= v1;
if (val > 0xffff) return -1;
saw_xdigit = 1;
continue;
}
if (ch == ':')
{
curtok = src;
if (!saw_xdigit)
{
if (colonp) return -1;
colonp = tp;
continue;
}
else if (src >= src_end)
{
/* a colon can't be the last character */
return -1;
}
*tp++ = (hcl_uint8_t)(val >> 8) & 0xff;
*tp++ = (hcl_uint8_t)val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + HCL_SIZEOF(struct in_addr)) <= endp) &&
str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0)
{
tp += HCL_SIZEOF(struct in_addr*);
saw_xdigit = 0;
break;
}
return -1;
}
if (saw_xdigit)
{
if (tp + HCL_SIZEOF(hcl_uint16_t) > endp) return -1;
*tp++ = (hcl_uint8_t)(val >> 8) & 0xff;
*tp++ = (hcl_uint8_t)val & 0xff;
}
if (colonp != HCL_NULL)
{
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
hcl_oow_t n = tp - colonp;
hcl_oow_t i;
for (i = 1; i <= n; i++)
{
endp[-i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp) return -1;
return 0;
}
#endif
static int str_to_sockaddr (hcl_server_t* server, const ooch_t* str, hcl_oow_t len, sockaddr_t* nwad, socklen_t* socklen)
{
const ooch_t* p;
const ooch_t* end;
oocs_t tmp;
p = str;
end = str + len;
if (p >= end)
{
hcl_server_seterrbfmt (server, HCL_EINVAL, "blank address");
return -1;
}
HCL_MEMSET (nwad, 0, HCL_SIZEOF(*nwad));
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (*p == '[')
{
/* IPv6 address */
tmp.ptr = (ooch_t*)++p; /* skip [ and remember the position */
while (p < end && *p != '%' && *p != ']') p++;
if (p >= end) goto no_rbrack;
tmp.len = p - tmp.ptr;
if (*p == '%')
{
/* handle scope id */
hcl_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
hcl_server_seterrbfmt (server, HCL_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
hcl_server_seterrbfmt (server, HCL_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO:
/* interface name as a scope id? */
const ooch_t* stmp = p;
unsigned int index;
do p++; while (p < end && *p != ']');
if (hcl_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
tmpad.u.in6.scope = index;
#endif
}
if (p >= end || *p != ']') goto no_rbrack;
}
p++; /* skip ] */
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
nwad->in6.sin6_family = AF_INET6;
}
else
{
#endif
/* IPv4 address */
tmp.ptr = (ooch_t*)p;
while (p < end && *p != ':') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv4(tmp.ptr, tmp.len, &nwad->in4.sin_addr) <= -1)
{
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
/* check if it is an IPv6 address not enclosed in [].
* the port number can't be specified in this format. */
if (p >= end || *p != ':')
{
/* without :, it can't be an ipv6 address */
goto unrecog;
}
while (p < end && *p != '%') p++;
tmp.len = p - tmp.ptr;
if (str_to_ipv6(tmp.ptr, tmp.len, &nwad->in6.sin6_addr) <= -1) goto unrecog;
if (p < end && *p == '%')
{
/* handle scope id */
hcl_uint32_t x;
p++; /* skip % */
if (p >= end)
{
/* premature end */
hcl_server_seterrbfmt (server, HCL_EINVAL, "scope id blank");
return -1;
}
if (*p >= '0' && *p <= '9')
{
/* numeric scope id */
nwad->in6.sin6_scope_id = 0;
do
{
x = nwad->in6.sin6_scope_id * 10 + (*p - '0');
if (x < nwad->in6.sin6_scope_id)
{
hcl_server_seterrbfmt (server, HCL_EINVAL, "scope id too large");
return -1; /* overflow */
}
nwad->in6.sin6_scope_id = x;
p++;
}
while (p < end && *p >= '0' && *p <= '9');
}
else
{
#if 0
TODO
/* interface name as a scope id? */
const ooch_t* stmp = p;
unsigned int index;
do p++; while (p < end);
if (hcl_nwifwcsntoindex(stmp, p - stmp, &index) <= -1) return -1;
nwad->in6.sin6_scope_id = index;
#endif
}
}
if (p < end) goto unrecog; /* some gargage after the end? */
nwad->in6.sin6_family = AF_INET6;
*socklen = HCL_SIZEOF(nwad->in6);
return nwad->in6.sin6_family;
#else
goto unrecog;
#endif
}
nwad->in4.sin_family = AF_INET;
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
}
#endif
if (p < end && *p == ':')
{
/* port number */
hcl_uint32_t port = 0;
p++; /* skip : */
tmp.ptr = (ooch_t*)p;
while (p < end && *p >= '0' && *p <= '9')
{
port = port * 10 + (*p - '0');
p++;
}
tmp.len = p - tmp.ptr;
if (tmp.len <= 0 || tmp.len >= 6 ||
port > HCL_TYPE_MAX(hcl_uint16_t))
{
hcl_server_seterrbfmt (server, HCL_EINVAL, "port number blank or too large");
return -1;
}
#if (HCL_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
if (nwad->in4.sin_family == AF_INET)
nwad->in4.sin_port = hcl_hton16(port);
else
nwad->in6.sin6_port = hcl_hton16(port);
#else
nwad->in4.sin_port = hcl_hton16(port);
#endif
}
*socklen = (nwad->in4.sin_family == AF_INET)? HCL_SIZEOF(nwad->in4): HCL_SIZEOF(nwad->in6);
return nwad->in4.sin_family;
unrecog:
hcl_server_seterrbfmt (server, HCL_EINVAL, "unrecognized address");
return -1;
no_rbrack:
hcl_server_seterrbfmt (server, HCL_EINVAL, "missing right bracket");
return -1;
}

View File

@ -827,7 +827,7 @@ HCL_INLINE hcl_bch_t* hcl_duputobcharswithheadroom (hcl_t* hcl, hcl_oow_t headro
hcl_bch_t* ptr;
inlen = ucslen;
if (hcl_convutobchars (hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1)
if (hcl_convutobchars(hcl, ucs, &inlen, HCL_NULL, &outlen) <= -1)
{
/* note it's also an error if no full conversion is made in this function */
return HCL_NULL;
@ -858,7 +858,7 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucstrwithheadroom (hcl_t* hcl, hcl_oow_t headroo
hcl_oow_t inlen, outlen;
hcl_uch_t* ptr;
if (hcl_convbtoucstr (hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1)
if (hcl_convbtoucstr(hcl, bcs, &inlen, HCL_NULL, &outlen) <= -1)
{
/* note it's also an error if no full conversion is made in this function */
return HCL_NULL;