Donkey King
Donkey King

Reputation: 87

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);
                  ^~~~~~~~~

Upvotes: 0

Views: 8324

Answers (3)

Robert Rademacher
Robert Rademacher

Reputation: 66

You need to add <features.h> before <signals.>, as the features.h contains #define _POST_C_SOURCE with latest value for compatibility purpose.

Upvotes: 0

krisz
krisz

Reputation: 2695

You need to define a positive integer for _POSIX_C_SOURCE. For sigaction, it needs to be atleast:

#define _POSIX_C_SOURCE 199309L

Look the the documentation for which POSIX version to use.

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 141473

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.

Upvotes: 2

Related Questions