Compare commits

..

4 Commits

Author SHA1 Message Date
f7f4ead790 updated README.md and the rpm spec file
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-14 14:06:40 +09:00
0c5cf2edc1 more documetnation on singal handling
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-13 18:24:13 +09:00
e8d1a179d6 updated the Hawk class and the Hawk::Run class to integrate the signal handling code
All checks were successful
continuous-integration/drone/push Build is passing
2026-01-13 15:14:24 +09:00
a83e85cc09 renamed SetSigsetHandler to OnSigset 2026-01-12 23:58:19 +09:00
10 changed files with 245 additions and 66 deletions

View File

@@ -45,7 +45,7 @@ The library is stable, portable, and designed for projects that need a scripting
- [@include and @include\_once](#include-and-include_once) - [@include and @include\_once](#include-and-include_once)
- [Comments](#comments) - [Comments](#comments)
- [Reserved Words](#reserved-words) - [Reserved Words](#reserved-words)
- [More Examples](#more-examples) - [Some Examples](#some-examples)
- [Garbage Collection](#garbage-collection) - [Garbage Collection](#garbage-collection)
- [Modules](#modules) - [Modules](#modules)
- [Hawk](#hawk) - [Hawk](#hawk)
@@ -182,6 +182,44 @@ $ gcc -Wall -O2 -o hawk02 hawk02.c -lhawk
The actual command may vary depending on the compiler used and the `configure` options used. The actual command may vary depending on the compiler used and the `configure` options used.
## Embedding Signal Handling
Signal handling is provided via a callback hook. The core library does not install OS-level signal handlers; the embedding application must do that and notify the runtime.
- Register a runtime callback with `hawk_rtx_pushecb()` and fill `hawk_rtx_ecb_t.sigset` (type `hawk_rtx_ecb_sigset_t`).
- Your callback is invoked when `sys::signal()` sets or clears a handler; use it to install or reset the OS signal handler.
- When the OS handler runs, call `hawk_rtx_raisesig()` on the target runtime.
Example:
```c
static hawk_rtx_t* g_rtx = HAWK_NULL;
static void on_os_signal (int sig)
{
if (g_rtx) hawk_rtx_raisesig(g_rtx, sig);
}
static void on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
{
if (fun)
{
g_rtx = rtx;
signal(sig, on_os_signal);
}
else
{
if (g_rtx == rtx) g_rtx = HAWK_NULL;
signal(sig, SIG_DFL);
}
}
hawk_rtx_ecb_t ecb;
memset(&ecb, 0, HAWK_SIZEOF(ecb));
ecb.sigset = on_sigset;
hawk_rtx_pushecb(rtx, &ecb);
```
# Embedding Hawk in C++ Applications # Embedding Hawk in C++ Applications
Hawk can also be embedded in C++ applications. Here's an example: Hawk can also be embedded in C++ applications. Here's an example:
@@ -1002,9 +1040,11 @@ The `sys` module provides various functions concerning the underlying operation
- sys::opendir - sys::opendir
- sys::openfd - sys::openfd
- sys::pipe - sys::pipe
- sys::raise
- sys::read - sys::read
- sys::readdir - sys::readdir
- sys::setttime - sys::setttime
- sys::signal
- sys::sleep - sys::sleep
- sys::strftime - sys::strftime
- sys::system - sys::system
@@ -1012,6 +1052,29 @@ The `sys` module provides various functions concerning the underlying operation
- sys::wait - sys::wait
- sys::write - sys::write
#### Signals
Use these to register handlers and raise signals from Hawk.
- sys::signal(sig, func) sets a handler function for a signal number. pass nil to clear it.
- sys::raise(sig) raises a signal to the current runtime.
- sys::kill(pid, sig) sends a signal to another process or to self.
Example:
```awk
function on_int(sig) { print "got", sig }
BEGIN {
sys::signal(sys::SIGINT, on_int);
sys::raise(sys::SIGINT);
## sys::kill(sys::getpid(), sys::SIGINT);
sys::signal(sys::SIGINT, @nil);
}
```
#### Raw byte reads
You may read the file in raw bytes. You may read the file in raw bytes.
@@ -1025,6 +1088,8 @@ BEGIN {
} }
``` ```
#### Wrap a file descriptor
You can map a raw file descriptor to a handle created by this module and use it. You can map a raw file descriptor to a handle created by this module and use it.
```awk ```awk
@@ -1037,6 +1102,8 @@ BEGIN {
} }
``` ```
#### Pipe to a child process
Creating pipes and sharing them with a child process is not big an issue. Creating pipes and sharing them with a child process is not big an issue.
```awk ```awk
@@ -1091,6 +1158,8 @@ BEGIN {
} }
``` ```
#### Read child stdout
You can read standard output of a child process in a parent process. You can read standard output of a child process in a parent process.
```awk ```awk
@@ -1142,6 +1211,8 @@ BEGIN {
} }
``` ```
#### Duplicate file handles
You can duplicate file handles as necessary. You can duplicate file handles as necessary.
```awk ```awk
@@ -1165,6 +1236,8 @@ BEGIN {
} }
``` ```
#### Directory traversal
Directory traversal is easy. Directory traversal is easy.
```awk ```awk
@@ -1183,6 +1256,8 @@ BEGIN {
} }
``` ```
#### Network interface info
You can get information of a network interface. You can get information of a network interface.
```awk ```awk
@@ -1194,6 +1269,8 @@ BEGIN {
} }
``` ```
#### Sockets
Socket functions are available. Socket functions are available.
```awk ```awk

