0

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);
                  ^~~~~~~~~
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Donkey King
  • 87
  • 1
  • 8
  • I wrote in the post that I found that but it didn't solve the problem. It added these errors. error: operator '&&' has no right operand || (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 1) \ ^~ /usr/include/features.h:303:48: error: operator '&&' has no right operand #if defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 2 || defined _XOPEN_SOURCE – Donkey King Feb 16 '19 at 00:38
  • There was once `_POSIX_SOURCE`(and you needed to `#define _POSIX_SOURCE 1`) but it has been `_POSIX_C_SOURCE` for ages (multiple decades). It's easier to remember the values for `_XOPEN_SOURCE` — `700` is the current version, 600 and 500 two previous versions. This gives you everything that `_POSIX_C_SOURCE` does — and some extras. Setting `_XOPEN_SOURCE 700` is loosely equivalent to `_POSIX_C_SOURCE 200809L`; `_XOPEN_SOURCE 600` is loosely equivalent to `_POSIX_C_SOURCE 200112L`; `_XOPEN_SOURCE 500` is loosely equivalent to `_POSIX_C_SOURCE 199506L`. – Jonathan Leffler Feb 16 '19 at 00:38
  • 2
    From `man sigaction`, it talks about `#define _POSIX_C_SOURCE` and _not_ `#define _POSIX_SOURCE`. And, it also talks about what value to use if you want `siginfo_t`. For me, because I use `gcc` and [more importantly] `glibc`, I just use `#define _GNU_SOURCE` and it gets _all_ the latest goodies--YMMV. _Side note:_ Don't do `printf` from within a signal handler as it can cause heap corruptions because `printf` will call `malloc` and the signal may interrupt a `malloc` call in the base level of the process – Craig Estey Feb 16 '19 at 01:02

3 Answers3

1

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.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

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.

krisz
  • 2,686
  • 2
  • 11
  • 18
0

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