How to Send Signal from One Program to Another

Signals between 2 programs

Assuming you mean POSIX signals, then yes. You can access the sender's PID through the si_pid member of siginfo_t, though you will need to use sigaction and the SA_SIGINFO flag to define your handler.

Non-POSIX systems (e.g. Windows) may not even have the concept of a signal (at least not in the POSIX sense), so none of this will apply.

How can you send a string given has argument to a program to another program using UNIX signals in C?

I've done the following:

  1. On the Client side, I've done this function to send bit by bit a char: (SIGUSR1 is 1 and SIGUSR2 is 0)

    int send_char_to_server(unsigned char c, int server_pid)
    {
    unsigned char bit;

    bit = 0b10000000;
    while (bit)
    {
    if (bit & c)
    {
    if (kill(server_pid, SIGUSR1) == -1)
    return (0);
    }
    else
    {
    if (kill(server_pid, SIGUSR2) == -1)
    return (0);
    }
    bit >>= 1;
    usleep(100);
    }
    return (1);
    }

    and I've also implemented a feedback handler that simply receives SIGUSR1 and exits correctly, if it takes more than 5sec to get feedback it displays an error message.




  1. On the Server side, I've created this struct and declared it has a global variable in order to access data, since I can't pass it as an argument:

    typedef struct s_data
    {
    char buffer[MAX_CHARS];
    unsigned char c;
    int index;
    int client_pid;
    } t_data;

    And I've also done 2 functions to handle both signals (SIGUSR1 and SIGUSR2):

    void    bit_on_handler(int sig, siginfo_t *info, void *ucontext)
    {
    unsigned char bit;

    (void)ucontext;
    (void)sig;
    bit = 0b10000000;
    g_data.c |= bit >> g_data.index;
    g_data.index++;
    if (!g_data.client_pid)
    g_data.client_pid = info->si_pid;
    }
    void bit_off_handler(int sig, siginfo_t *info, void *ucontext)
    {
    (void)ucontext;
    (void)sig;
    g_data.index++;
    if (!g_data.client_pid)
    g_data.client_pid = info->si_pid;
    }

    Since my server is not supposed to quit after receiving a message I've done the loop_handler function that adds the character received (the 8 signals sequence) to my buffer and resets the needed values back to 0.

    void    loop_handler(void)
    {
    int i;

    i = 0;
    while (1)
    {
    pause();
    if (g_data.index == 8)
    {
    while (g_data.buffer[i] && i < MAX_CHARS)
    i++;
    if (i == MAX_CHARS)
    error_handler(STR_TOO_LONG);
    if (g_data.c == 0)
    null_handler(i);
    g_data.buffer[i] = g_data.c;
    g_data.c = 0;
    g_data.index = 0;
    i = 0;
    }
    }
    }

    My null_handler() simply displays the string, sends the SIGUSR1 signal to the Client, sets client_pid back to 0 and the buffer gets emptied.


(this is my 1st post, if you have any tips please feel free to send them, there's always room for improvement)

Send signal to other process

If you have created process with os.StartProcess or exec.Command you can use Process.Signal method:

cmd := exec.Command("CmdPath", "-param1", param1)
cmd.Process.Signal(signal)

For external process You should know it's process id (PID) and then call for example:

syscall.Kill(pid,syscall.SIGHUP)

Signal is a standart UNIX "kill" syscall, if you know a pid of the process, you can simply make a syscall with
https://golang.org/pkg/syscall/#Kill

Is there any way to send a value through signal

Data can be sent/received with a signal -
at least on systems supporting sigqueue() and sigaction() with SA_SIGINFO.
Example for the receiving process:

#include <signal.h>
#include <string.h>

void usr1(int sig, siginfo_t *sip, void *ptr)
{
printf("sival_int %d\n", sip->si_value.sival_int);
}

. . .

struct sigaction sa;

memset(&sa, 0, sizeof (sa));
sa.sa_sigaction = usr1;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &sa, NULL);

Example for the sending process:

#include <signal.h>

. . .

union sigval sv;

sv.sival_int = 43210;
sigqueue(target_pid, SIGUSR1, sv);

See union sigval for another choice.

Manual pages: sigaction, sigqueue



Related Topics



Leave a reply



Submit