4

I have a c++ program that handles several signals to perform different actions, using signal:

    signal(SIGHUP, signal_handler);

I wanted to extend this signal handling to allow me to send different action requests to my program, and found that using sigaction I would be able to receive extra information along with the signal:

    sigaction(SIGUSR1, &act, 0);

For what I could find, I am able to send this type of signals from other programs, setting extra information on the sigval object, so that I know, on the receiving end, what the program was requested to do.

What I wanted to know is how can I send this type of signal information through a shell script on bash. Is it possible? I can send signals to my program using kill -S SIGHUP [PID] but I do not find a way to send that extra parameter using kill, so I was wondering if bash has any command that emulates the sigaction / sigqueue behaviour, allowing me to send signals to my app without having to develop another application to do the job.

1

Your information seems to be outdated. From my sigaction man page:

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.

  • I did not know that... Is there another way of achieving this, that you know of? – BlunT Oct 1 '15 at 8:05
  • Most programs will use, say, 3 different signals to request 3 different actions, but to pass more information, typically the info is put in a known file, then the program is signalled and it reads the file to see what it should do. If there is a lot of communication going on, programs will instead do something like open a (unix domain) socket and listen for requests on it. If you want to easily communicate from bash, you could have your program read a named pipe (see mkfifo), as bash can easily write to such a device. – meuh Oct 1 '15 at 8:17
1

It is possible to send and receive extra parameters using sigqueue() and si_value in siginfo_t. "This use is obsolete now" in sigaction() is perhaps referring to use of sa_handler with two arguments with second one being sigcontext. After introduction of SA_SIGINFO, there's no need to use such an undocumented handler, since all handlers take siginfo_t argument which has the si_value field.

However, I don't know a way to queue a signal with payload from the shell, you may need to write a small C program for that.

0

This works. First, set SA_SIGINFO to .sa_flags to signal an interest in extra info:

#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();
    }

}

Second, create your own kill(er) app capable of sending such extra info:

#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);
}

You can try compiling these two and you should be able to use the second executable to send integers to the first one (./second pid int).

The manpages should provide you with more information on how to build on this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.