0

I'm starting to learn signals and how to trigger them. I have this simple code that triggers a signal using SIGUSR1, but when I run the code, the only thing that gets printed is the "Starting..." line. Nothing else gets printed. Am I doing something wrong?

#include <signal.h>
#include <stdio.h>

void my_handler(int signum)
{
    printf("Hello\n");
    printf("%d\n", signum);
    if (signum == SIGUSR1) {
        printf("Receveid\n");
    }
}

int main() {
    printf("Starting...\n");
    signal(SIGUSR1, my_handler);
    return 0;
}
Kinnturo
  • 141
  • 1
  • 2
  • 13
  • How are you sending the signal? – Barmar Sep 10 '21 at 22:48
  • 1
    Your program exits immediately, you'll never have time to send the signal. – Barmar Sep 10 '21 at 22:48
  • **I have this simple code that triggers a signal using SIGUSR1** No you don't. You have code that registers a handler for the signal, you have nothing to trigger the signal. – Barmar Sep 10 '21 at 22:49
  • Sorry, I guess I'm not understanding signals correctly then. If signal(SIGUSR1, my_handler) only registers it, then I'm not sure how to trigger it. – Kinnturo Sep 10 '21 at 22:52
  • Note also the calling `printf()` from within a signal handler invokes undefined behavior. [Footnote 188 of the (draft) C11 standard](https://port70.net/~nsz/c/c11/n1570.html#note188): "... a signal handler cannot, in general, call standard library functions." [POSIX allows for the calling of async-signal-safe functions](https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03) (page down some for the list). `printf()` is not async-signal-safe. Windows has a similar list. – Andrew Henle Sep 11 '21 at 00:27
  • @Kinnturo Normally signals are sent by some other process or the OS. For instance, when you type Control-C, the OS sends SIGINT to the foreground processes. And you can use `kill -USR1 ` to send `SIGUSR1` from the shell. – Barmar Sep 11 '21 at 00:48

1 Answers1

2

signal only registers a signal handler - the function to be called when the process receives a signal. From within your program, you can use raise to send a signal to the calling process.

If you are in a POSIX environment, you should take a look at man 7 signal-safety for a list of functions that are safe to call from within signal handlers (additional information in this answer). printf is not included in this list - nor are a lot standard library functions. Its better to use an operation which is atomic with regards to signals, such as write (or reentrant, such as strlen).

A cursory example of using raise, which returns 0 on success, and nonzero on error.

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

void my_handler(int signum) {
    char msg[] = "SIGUSR1 handler\n";

    if (signum == SIGUSR1)
        write(STDOUT_FILENO, msg, strlen(msg));
}

int main(void) {
    printf("Starting...\n");

    signal(SIGUSR1, my_handler);

    (void) getchar();

    if (raise(SIGUSR1) != 0)
        fprintf(stderr, "Could not raise signal.\n");
}
Oka
  • 23,367
  • 6
  • 42
  • 53