Solved [C] Help With Figuring Out Signal Handling in FreeBSD

I'm trying to learn signal handling in FreeBSD, and so I made this little apparently-not-functional program:

C:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <err.h>

void handler(int sig) {
    printf("Boo!\n");
}

int main(void) {
    printf("Send any signal to continue, or USR1+10 to get a surprise...\n");

    if (signal(SIGUSR1+10, handler) == SIG_ERR)
        err(1, "Failed to install signal handler!");

    while (1) {
        printf("Waiting...\n");
        sleep(5);
    }

    return 0;
}

I swear I have no idea what's wrong with it, because pkill USR1+10 sighandler simply doesn't work at all. Instead of sending the signal to the program and letting it handle it, it just kills it entirely instead. No matter what I try, it just dies instead of printing the correct message.
Weirdly enough, I don't even see that error message I put. That means it was able to install the handler then, right? No? Could it be that it got fooled by the OS too?

I should also mention that I'm not very experienced with C either, so I apologize if I made any stupid mistakes. I'm just trying to figure this out to fix a bigger program that relies on the same thing. It'd work just fine on Linux.
 
huh? in this other program i mentioned you assign arbitrary signal numbers for it to update the text, on linux that'd be SIGRTMIN+n··· thought it'd be at least similar on FreeBSD and that's why i wrote it that way···

changing the trigger to SIGUSR1 still does nothing tho', so i guess it really did not install it properly
really weird that it didn't warn me or anything
 
ERRORS
The signal() function will fail and no action will take place if one of
the following occur:

[EINVAL] The sig argument is not a valid signal number.

still kill(2) allows you to send even if kill(1) and kllall won't
Code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <err.h>

void handler(int sig) {
    printf("Boo!\n");
}

int main(void) {
    printf("Send any signal to continue, or USR1+10 to get a surprise...\n");

    if (signal(SIGUSR1+10, handler) == SIG_ERR)
        err(1, "Failed to install signal handler!");

    while (1) {
        printf("Waiting...\n");
        sleep(5);

        printf("%d\n",kill(getpid(),SIGUSR1+10));
    }

    return 0;
}
this works
 
Just check for SIGUSR1 -- then:

Code:
 shell$ kill -SIGUSR1 <pid>

I just tested it using your code and... it works ! :)
 
per the manpage, signal() returns SIG_ERR on error, you need to check explicitly for that.
isn't it what it does in if (signal(SIGUSR1+10, handler) == SIG_ERR) already? or is that not explicit enough?

The signal() function will fail and no action will take place if one of
the following occur:

[EINVAL] The sig argument is not a valid signal number.

still kill(2) allows you to send even if kill(1) and kllall won't
[...]
this works
i see··· what are the valid signal numbers then? or do we only have two (SIGUSR1 and -2)?

Just check for SIGUSR1 -- then:

Code:
 shell$ kill -SIGUSR1 <pid>

I just tested it using your code and... it works ! :)
oh wow, i just tested on mine and it did work as well, even with pkill 😅

Calling printf in a signal handler is also illegal (because it can call malloc(3)). Try a plain write(2).
damn now i've never heard of that detail, will try
 
in this other program i mentioned you assign arbitrary signal numbers for it to update the text, on linux that'd be SIGRTMIN+n··· thought it'd be at least similar on FreeBSD and that's why i wrote it that way···
On freebsd the value for SIGRTMIN is 65, while SIGUSR1 is 30.

if (signal(SIGUSR1+10, handler) == SIG_ERR)
Given that this doesn't fail, it should be considered a bug since SIGUSR1+10 is outside the valid signal number range. You should file a bug report for this.
 
On freebsd the value for SIGRTMIN is 65, while SIGUSR1 is 30.
well yeah, i did try using SIGRTMIN at first but it doesn't look like my system supports it somehow

Given that this doesn't fail, it should be considered a bug since SIGUSR1+10 is outside the valid signal number range. You should file a bug report for this.
i see··· so is the valid signal number range 1-31 (SIGHUP-SIGUSR2)?
 
1-33 and (presumably) SIGRTMIN..SIGRTMAX (65..126) -- see /usr/include/sys/signal.h. The latter are for POSIX realtime signal support (I am not familiar with this so can't tell you how to use them right). In any case expressions such as <signum>+n would only make sense for the latter. Signums 1..33 have specific meanings so you wouldn't e.g. do SIGKILL+n!
 
ah right, that makes sense

so that's why my program does work now that i set it to update on SIGUSR1 only, this isn't as straightforward as Linux···
thanks for the help tho'
 
this isn't as straightforward as Linux···
As you experienced, you can pick up bad habits on linux :-) Always read relevant man pages on FreeBSD. Assuming it behaves identically to Linux is not a good idea. If you want behavior identical to linux, why not stay on linux.
 
What makes you think SIGUSR1 + 10 is valid in Linux?
oh no, i meant SIGRTMIN+10 on linux, i wasn't even aware it had SIGUSR too

As you experienced, you can pick up bad habits on linux :-) Always read relevant man pages on FreeBSD. Assuming it behaves identically to Linux is not a good idea. If you want behavior identical to linux, why not stay on linux.
yeah that's for sure, i did the wrong thing by assuming they'd be similar just because they're related to UNIX

so now i still wonder why i can't use SIGRTMIN here, even though i obviously have it defined in signal.h
i don't really think it's reserved for the Linux compatibility layer (why am i even bothering 😓)
 
so now i still wonder why i can't use SIGRTMIN here, even though i obviously have it defined in signal.h
This has to do with real time stuff -- can't help you there. Read relevant man pages as can be found with apropos REALTIME. But I'd say ignore this until you absolutely need real time support.
 
the fact that it works there just fine?


pkill -SIGRTMIN+10 <statusbar>, same thing i tried here at first
i guess it does on Linux ¯\_(ツ)_/¯


yeah that's what bakul mentioned

Do you have a console log copy and paste of this working?

It is hard to believe that pkill does arithmetic on the command line.
 
UPDATE: i just booted onto linux on my laptop and discovered that SIGRTMIN{,+{1..15}} are actually signals by themselves, and not some compounds
it even is the opposite for SIGRTMAX, where it goes from -14 to
and then SIGUSR{1,2} there are signals 10 and 12 for some reason
 
Back
Top