changed qse_awk_stdmodXXX() functions to avoid accessing extension area such that StdAwk doesn't get bitten when it called them

This commit is contained in:
hyung-hwan 2017-05-03 03:41:00 +00:00
parent 1e19713270
commit 5630bd63f0
2 changed files with 41 additions and 28 deletions

View File

@ -152,7 +152,7 @@ void StdAwk::close ()
//if (this->stdmod_up) //if (this->stdmod_up)
//{ //{
// qse_awk_stdmodshutdown (this->awk); // qse_awk_stdmodshutdown (this->awk);
// stdmod_up = false; // this->stdmod_up = false;
//} //}
// //
@ -164,7 +164,7 @@ void StdAwk::uponClosing ()
if (this->stdmod_up) if (this->stdmod_up)
{ {
qse_awk_stdmodshutdown (this->awk); qse_awk_stdmodshutdown (this->awk);
stdmod_up = false; this->stdmod_up = false;
} }
// chain up // chain up

View File

@ -114,9 +114,7 @@ typedef struct xtn_t
int gbl_environ; int gbl_environ;
qse_awk_ecb_t ecb; qse_awk_ecb_t ecb;
#if defined(USE_LTDL) int stdmod_up;
int ltdl_fail;
#endif
} xtn_t; } xtn_t;
typedef struct rxtn_t typedef struct rxtn_t
@ -184,6 +182,11 @@ qse_awk_flt_t qse_awk_stdmathmod (qse_awk_t* awk, qse_awk_flt_t x, qse_awk_flt_t
#endif #endif
} }
/* [IMPORTANT]
* qse_awk_stdmodXXXX() functions must not access the extension
* area of 'awk'. they are used in StdAwk.cpp which instantiates
* an awk object with qse_awk_open() instead of qse_awk_openstd(). */
int qse_awk_stdmodstartup (qse_awk_t* awk) int qse_awk_stdmodstartup (qse_awk_t* awk)
{ {
#if defined(USE_LTDL) #if defined(USE_LTDL)
@ -192,14 +195,7 @@ int qse_awk_stdmodstartup (qse_awk_t* awk)
* lt_dlexit() shuts down libltdl if it's called as many times as * lt_dlexit() shuts down libltdl if it's called as many times as
* corresponding lt_dlinit(). so it's safe to call lt_dlinit() * corresponding lt_dlinit(). so it's safe to call lt_dlinit()
* and lt_dlexit() at the library level. */ * and lt_dlexit() at the library level. */
if (lt_dlinit() != 0) return lt_dlinit() != 0? -1: 0;
{
xtn_t* xtn = QSE_XTN(awk);
xtn->ltdl_fail = 1;
/* carry on even if ltdl initialize failed */
}
return 0;
#else #else
return 0; return 0;
@ -210,14 +206,27 @@ int qse_awk_stdmodstartup (qse_awk_t* awk)
void qse_awk_stdmodshutdown (qse_awk_t* awk) void qse_awk_stdmodshutdown (qse_awk_t* awk)
{ {
#if defined(USE_LTDL) #if defined(USE_LTDL)
xtn_t* xtn = QSE_XTN(awk); lt_dlexit ();
if (!xtn->ltdl_fail) lt_dlexit ();
#else #else
/* do nothing */ /* do nothing */
#endif #endif
} }
static void* std_mod_open_checked (qse_awk_t* awk, const qse_awk_mod_spec_t* spec)
{
xtn_t* xtn = QSE_XTN(awk);
if (!xtn->stdmod_up)
{
/* qse_awk_stdmodstartup() must have failed upon start-up.
* return failure immediately */
qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL);
return QSE_NULL;
}
return qse_awk_stdmodopen (awk, spec);
}
void* qse_awk_stdmodopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec) void* qse_awk_stdmodopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec)
{ {
#if defined(USE_LTDL) #if defined(USE_LTDL)
@ -226,15 +235,6 @@ void* qse_awk_stdmodopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec)
qse_mchar_t* modpath; qse_mchar_t* modpath;
const qse_char_t* tmp[4]; const qse_char_t* tmp[4];
int count; 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; count = 0;
if (spec->prefix) tmp[count++] = spec->prefix; if (spec->prefix) tmp[count++] = spec->prefix;
@ -441,7 +441,12 @@ qse_awk_t* qse_awk_openstd (qse_size_t xtnsize, qse_awk_errnum_t* errnum)
static void fini_xtn (qse_awk_t* awk) static void fini_xtn (qse_awk_t* awk)
{ {
xtn_t* xtn = QSE_XTN (awk);
if (xtn->stdmod_up)
{
qse_awk_stdmodshutdown (awk); qse_awk_stdmodshutdown (awk);
xtn->stdmod_up = 0;
}
} }
static void clear_xtn (qse_awk_t* awk) static void clear_xtn (qse_awk_t* awk)
@ -458,7 +463,7 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_aw
prm.math.pow = qse_awk_stdmathpow; prm.math.pow = qse_awk_stdmathpow;
prm.math.mod = qse_awk_stdmathmod; prm.math.mod = qse_awk_stdmathmod;
prm.modopen = qse_awk_stdmodopen; prm.modopen = std_mod_open_checked;
prm.modclose = qse_awk_stdmodclose; prm.modclose = qse_awk_stdmodclose;
prm.modsym = qse_awk_stdmodsym; prm.modsym = qse_awk_stdmodsym;
@ -475,7 +480,15 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_aw
if (add_globals(awk) <= -1 || if (add_globals(awk) <= -1 ||
add_functions (awk) <= -1) goto oops; add_functions (awk) <= -1) goto oops;
if (qse_awk_stdmodstartup (awk) <= -1) goto oops; if (qse_awk_stdmodstartup (awk) <= -1)
{
xtn->stdmod_up = 0;
/* carry on regardless of failure */
}
else
{
xtn->stdmod_up = 1;
}
xtn->ecb.close = fini_xtn; xtn->ecb.close = fini_xtn;
xtn->ecb.clear = clear_xtn; xtn->ecb.clear = clear_xtn;