Enviando sigaction / sigaction através do shell

4

Eu tenho um programa c ++ que lida com vários sinais para executar diferentes ações, usando signal:

    signal(SIGHUP, signal_handler);

Eu queria estender esse tratamento de sinal para permitir que eu enviasse solicitações de ação diferentes para o meu programa, e descobri que usando sigaction eu seria capaz de receber informações extras junto com o sinal:

    sigaction(SIGUSR1, &act, 0);

Para o que pude encontrar, eu sou capaz de enviar este tipo de sinais de outros programas, definindo informações extras sobre o objeto sigval, para que eu saiba, no final do recebimento, o que o programa foi solicitado a fazer.

O que eu queria saber é como posso enviar este tipo de informação de sinal através de um script de shell no bash. É possível? Eu posso enviar sinais para o meu programa usando kill -S SIGHUP [PID] , mas eu não encontrar uma maneira de enviar esse parâmetro extra usando kill , então eu queria saber se bash tem qualquer comando que emula o comportamento sigaction / sigqueue, permitindo-me enviar sinais para o meu aplicativo sem ter que desenvolver outro aplicativo para fazer o trabalho.

    
por BlunT 30.09.2015 / 13:09

3 respostas

1

Sua informação parece estar desatualizada. Na minha página sigaction man:

Undocumented. Before the introduction of SA_SIGINFO it was also possible to get some additional information, namely by using a sa_handler with second argu- ment of type struct sigcontext. This use is obsolete now.

    
por 30.09.2015 / 19:11
1

É possível enviar e receber parâmetros extras usando sigqueue() e si_value em siginfo_t . "Esse uso está obsoleto agora", em sigaction() , talvez esteja se referindo ao uso de sa_handler com dois argumentos, com o segundo sendo sigcontext . Após a introdução de SA_SIGINFO , não há necessidade de usar um manipulador não documentado, pois todos os manipuladores aceitam o argumento siginfo_t que possui o campo si_value .

No entanto, eu não sei como enfileirar um sinal com payload do shell, você pode precisar escrever um pequeno programa em C para isso.

    
por 22.03.2017 / 23:29
0

Isso funciona. Primeiro, defina SA_SIGINFO para .sa_flags para sinalizar um interesse em informações adicionais:

#include <signal.h>
#include <unistd.h>
void act(int s, siginfo_t *i, void *v)
{
    //printing from here is unsafe but this is for testing 
    //purposes only
    printf("pid=%d val=%d\n", i->si_pid, i->si_value.sival_int);
}
int main(int argc, char **argv)
{
    struct sigaction sa = { 
        .sa_sigaction=act ,
        .sa_flags = SA_RESTART|SA_SIGINFO
    } ;
    sigaction(SIGUSR1, &sa, NULL);
    printf("%d\n", (int)getpid());
    for(;;){
        pause();
    }

}

Em segundo lugar, crie seu próprio aplicativo kill (er) capaz de enviar informações extras:

#include <signal.h>
#include <unistd.h>

int main(int argc, char**argv)
{
    union sigval val = { .sival_int = atoi(argv[2]) };
    sigqueue((pid_t)atoi(argv[1]), SIGUSR1, val);
}

Você pode tentar compilar esses dois e deverá usar o segundo executável para enviar inteiros ao primeiro ( ./second pid int ).

As páginas de manual devem fornecer mais informações sobre como criar isso.

    
por 23.03.2017 / 01:53

Tags