Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

197
Visualizações
Signal Handler Example in The Linux Programming Interface

The following example from The Programming Linux Programming Interface by Michael Kerrisk

static void sigHandler(int sig){
    printf("Ouch!\n");
}

int main(int argc, char *argv[])
{
    int j;

    if (signal(SIGINT, sigHandler) == SIG_ERR)
    errExit("signal");

    for (j = 0; ; j++){
        printf("%d\n", j);
        sleep(3);
    }
}

is supposed print "Ouch!" to the terminal whenever the user types Control-C (CTRL+C); in the author's own example, he types it twice before finally quitting the terminal with Control-\ (CTRL+\ ).

When I do this, the program works as expected on only the first execution of CTRL+C. If I type it in for the second time, like the author does in his example, my program quits the terminal- it does not print "Ouch!" nor does it continue to run (looping).

I used the exact same code as given here, on the book's website:

Ouch.c

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Typically signal needs the signal handler to be re-installed. Otherwise, it defautlts to SIG_DFL (default action corresponding to the signal). The default action for SIGINT is to terminate the program.

Note that printf(3) is not one of the async-safe functions. So you could write(2) to to do the same. See the POSIX list of Async-signal-safe functions.

Re-installing it should make work as expected:

static void sigHandler(int sig){
    signal(SIGINT, sigHandler);
    write(STDOUT_FILENO, "Ouch!\n", 6);
}

This is one of the reasons why you should avoid signal and use sigaction instead. The above mentioned behaviour is not universal across platforms. So perhaps, the platform you are running is not what author tested his code on or you are using a different Linux kernal.

The behaviour where you need to re-install the signal handler upon receiving a signal is System V behaviour. But BSD semantics doesn't need re-installing. Until recently, Linux showed System V behaviour but it seems to have been fixed in the recent kernel and I do not see this on my 3.19 kernel but can see 2.6.32 kernel (considerably old).

Signal's documentation states:

 The situation on Linux is as follows:

   * The kernel's signal() system call provides System V semantics.

   * By default, in glibc 2 and later, the signal() wrapper function
     does not invoke the kernel system call.  Instead, it calls
     sigaction(2) using flags that supply BSD semantics.  This default
     behavior is provided as long as the _BSD_SOURCE feature test macro
     is defined.  By default, _BSD_SOURCE is defined; it is also
     implicitly defined if one defines _GNU_SOURCE, and can of course be
     explicitly defined.

   * On glibc 2 and later, if the _BSD_SOURCE feature test macro is not
     defined, then signal() provides System V semantics.  (The default
     implicit definition of _BSD_SOURCE is not provided if one invokes
     gcc(1) in one of its standard modes (-std=xxx or -ansi) or defines
     various other feature test macros such as _POSIX_SOURCE,
     _XOPEN_SOURCE, or _SVID_SOURCE; see feature_test_macros(7).)

So you could work around by defining _BSD_SOURCE to get BSD semantics. So behaviour you observe is mostly likely because the signal on your system follows System V semantics and recent Linux (and probably what Kerrisk tested it on) follows BSD semantics.

over 4 years ago · Santiago Trujillo Relatório

0

you should not use printf() in signal and exception handlers because they are not reentrant. printf also buffer data in memory before putting this to console so using fflush() will help to print but not recommended. for test purpose use counter(flag) in handler and use printf outside handler. do not use signal() to register handler as every flavor of unix(BSD,Linux) does not provide same implementation. Instead use sigaction.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda