Search code examples
cposixsigaction

How do I use sigaction()? struct sigaction is not defined


I am doing simple sigaction example to practice C, but when I try to compile my code, it claims that struct sigaction doesn't exist [1].

When I checked out some old code I had produced I saw that I had added some POSIX string at the very top of the file [2]. But when I read the manual for sigaction (man 2 sigaction) there is nothing about _POSIX_SOURCE in it, the closest being _POSIX_C_SOURCE which doesn't work. How and when do I know which POSIX is the be used? When I try simple code that others have suggested, which is without the _POSIX_SOURCE it doesn't work.

[1]

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

void sa_handler(int signum)
{
    printf("The signal has been replaced with this useless 
string!\n");
    exit(0);
}

int main(void)
{
    struct sigaction sa = {.sa_handler = sa_handler};
    int sigret = sigaction(SIGINT, &sa, NULL);
    while(1);

    return 0;
}

[2]

#define _POSIX_SOURCE
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void sa_handler(int signum)
{
    printf("The signal has been replaced with this useless 
string!\n");
    exit(0);
}

int main(void)
{
    struct sigaction sa = {.sa_handler = sa_handler};
    int sigret = sigaction(SIGINT, &sa, NULL);
    while(1);

    return 0;
}

When I compile the first example the result are these error messages.

sigaction.c: In function ‘main’:
sigaction.c:13:12: error: variable ‘sa’ has initializer but 
incomplete type
     struct sigaction sa = {.sa_handler = sa_handler};
            ^~~~~~~~~
sigaction.c:13:29: error: ‘struct sigaction’ has no member named 
‘sa_handler’
     struct sigaction sa = {.sa_handler = sa_handler};
                             ^~~~~~~~~~
sigaction.c:13:42: warning: excess elements in struct initializer
     struct sigaction sa = {.sa_handler = sa_handler};
                                          ^~~~~~~~~~
sigaction.c:13:42: note: (near initialization for ‘sa’)
sigaction.c:13:22: error: storage size of ‘sa’ isn’t known
     struct sigaction sa = {.sa_handler = sa_handler};
                      ^~
sigaction.c:14:18: warning: implicit declaration of function 
‘sigaction’ [-Wimplicit-function-declaration]
     int sigret = sigaction(SIGINT, &sa, NULL);
                  ^~~~~~~~~

Solution

  • when I read the manual for sigaction (man 2 sigaction) there is nothing about _POSIX_SOURCE in it

    From man sigaction:L

    Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

    From future_test_macros(7):

    _POSIX_SOURCE
    Defining this obsolete macro with any value is equivalent to
    defining _POSIX_C_SOURCE with the value 1.

    Since this macro is obsolete, its usage is generally not doc‐
    umented when discussing feature test macro requirements in
    the man pages.

    So _POSIX_SOURCE is equivalent to _POSIX_C_SOURCE 1 and is obsolete.

    How and when do I know which POSIX is the be used?

    From man future_test_macros:

    Specification of feature test macro requirements in manual pages
    When a function requires that a feature test macro is defined, the
    manual page SYNOPSIS typically includes a note [....]

    So you should check SYNOPSIS section in the manual page of the function/feature you are interested in. For example for man sigaction:

    sigaction(): _POSIX_C_SOURCE
    siginfo_t: _POSIX_C_SOURCE >= 199309L

    So you need to define _POSIX_C_SOURCE for sigaction() and _POSIX_C_SOURCE greater or equal to the value of 199309 for siginfo_t.