Compare commits

..

2 Commits

Author SHA1 Message Date
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
9 changed files with 176 additions and 59 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)
- [Comments](#comments)
- [Reserved Words](#reserved-words)
- [More Examples](#more-examples)
- [Some Examples](#some-examples)
- [Garbage Collection](#garbage-collection)
- [Modules](#modules)
- [Hawk](#hawk)
@@ -1012,6 +1012,29 @@ The `sys` module provides various functions concerning the underlying operation
- sys::wait
- 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.
@@ -1025,6 +1048,8 @@ BEGIN {
}
```
#### Wrap a file descriptor
You can map a raw file descriptor to a handle created by this module and use it.
```awk
@@ -1037,6 +1062,8 @@ BEGIN {
}
```
#### Pipe to a child process
Creating pipes and sharing them with a child process is not big an issue.
```awk
@@ -1091,6 +1118,8 @@ BEGIN {
}
```
#### Read child stdout
You can read standard output of a child process in a parent process.
```awk
@@ -1142,6 +1171,8 @@ BEGIN {
}
```
#### Duplicate file handles
You can duplicate file handles as necessary.
```awk
@@ -1165,6 +1196,8 @@ BEGIN {
}
```
#### Directory traversal
Directory traversal is easy.
```awk
@@ -1183,6 +1216,8 @@ BEGIN {
}
```
#### Network interface info
You can get information of a network interface.
```awk
@@ -1194,6 +1229,8 @@ BEGIN {
}
```
#### Sockets
Socket functions are available.
```awk

View File

@@ -341,7 +341,14 @@ static void on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
else
{
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 (sig == SIGTERM) back_to_stop_run = 1;
#endif
@@ -351,7 +358,10 @@ static void on_sigset (hawk_rtx_t* rtx, int sig, hawk_fun_t* fun)
#if defined(SIGINT)
if (sig == SIGINT) back_to_stop_run = 1;
#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
s = syscall.Signal(signo)
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()
}
} 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
s = syscall.Signal(signo)
if reset {

View File

@@ -632,7 +632,7 @@ func (rtx* Rtx) Halt() {
C.hawk_rtx_halt(rtx.c)
}
func (rtx *Rtx) SetSigsetHandler(f RtxSigsetHandler) {
func (rtx *Rtx) OnSigset(f RtxSigsetHandler) {
rtx.sigset_handler = f
}
@@ -814,6 +814,8 @@ func (rtx *Rtx) GetNamedVars(vars map[string]*Val) {
//export hawk_go_sigset_handler
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 rtx_inst RtxInstance
var rtx *Rtx
@@ -822,8 +824,10 @@ 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 = rtx_inst.g.Value()
if rtx.sigset_handler != nil {
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)))
#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
//////////////////////////////////////////////////////////////////
@@ -1935,6 +1946,11 @@ void Hawk::uponClearing ()
// nothing to do
}
void Hawk::uponSigset (Run& run, int sig, bool reset)
{
// nothing to do
}
Hawk::Run* Hawk::parse (Source& in, Source& out)
{
HAWK_ASSERT(this->hawk != HAWK_NULL);
@@ -2096,6 +2112,12 @@ void Hawk::halt ()
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 ()
{
if (this->runctx.rtx) return 0;
@@ -2118,6 +2140,9 @@ int Hawk::init_runctx ()
rxtn_t* rxtn = GET_RXTN(rtx);
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;
}
@@ -2179,11 +2204,11 @@ int Hawk::setIncludeDirs (const hawk_bch_t* dirs)
{
#if defined(HAWK_OOCH_IS_UCH)
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;
int n = hawk_setopt(hawk, HAWK_OPT_INCLUDEDIRS, tmp);
hawk_freemem(hawk, tmp);
int n = hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, tmp);
hawk_freemem(this->hawk, tmp);
return n;
#else
return hawk_setopt(this->hawk, HAWK_OPT_INCLUDEDIRS, dirs);

View File

@@ -1330,6 +1330,7 @@ public:
protected:
Hawk* hawk;
hawk_rtx_t* rtx;
hawk_rtx_ecb_t rtx_ecb;
};
///
@@ -1389,6 +1390,11 @@ public:
///
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
/// 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
///
void halt ();
int raiseSignal (int sig);
/// \}
///

View File

@@ -244,7 +244,7 @@ HawkStd::Run* HawkStd::parse (Source& in, Source& out)
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;
}
@@ -1326,7 +1326,7 @@ int HawkStd::SourceFile::open (Data& io)
if (totlen >= HAWK_COUNTOF(fbuf))
{
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;
}
else path = fbuf;

View File

@@ -54,6 +54,15 @@ typedef HAWK::HawkStd HawkStd;
typedef HAWK::HawkStd::Run Run;
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
{
public:
@@ -80,6 +89,26 @@ public:
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)
{
if (args[0].isIndexed())
@@ -169,6 +198,11 @@ private:
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, ...)
{
va_list va;
@@ -201,7 +235,7 @@ static BOOL WINAPI stop_run (DWORD ctrl_type)
if (ctrl_type == CTRL_C_EVENT ||
ctrl_type == CTRL_CLOSE_EVENT)
{
if (app_hawk) app_hawk->stop ();
if (app_hawk) app_hawk->halt();
return TRUE;
}