View File

@@ -341,7 +341,14 @@ static void on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
else else
{ {
int back_to_stop_run = 0; int back_to_stop_run = 0;
hawk_main_unset_signal_handler(sig);
#if defined(SIGPIPE)
if (sig == SIGPIPE)
{
set_intr_pipe(); // to application default. not OS default.
return;
}
#endif
#if defined(SIGTERM) #if defined(SIGTERM)
if (sig == SIGTERM) back_to_stop_run = 1; if (sig == SIGTERM) back_to_stop_run = 1;
#endif #endif
@@ -351,7 +358,10 @@ static void on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
#if defined(SIGINT) #if defined(SIGINT)
if (sig == SIGINT) back_to_stop_run = 1; if (sig == SIGINT) back_to_stop_run = 1;
#endif #endif
if (back_to_stop_run) hawk_main_set_signal_handler(sig, stop_run, 0); if (back_to_stop_run)
hawk_main_set_signal_handler(sig, stop_run, 0);
else
hawk_main_unset_signal_handler(sig);
} }
} }

View File

@@ -211,7 +211,7 @@ func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan ch
} }
} }
rtx.SetSigsetHandler(func(rtx *hawk.Rtx, signo int, reset bool) { rtx.OnSigset(func(rtx *hawk.Rtx, signo int, reset bool) {
var s os.Signal var s os.Signal
s = syscall.Signal(signo) s = syscall.Signal(signo)
if reset { if reset {
@@ -229,7 +229,7 @@ func run_script(h *hawk.Hawk, fs_idx int, data_idx int, cfg* Config, rtx_chan ch
args[idx].Close() args[idx].Close()
} }
} else { } else {
rtx.SetSigsetHandler(func(rtx *hawk.Rtx, signo int, reset bool) { rtx.OnSigset(func(rtx *hawk.Rtx, signo int, reset bool) {
var s os.Signal var s os.Signal
s = syscall.Signal(signo) s = syscall.Signal(signo)
if reset { if reset {

View File

@@ -632,7 +632,7 @@ func (rtx* Rtx) Halt() {
C.hawk_rtx_halt(rtx.c) C.hawk_rtx_halt(rtx.c)
} }
func (rtx *Rtx) SetSigsetHandler(f RtxSigsetHandler) { func (rtx *Rtx) OnSigset(f RtxSigsetHandler) {
rtx.sigset_handler = f rtx.sigset_handler = f
} }
@@ -814,6 +814,8 @@ func (rtx *Rtx) GetNamedVars(vars map[string]*Val) {
//export hawk_go_sigset_handler //export hawk_go_sigset_handler
func hawk_go_sigset_handler(rtx_xtn *C.rtx_xtn_t, sig C.int, reset C.int) { func hawk_go_sigset_handler(rtx_xtn *C.rtx_xtn_t, sig C.int, reset C.int) {
// this handler is called when sys::signal() is invoked in a script.
//var inst HawkInstance //var inst HawkInstance
var rtx_inst RtxInstance var rtx_inst RtxInstance
var rtx *Rtx var rtx *Rtx
@@ -822,7 +824,9 @@ func hawk_go_sigset_handler(rtx_xtn *C.rtx_xtn_t, sig C.int, reset C.int) {
rtx_inst = rtx_inst_table.slot_to_instance(int(rtx_xtn.rtx_inst_no)) rtx_inst = rtx_inst_table.slot_to_instance(int(rtx_xtn.rtx_inst_no))
rtx = rtx_inst.g.Value() rtx = rtx_inst.g.Value()
if rtx.sigset_handler != nil {
rtx.sigset_handler(rtx, int(sig), reset != 0) rtx.sigset_handler(rtx, int(sig), reset != 0)
}
} }
// ----------------------------------------------------------- // -----------------------------------------------------------

View File

@@ -132,6 +132,17 @@ static HAWK_INLINE rxtn_t* GET_RXTN(hawk_rtx_t* rtx) { return (rxtn_t*)((hawk_ui
#define GET_RXTN(rtx) ((rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t))) #define GET_RXTN(rtx) ((rxtn_t*)((hawk_uint8_t*)hawk_rtx_getxtn(rtx) - HAWK_SIZEOF(rxtn_t)))
#endif #endif
static void rtx_on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
{
rxtn_t* rxtn = GET_RXTN(rtx);
Hawk::Run* run = rxtn->run;
if (run)
{
Hawk* hawk = (Hawk*)*run; // call operator Hawk*
if (hawk) hawk->uponSigset(*run, sig, fun == HAWK_NULL);
}
}
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Hawk::Pipe // Hawk::Pipe
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
@@ -1881,7 +1892,7 @@ int Hawk::open ()
HAWK_HTB_SIZER_DEFAULT, HAWK_HTB_SIZER_DEFAULT,
HAWK_HTB_HASHER_DEFAULT HAWK_HTB_HASHER_DEFAULT
}; };
hawk_htb_setstyle (this->functionMap, &style); hawk_htb_setstyle(this->functionMap, &style);
#endif #endif
@@ -1935,6 +1946,11 @@ void Hawk::uponClearing ()
// nothing to do // nothing to do
} }
void Hawk::uponSigset (Run& run, int sig, bool reset)
{
// nothing to do
}
Hawk::Run* Hawk::parse (Source& in, Source& out) Hawk::Run* Hawk::parse (Source& in, Source& out)
{ {
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
@@ -1981,7 +1997,7 @@ int Hawk::loop (Value* ret)
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
HAWK_ASSERT(this->runctx.rtx != HAWK_NULL); HAWK_ASSERT(this->runctx.rtx != HAWK_NULL);
hawk_val_t* rv = hawk_rtx_loop (this->runctx.rtx); hawk_val_t* rv = hawk_rtx_loop(this->runctx.rtx);
if (rv == HAWK_NULL) if (rv == HAWK_NULL)
{ {
this->retrieveError(&this->runctx); this->retrieveError(&this->runctx);
@@ -2010,7 +2026,7 @@ int Hawk::call (const hawk_bch_t* name, Value* ret, const Value* args, hawk_oow_
ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs); ptr = (hawk_val_t**)hawk_allocmem(this->hawk, HAWK_SIZEOF(hawk_val_t*) * nargs);
if (ptr == HAWK_NULL) if (ptr == HAWK_NULL)
{ {
this->runctx.setError (HAWK_ENOMEM); this->runctx.setError(HAWK_ENOMEM);
this->retrieveError(&this->runctx); this->retrieveError(&this->runctx);
return -1; return -1;
} }
@@ -2096,6 +2112,12 @@ void Hawk::halt ()
hawk_haltall (this->hawk); hawk_haltall (this->hawk);
} }
int Hawk::raiseSignal (int sig)
{
if (this->runctx.rtx) return hawk_rtx_raisesig(this->runctx.rtx, sig);
return -1;
}
int Hawk::init_runctx () int Hawk::init_runctx ()
{ {
if (this->runctx.rtx) return 0; if (this->runctx.rtx) return 0;
@@ -2118,6 +2140,9 @@ int Hawk::init_runctx ()
rxtn_t* rxtn = GET_RXTN(rtx); rxtn_t* rxtn = GET_RXTN(rtx);
rxtn->run = &this->runctx; rxtn->run = &this->runctx;
HAWK_MEMSET(&this->runctx.rtx_ecb, 0, HAWK_SIZEOF(this->runctx.rtx_ecb));
this->runctx.rtx_ecb.sigset = rtx_on_sigset;
hawk_rtx_pushecb(rtx, &this->runctx.rtx_ecb);
return 0; return 0;
} }
@@ -2142,7 +2167,7 @@ int Hawk::getTrait () const
void Hawk::setTrait (int trait) void Hawk::setTrait (int trait)
{ {
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
hawk_setopt (this->hawk, HAWK_OPT_TRAIT, &trait); hawk_setopt(this->hawk, HAWK_OPT_TRAIT, &trait);
} }
hawk_oow_t Hawk::getMaxDepth (depth_t id) const hawk_oow_t Hawk::getMaxDepth (depth_t id) const
@@ -2157,7 +2182,7 @@ hawk_oow_t Hawk::getMaxDepth (depth_t id) const
void Hawk::setMaxDepth (depth_t id, hawk_oow_t depth) void Hawk::setMaxDepth (depth_t id, hawk_oow_t depth)
{ {
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
hawk_setopt (this->hawk, (hawk_opt_t)id, &depth); hawk_setopt(this->hawk, (hawk_opt_t)id, &depth);
} }
int Hawk::setIncludeDirs (const hawk_uch_t* dirs) int Hawk::setIncludeDirs (const hawk_uch_t* dirs)
@@ -2179,11 +2204,11 @@ int Hawk::setIncludeDirs (const hawk_bch_t* dirs)
{ {
#if defined(HAWK_OOCH_IS_UCH) #if defined(HAWK_OOCH_IS_UCH)
hawk_ooch_t* tmp; hawk_ooch_t* tmp;
tmp = hawk_dupbtoucstr(hawk, dirs, HAWK_NULL, 1); tmp = hawk_dupbtoucstr(this->hawk, dirs, HAWK_NULL, 1);
if (HAWK_UNLIKELY(!tmp)) return -1; if (HAWK_UNLIKELY(!tmp)) return -1;
int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp); int n = hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, tmp);
hawk_freemem(hawk, tmp); hawk_freemem(this->hawk, tmp);
return n; return n;
#else #else
return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs); return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);
@@ -2539,7 +2564,7 @@ int Hawk::getGlobal (int id, Value& v)
HAWK_ASSERT(this->hawk != HAWK_NULL); HAWK_ASSERT(this->hawk != HAWK_NULL);
HAWK_ASSERT(runctx.rtx != HAWK_NULL); HAWK_ASSERT(runctx.rtx != HAWK_NULL);
int n = runctx.getGlobal (id, v); int n = runctx.getGlobal(id, v);
if (n <= -1) this->retrieveError(); if (n <= -1) this->retrieveError();
return n; return n;
} }
@@ -2576,7 +2601,7 @@ int Hawk::addFunction (
hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler)); hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
if (!pair) if (!pair)
{ {
hawk_delfncwithbcstr (this->hawk, name); hawk_delfncwithbcstr(this->hawk, name);
this->retrieveError(); this->retrieveError();
return -1; return -1;
} }
@@ -2586,7 +2611,7 @@ int Hawk::addFunction (
catch (...) { pair = HAWK_NULL; } catch (...) { pair = HAWK_NULL; }
if (!pair) if (!pair)
{ {
hawk_delfncwithbcstr (this->hawk, name); hawk_delfncwithbcstr(this->hawk, name);
this->setError(HAWK_ENOMEM); this->setError(HAWK_ENOMEM);
return -1; return -1;
} }
@@ -2627,7 +2652,7 @@ int Hawk::addFunction (
hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler)); hawk_htb_pair_t* pair = hawk_htb_upsert(this->functionMap, (hawk_ooch_t*)fnc->name.ptr, fnc->name.len, &handler, HAWK_SIZEOF(handler));
if (HAWK_UNLIKELY(!pair)) if (HAWK_UNLIKELY(!pair))
{ {
hawk_delfncwithucstr (this->hawk, name); hawk_delfncwithucstr(this->hawk, name);
this->retrieveError(); this->retrieveError();
return -1; return -1;
} }
@@ -2637,7 +2662,7 @@ int Hawk::addFunction (
catch (...) { pair = HAWK_NULL; } catch (...) { pair = HAWK_NULL; }
if (HAWK_UNLIKELY(!pair)) if (HAWK_UNLIKELY(!pair))
{ {
hawk_delfncwithucstr (this->hawk, name); hawk_delfncwithucstr(this->hawk, name);
this->setError(HAWK_ENOMEM); this->setError(HAWK_ENOMEM);
return -1; return -1;
} }

View File

@@ -1330,6 +1330,7 @@ public:
protected: protected:
Hawk* hawk; Hawk* hawk;
hawk_rtx_t* rtx; hawk_rtx_t* rtx;
hawk_rtx_ecb_t rtx_ecb;
}; };
/// ///
@@ -1389,6 +1390,11 @@ public:
/// ///
virtual void uponClearing (); virtual void uponClearing ();
/// The uponSigset() function is called back when sys::signal()
/// attempts to set or unset a signal handler. This maps to the
/// sigset callback of #hawk_rtx_ecb_t.
virtual void uponSigset (Run& run, int sig, bool reset);
/// ///
/// The parse() function parses the source code read from the input /// The parse() function parses the source code read from the input
/// stream \a in and writes the parse tree to the output stream \a out. /// stream \a in and writes the parse tree to the output stream \a out.
@@ -1477,6 +1483,7 @@ public:
/// The halt() function makes request to abort execution /// The halt() function makes request to abort execution
/// ///
void halt (); void halt ();
int raiseSignal (int sig);
/// \} /// \}
/// ///

View File

@@ -172,7 +172,7 @@ int HawkStd::open ()
return 0; return 0;
oops: oops:
Hawk::close (); Hawk::close();
return -1; return -1;
} }
@@ -180,11 +180,11 @@ void HawkStd::close ()
{ {
if (this->cmgrtab_inited) if (this->cmgrtab_inited)
{ {
hawk_htb_fini (&this->cmgrtab); hawk_htb_fini(&this->cmgrtab);
this->cmgrtab_inited = false; this->cmgrtab_inited = false;
} }
clearConsoleOutputs (); clearConsoleOutputs();
// //
// HawkStd called hawk_stdmodstartup() after Hawk::open(). // HawkStd called hawk_stdmodstartup() after Hawk::open().
@@ -198,12 +198,12 @@ void HawkStd::close ()
// //
//if (this->stdmod_up) //if (this->stdmod_up)
//{ //{
// hawk_stdmodshutdown (this->hawk); // hawk_stdmodshutdown(this->hawk);
// this->stdmod_up = false; // this->stdmod_up = false;
//} //}
// //
Hawk::close (); Hawk::close();
} }
void HawkStd::uponClosing () void HawkStd::uponClosing ()
@@ -215,7 +215,7 @@ void HawkStd::uponClosing ()
} }
// chain up // chain up
Hawk::uponClosing (); Hawk::uponClosing();
} }
HawkStd::Run* HawkStd::parse (Source& in, Source& out) HawkStd::Run* HawkStd::parse (Source& in, Source& out)
@@ -227,7 +227,7 @@ HawkStd::Run* HawkStd::parse (Source& in, Source& out)
// if cmgrtab has already been initialized, // if cmgrtab has already been initialized,
// just clear the contents regardless of // just clear the contents regardless of
// parse() result. // parse() result.
hawk_htb_clear (&this->cmgrtab); hawk_htb_clear(&this->cmgrtab);
} }
else if (run && (this->getTrait() & HAWK_RIO)) else if (run && (this->getTrait() & HAWK_RIO))
{ {
@@ -240,11 +240,11 @@ HawkStd::Run* HawkStd::parse (Source& in, Source& out)
this->setError (HAWK_ENOMEM); this->setError (HAWK_ENOMEM);
return HAWK_NULL; return HAWK_NULL;
} }
hawk_htb_setstyle (&this->cmgrtab, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER)); hawk_htb_setstyle(&this->cmgrtab, hawk_get_htb_style(HAWK_HTB_STYLE_INLINE_KEY_COPIER));
this->cmgrtab_inited = true; this->cmgrtab_inited = true;
} }
if (run && make_additional_globals(run) <= -1) return HAWK_NULL; if (run && this->make_additional_globals(run) <= -1) return HAWK_NULL;
return run; return run;
} }
@@ -553,8 +553,8 @@ int HawkStd::open_nwio (Pipe& io, int flags, void* nwad)
if (cmgr) hawk_nwio_setcmgr(handle, cmgr); if (cmgr) hawk_nwio_setcmgr(handle, cmgr);
#endif #endif
io.setHandle ((void*)handle); io.setHandle((void*)handle);
io.setUflags (1); io.setUflags(1);
return 1; return 1;
} }
@@ -594,8 +594,8 @@ int HawkStd::open_pio (Pipe& io)
hawk_pio_setcmgr(pio, HAWK_PIO_ERR, cmgr); hawk_pio_setcmgr(pio, HAWK_PIO_ERR, cmgr);
} }
#endif #endif
io.setHandle (pio); io.setHandle(pio);
io.setUflags (0); io.setUflags(0);
return 1; return 1;
} }
@@ -618,7 +618,7 @@ static int parse_rwpipe_uri (const hawk_ooch_t* uri, int* flags, hawk_nwad_t* nw
for (i = 0; i < HAWK_COUNTOF(x); i++) for (i = 0; i < HAWK_COUNTOF(x); i++)
{ {
if (hawk_strzcmp (uri, x[i].prefix, x[i].len) == 0) if (hawk_strzcmp(uri, x[i].prefix, x[i].len) == 0)
{ {
if (hawk_strtonwad (uri + x[i].len, nwad) <= -1) return -1; if (hawk_strtonwad (uri + x[i].len, nwad) <= -1) return -1;
*flags = x[i].flags; *flags = x[i].flags;
@@ -656,7 +656,7 @@ int HawkStd::closePipe (Pipe& io)
if (io.getUflags() > 0) if (io.getUflags() > 0)
{ {
/* nwio can't honor partical close */ /* nwio can't honor partical close */
hawk_nwio_close ((hawk_nwio_t*)io.getHandle()); hawk_nwio_close((hawk_nwio_t*)io.getHandle());
} }
else else
{ {
@@ -677,7 +677,7 @@ int HawkStd::closePipe (Pipe& io)
} }
} }
hawk_pio_close (pio); hawk_pio_close(pio);
#if defined(ENABLE_NWIO) #if defined(ENABLE_NWIO)
} }
#endif #endif
@@ -850,7 +850,7 @@ int HawkStd::addConsoleOutput (const hawk_bch_t* arg)
void HawkStd::clearConsoleOutputs () void HawkStd::clearConsoleOutputs ()
{ {
this->ofile.clear (this->hawk); this->ofile.clear(this->hawk);
} }
static int check_var_assign (hawk_rtx_t* rtx, const hawk_ooch_t* str) static int check_var_assign (hawk_rtx_t* rtx, const hawk_ooch_t* str)
@@ -1243,7 +1243,7 @@ void* HawkStd::modopen (const hawk_mod_spec_t* spec)
void HawkStd::modclose (void* handle) void HawkStd::modclose (void* handle)
{ {
hawk_stdmodclose (this->hawk, handle); hawk_stdmodclose(this->hawk, handle);
} }
void* HawkStd::modgetsym (void* handle, const hawk_ooch_t* name) void* HawkStd::modgetsym (void* handle, const hawk_ooch_t* name)
@@ -1326,13 +1326,13 @@ int HawkStd::SourceFile::open (Data& io)
if (totlen >= HAWK_COUNTOF(fbuf)) if (totlen >= HAWK_COUNTOF(fbuf))
{ {
dbuf = (hawk_ooch_t*)hawk_allocmem((hawk_t*)io, HAWK_SIZEOF(hawk_ooch_t) * (totlen + 1)); dbuf = (hawk_ooch_t*)hawk_allocmem((hawk_t*)io, HAWK_SIZEOF(hawk_ooch_t) * (totlen + 1));
if (!dbuf) return -1; if (HAWK_UNLIKELY(!dbuf)) return -1;
path = dbuf; path = dbuf;
} }
else path = fbuf; else path = fbuf;
tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen); tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen);
hawk_copy_oocstr_unlimited ((hawk_ooch_t*)path + tmplen, ioname); hawk_copy_oocstr_unlimited((hawk_ooch_t*)path + tmplen, ioname);
} }
} }
@@ -1370,8 +1370,8 @@ int HawkStd::SourceFile::open (Data& io)
); );
if (!sio) return -1; if (!sio) return -1;
io.setPath (xpath); io.setPath(xpath);
io.setHandle (sio); io.setHandle(sio);
if (this->cmgr) hawk_sio_setcmgr(sio, this->cmgr); if (this->cmgr) hawk_sio_setcmgr(sio, this->cmgr);
} }
@@ -1382,7 +1382,7 @@ int HawkStd::SourceFile::open (Data& io)
int HawkStd::SourceFile::close (Data& io) int HawkStd::SourceFile::close (Data& io)
{ {
hawk_sio_t* sio = (hawk_sio_t*)io.getHandle(); hawk_sio_t* sio = (hawk_sio_t*)io.getHandle();
hawk_sio_flush (sio); hawk_sio_flush(sio);
hawk_sio_close(sio); hawk_sio_close(sio);
return 0; return 0;
} }
@@ -1483,7 +1483,7 @@ int HawkStd::SourceString::open (Data& io)
else path = fbuf; else path = fbuf;
tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen); tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen);
hawk_copy_oocstr_unlimited ((hawk_ooch_t*)path + tmplen, ioname); hawk_copy_oocstr_unlimited((hawk_ooch_t*)path + tmplen, ioname);
} }
} }
xpath = hawk_addsionamewithoochars((hawk_t*)io, path, hawk_count_oocstr(path)); xpath = hawk_addsionamewithoochars((hawk_t*)io, path, hawk_count_oocstr(path));

