The program is prompted to exit (core spitting).

/* sigactdemo.c
 *               purpose: shows use of sigaction()
 *               feature: blocks ^\ while handling ^C
 *                        does not reset ^C handler, so two kill
 */

-sharpinclude    <stdio.h>
-sharpinclude    <signal.h>
-sharpdefine    INPUTLEN    100

main()
{
    struct sigaction newhandler;            /* new settings        */
    sigset_t         blocked;               /* set of blocked sigs */
    void         inthandler();          /* the handler         */
    char         x[INPUTLEN];

    /* load these two members first */
    newhandler.sa_handler = inthandler;      /* handler function    */
    newhandler.sa_flags = SA_RESETHAND | SA_RESTART;  /* options    */

    /* then build the list of blocked signals */
    sigemptyset(&blocked);                  /* clear all bits      */
    sigaddset(&blocked, SIGQUIT);        /* add SIGQUIT to list */

    newhandler.sa_mask = blocked;        /* store blockmask     */

    if ( sigaction(SIGINT, &newhandler, NULL) == -1 )
        perror("sigaction");
    else
        while( 1 ){
            fgets(x, INPUTLEN, stdin);
            printf("input: %s", x);
        }
}

void inthandler(int s)
{
    printf("Called with signal %d\n", s);
    sleep(s);
    printf("done handling signal %d\n", s);
}

Unix/Linux system programming practice tutorial book P205 page example, the above use of the function sigaction, is mainly to demonstrate blocking SIGQUIT (ctrl + when processing SIGINT (ctrl + C), search the lower structure sigcation the function of sa_mask is to block the signal when processing, so use sigaddset and other functions to add SIGQUIT signal, but report an error during execution

[root@centos-linux-7 CH07]-sharp ./sigactdemo 
^\()
[root@centos-linux-7 CH07]-sharp gcc -v
 specs
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
:x86_64-redhat-linux
:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,cPP,objc,obj-cPP,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
:posix
gcc  4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
[root@centos-linux-7 CH07]-sharp 
Apr.05,2021

There is nothing wrong with the

code.

by default, the SIGQUIT signal causes the process to terminate and produces Core Dump, which you describe as "spitting kernel".

when the process is interrupted by the SIGINT signal, the process will not be terminated immediately because the setting sa_mask blocks SIGQUIT . It will proceed after the SIGINT signal processing is completed.

you can compare sa_mask emptying once, and the operation flow is the same both times, as follows

  1. run the compiled file
  2. Press Ctrl + c, which produces SIGINT signal
  3. when "Called with signal 2" is displayed, press Ctrl +\, which will generate SIGQUIT signal

the following is the running result

  • blocks SIGQUIT
^CCalled with signal 2
^\done handling signal 2
[N]    NNN quit (core dumped)  ./xxx
  • is not blocked SIGQUIT
^CCalled with signal 2
^\[N]    NNN quit (core dumped)  ./xxx
Menu