Hi Constantine,

> I still want to use `libcurl` in PicoLisp and want default signal processing
> during long operations like `curl_easy_perform`, so I can i.e. terminate the
> script by Ctrl-C. I made this function (naming convensions are not so good):
> 
> (de defsigint Prg
>    (let action_size 160
>       (buf defaction action_size
>          (%@ "memset" NIL defaction 0 action_size)
>          (buf oldaction action_size
>             (%@ "sigaction" 'N 2 defaction oldaction)
>             (run Prg)
>             (%@ "sigaction" 'N 2 oldaction 0) ) ) ) )

Off~Topic, two notes:

   * The naming conventions are good, just the three local variables should be
     upper-cased)

   * sigaction() returns an integer, so the call is better
     (%@ "sigaction" 'I 2 ...


> This function sets SIGINT to default and then restores the original.

OK


I think you could instead simply reset SIGINT at the beginning of your script:

   #!/usr/bin/pil

   (%@ "signal" NIL 2 0)
   ...

There is no need to restore the original signal handler, as you want to
terminate the script anyway.


> This code is non-portable and hacky

The only nonportable things here are the constant SIGINT (which is usually 2
anyway) and the structure size. It would be sufficient to extend @src/sysdefs.c
by adding a "signal" section

   ttl("errno");

and constants like

   num("SIG_DFL", SIG_DFL);
   num("SIG_IGN", SIG_IGN);
   num("SIGINT", SIGINT);

and then call

   #!/usr/bin/pil

   (sysdefs "signal")
   (%@ "signal" NIL SIGINT SIG_DFL)


> so I decided to patch PicoLisp to implement
> signal processing right way: make tools for saving, restoring signal handlers
> and make them universal instead of predefined set of signals. (I have an idea 
> to
> make PicoLisp the only scripting tool on my Linux.)

OK, which other signals than SIGINT do you have in mind?


> But I confused with the source code. I.e. I see `sighandler` func, I see that 
> it
> used only in `sigChk` func. So I can't get a picture of how signal processing 
> is
> working in PicoLisp.

Correct, 'sighandler' does the actual dispatching of signals to the handlers
defined in Lisp code.

> Could you make some brief explanations of functions of signal processing in
> PicoLisp please?

Sure! I try!


The low-level signal handler, installed via sigaction() in iSignal(), is sig():

   (de void sig ((i32 . N))
      (if (val $TtyPid)
         (kill @ N)
         (set $Signal (+ (val $Signal) 1))
         (let P (ofs $Signal (gSignal N))
            (set P (+ (val P) 1)) ) ) )

It basically does nothing except remembering (counting) the signal in the global
'$Signal' array.

This is necessary, because a running PicoLisp must not be interrupted the hard
way. It may be in a critical phase like garbage collection or database
transactions. If for example a garbage collection is interrupted, no Lisp code
can be run, because the heap is in an unusable state (all pointers are
modified).

Thus, the interpreter needs to check for possibly remembered signals at "safe"
points. These are the 'sigChk' calls you saw.

   (inline sigChk (Exe)
      (when (val $Signal)
         (sighandler Exe) ) )

The interpreter will handle all signal(s) which arrived meanwhile in
'sighandler', and then continue with normal processing.


> If I will make a patch with new signal processing will you accept such patch?

I'm not sure if this is possible without a major changes in the base system. Let
me know what your strategy is.

☺/ A!ex

-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to