View File

@@ -1369,7 +1369,7 @@ static hawk_ooi_t sf_in_open (hawk_t* hawk, hawk_sio_arg_t* arg, xtn_t* xtn)
else path = fbuf; else path = fbuf;
tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen); tmplen = hawk_copy_oochars_to_oocstr_unlimited((hawk_ooch_t*)path, outer, dirlen);
hawk_copy_oocstr_unlimited ((hawk_ooch_t*)path + tmplen, arg->name); hawk_copy_oocstr_unlimited((hawk_ooch_t*)path + tmplen, arg->name);
} }
} }
@@ -2021,7 +2021,7 @@ static int parse_rwpipe_uri (const hawk_ooch_t* uri, int* flags, hawk_nwad_t* nw
for (i = 0; i < HAWK_COUNTOF(x); i++) for (i = 0; i < HAWK_COUNTOF(x); i++)
{ {
if (hawk_strzcmp (uri, x[i].prefix, x[i].len) == 0) if (hawk_strzcmp(uri, x[i].prefix, x[i].len) == 0)
{ {
if (hawk_strtonwad (uri + x[i].len, nwad) <= -1) return -1; if (hawk_strtonwad (uri + x[i].len, nwad) <= -1) return -1;
*flags = x[i].flags; *flags = x[i].flags;
@@ -2129,7 +2129,7 @@ static hawk_ooi_t pio_handler_rest (hawk_rtx_t* rtx, hawk_rio_cmd_t cmd, hawk_ri
case HAWK_RIO_CMD_FLUSH: case HAWK_RIO_CMD_FLUSH:
/*if (riod->mode == HAWK_RIO_PIPE_READ) return -1;*/ /*if (riod->mode == HAWK_RIO_PIPE_READ) return -1;*/
return hawk_pio_flush ((hawk_pio_t*)riod->handle, HAWK_PIO_IN); return hawk_pio_flush((hawk_pio_t*)riod->handle, HAWK_PIO_IN);
case HAWK_RIO_CMD_NEXT: case HAWK_RIO_CMD_NEXT:
break; break;

View File

@@ -5,11 +5,11 @@
%define __brp_remove_la_files /bin/true %define __brp_remove_la_files /bin/true
%define source_date_epoch_from_changelog 0 %define source_date_epoch_from_changelog 0
%define enable_mod_ffi 1 %{!?enable_mod_ffi:%define enable_mod_ffi 1}
%define enable_mod_memc 0 %{!?enable_mod_memc:%define enable_mod_memc 0}
%define enable_mod_mysql 1 %{!?enable_mod_mysql:%define enable_mod_mysql 1}
%define enable_mod_sqlite 1 %{!?enable_mod_sqlite:%define enable_mod_sqlite 1}
%define enable_mod_uci 0 %{!?enable_mod_uci:%define enable_mod_uci 0}
Summary: Hawk Interpreter Summary: Hawk Interpreter
Name: @PACKAGE_NAME@ Name: @PACKAGE_NAME@
@@ -26,20 +26,31 @@ Requires: %{name}-libs%{?_isa}
## prep_cif_var() available since 3.0.11 ## prep_cif_var() available since 3.0.11
BuildRequires: libffi-devel%{?_isa} >= 3.0.11 BuildRequires: libffi-devel%{?_isa} >= 3.0.11
%endif %endif
%if %{enable_mod_memc} %if %{enable_mod_memc}
BuildRequires: libmemcached-devel%{?_isa} >= 1.0.18 BuildRequires: libmemcached-devel%{?_isa} >= 1.0.18
%endif %endif
%if %{enable_mod_mysql} %if %{enable_mod_mysql}
##BuildRequires: mariadb-connector-c-devel%{?_isa}
%if 0%{?fedora} > 22
BuildRequires: mariadb-connector-c-devel%{?_isa}
%else
%if 0%{?suse_version} > 0 %if 0%{?suse_version} > 0
BuildRequires: libmariadb-devel%{?_isa} BuildRequires: libmariadb-devel%{?_isa}
%else %else
BuildRequires: mysql-devel%{?_isa} BuildRequires: mysql-devel%{?_isa}
%endif %endif
%endif %endif
%endif
%if %{enable_mod_sqlite} %if %{enable_mod_sqlite}
BuildRequires: sqlite-devel%{?_isa} BuildRequires: sqlite-devel%{?_isa}
%endif %endif
%if %{enable_mod_uci} %if %{enable_mod_uci}
BuildRequires: libuci-devel%{?_isa} BuildRequires: libuci-devel%{?_isa}
%endif %endif
@@ -83,8 +94,19 @@ This package contains the memc module file for Hawk.
Summary: Hawk mysql module Summary: Hawk mysql module
Group: System Environment/Libraries Group: System Environment/Libraries
Requires: %{name}-libs%{?_isa} = %{version} Requires: %{name}-libs%{?_isa} = %{version}
%if 0%{?fedora} > 22
Requires: mariadb-connector-c%{?_isa}
%else
%if 0%{?suse_version} > 0
Requires: libmariadb%{?_isa}
%else
## tricky to specify the right mysql/mariadb client library. ## tricky to specify the right mysql/mariadb client library.
##Requires: mariadb-connector-c%{?_isa} Requires:
%endif
%endif
%description mysql %description mysql
This package contains the mysql module file for Hawk. This package contains the mysql module file for Hawk.

View File

@@ -54,6 +54,15 @@ typedef HAWK::HawkStd HawkStd;
typedef HAWK::HawkStd::Run Run; typedef HAWK::HawkStd::Run Run;
typedef HAWK::HawkStd::Value Value; typedef HAWK::HawkStd::Value Value;
#ifdef _WIN32
static BOOL WINAPI stop_run (DWORD ctrl_type);
#else
static void stop_run (int sig);
static void do_nothing (int sig);
#endif
static void relay_signal (int sig);
static int setsignal (int sig, void(*handler)(int), int restart);
class MyHawk: public HawkStd class MyHawk: public HawkStd
{ {
public: public:
@@ -80,6 +89,26 @@ public:
return -1; return -1;
} }
void uponSigset (Run& run, int sig, bool reset)
{
if (reset)
{
/* this part must be in sync with set_singal() */
if (sig == SIGINT)
setsignal(sig, stop_run, 0);
#if defined(SIGPIPE)
else if (sig == SIGPIPE)
setsignal(sig, do_nothing, 0);
#endif
else
setsignal(sig, SIG_DFL, 0);
}
else
{
setsignal(sig, relay_signal, 0);
}
}
int sleep (Run& run, Value& ret, Value* args, hawk_oow_t nargs, const hawk_ooch_t* name, hawk_oow_t len) int sleep (Run& run, Value& ret, Value* args, hawk_oow_t nargs, const hawk_ooch_t* name, hawk_oow_t len)
{ {
if (args[0].isIndexed()) if (args[0].isIndexed())
@@ -169,6 +198,11 @@ private:
static MyHawk* app_hawk = HAWK_NULL; static MyHawk* app_hawk = HAWK_NULL;
static void relay_signal (int sig)
{
if (app_hawk) app_hawk->raiseSignal(sig);
}
static void print_error (const hawk_bch_t* fmt, ...) static void print_error (const hawk_bch_t* fmt, ...)
{ {
va_list va; va_list va;
@@ -201,7 +235,7 @@ static BOOL WINAPI stop_run (DWORD ctrl_type)
if (ctrl_type == CTRL_C_EVENT || if (ctrl_type == CTRL_C_EVENT ||
ctrl_type == CTRL_CLOSE_EVENT) ctrl_type == CTRL_CLOSE_EVENT)
{ {
if (app_hawk) app_hawk->stop (); if (app_hawk) app_hawk->halt();
return TRUE; return TRUE;
} }
@@ -214,7 +248,7 @@ static int setsignal (int sig, void(*handler)(int), int restart)
struct sigaction sa_int; struct sigaction sa_int;
sa_int.sa_handler = handler; sa_int.sa_handler = handler;
sigemptyset (&sa_int.sa_mask); sigemptyset(&sa_int.sa_mask);
sa_int.sa_flags = 0; sa_int.sa_flags = 0;
@@ -230,13 +264,13 @@ static int setsignal (int sig, void(*handler)(int), int restart)
sa_int.sa_flags |= SA_INTERRUPT; sa_int.sa_flags |= SA_INTERRUPT;
#endif #endif
} }
return sigaction (sig, &sa_int, NULL); return sigaction(sig, &sa_int, NULL);
} }
static void stop_run (int sig) static void stop_run (int sig)
{ {
int e = errno; int e = errno;
if (app_hawk) app_hawk->halt (); if (app_hawk) app_hawk->halt();
errno = e; errno = e;
} }
@@ -249,21 +283,21 @@ static void do_nothing (int sig)
static void set_signal (void) static void set_signal (void)
{ {
#ifdef _WIN32 #ifdef _WIN32
SetConsoleCtrlHandler (stop_run, TRUE); SetConsoleCtrlHandler(stop_run, TRUE);
#else #else
/*setsignal (SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/ /*setsignal(SIGINT, stop_run, 1); TO BE MORE COMPATIBLE WITH WIN32*/
setsignal (SIGINT, stop_run, 0); setsignal(SIGINT, stop_run, 0);
setsignal (SIGPIPE, do_nothing, 0); setsignal(SIGPIPE, do_nothing, 0);
#endif #endif
} }
static void unset_signal (void) static void unset_signal(void)
{ {
#ifdef _WIN32 #ifdef _WIN32
SetConsoleCtrlHandler (stop_run, FALSE); SetConsoleCtrlHandler(stop_run, FALSE);
#else #else
setsignal (SIGINT, SIG_DFL, 1); setsignal(SIGINT, SIG_DFL, 1);
setsignal (SIGPIPE, SIG_DFL, 1); setsignal(SIGPIPE, SIG_DFL, 1);
#endif #endif
} }