diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index 632987d6..2e6da55f 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -140,7 +140,7 @@ int qse_awk_init (qse_awk_t* awk, qse_mmgr_t* mmgr, const qse_awk_prm_t* prm) }; /* zero out the object */ - QSE_MEMSET (awk, 0, QSE_SIZEOF(qse_awk_t)); + QSE_MEMSET (awk, 0, QSE_SIZEOF(*awk)); /* remember the memory manager */ awk->mmgr = mmgr; diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index 4dabce2e..d066551b 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -114,6 +114,9 @@ typedef struct xtn_t int gbl_environ; qse_awk_ecb_t ecb; +#if defined(USE_LTDL) + int ltdl_fail; +#endif } xtn_t; typedef struct rxtn_t @@ -184,11 +187,19 @@ qse_awk_flt_t qse_awk_stdmathmod (qse_awk_t* awk, qse_awk_flt_t x, qse_awk_flt_t int qse_awk_stdmodstartup (qse_awk_t* awk) { #if defined(USE_LTDL) + /* lt_dlinit() can be called more than once and * lt_dlexit() shuts down libltdl if it's called as many times as * corresponding lt_dlinit(). so it's safe to call lt_dlinit() * and lt_dlexit() at the library level. */ - return (lt_dlinit () != 0)? -1: 0; + if (lt_dlinit() != 0) + { + xtn_t* xtn = QSE_XTN(awk); + xtn->ltdl_fail = 1; + /* carry on even if ltdl initialize failed */ + } + + return 0; #else return 0; @@ -199,8 +210,8 @@ int qse_awk_stdmodstartup (qse_awk_t* awk) void qse_awk_stdmodshutdown (qse_awk_t* awk) { #if defined(USE_LTDL) - - lt_dlexit (); + xtn_t* xtn = QSE_XTN(awk); + if (!xtn->ltdl_fail) lt_dlexit (); #else /* do nothing */ @@ -214,6 +225,15 @@ void* qse_awk_stdmodopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec) qse_mchar_t* modpath; const qse_char_t* tmp[4]; int count; + xtn_t* xtn = QSE_XTN(awk); + + if (xtn->ltdl_fail) + { + /* ltdl_init() failed during initialization. + * return failure immediately */ + qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL); + return QSE_NULL; + } count = 0; if (spec->prefix) tmp[count++] = spec->prefix; @@ -364,7 +384,7 @@ void* qse_awk_stdmodsym (qse_awk_t* awk, void* handle, const qse_char_t* name) #if defined(QSE_CHAR_IS_MCHAR) mname = name; #else - mname = qse_wcstombsdup (name, QSE_NULL, awk->mmgr); + mname = qse_wcstombsdup (name, QSE_NULL, awk->mmgr); if (!mname) { qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); @@ -434,6 +454,7 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_aw /* initialize extension */ xtn = (xtn_t*) QSE_XTN (awk); + QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); /* add intrinsic global variables and functions */ if (add_globals(awk) <= -1 || diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index bab42271..9cfea5bd 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -756,7 +756,7 @@ qse_httpd_t* qse_httpd_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) if (httpd == QSE_NULL) goto oops; xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); - QSE_MEMSET (xtn, 0, QSE_SIZEOF(httpd_xtn_t*)); + QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); #if defined(USE_LTDL) /* lt_dlinit() can be called more than once and diff --git a/qse/lib/sed/std.c b/qse/lib/sed/std.c index 34233342..e7970a89 100644 --- a/qse/lib/sed/std.c +++ b/qse/lib/sed/std.c @@ -107,7 +107,17 @@ qse_sed_t* qse_sed_openstd (qse_size_t xtnsize) qse_sed_t* qse_sed_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) { - return qse_sed_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize); + qse_sed_t* sed; + xtn_t* xtn; + + sed = qse_sed_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize); + if (!sed) return QSE_NULL; + + /* initialize the my own extension area excluding xtnsize */ + xtn = (xtn_t*) QSE_XTN(sed); + QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); + + return sed; } void* qse_sed_getxtnstd (qse_sed_t* sed) diff --git a/qse/lib/xli/std.c b/qse/lib/xli/std.c index f6d09ee6..1721a021 100644 --- a/qse/lib/xli/std.c +++ b/qse/lib/xli/std.c @@ -97,6 +97,7 @@ qse_xli_t* qse_xli_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_si /* initialize extension */ xtn = (xtn_t*) QSE_XTN (xli); + QSE_MEMSET (xtn, 0, QSE_SIZEOF(*xtn)); xtn->ecb.close = fini_xtn; xtn->ecb.clear = clear_xtn;