2

I'm in the process of transitioning my program's signal handling from signal() to sigaction().

According to the UNIX spec a struct sigaction should have at least 4 members; sa_handler, sa_mask, sa_flags and sa_sigaction.

When I define a structure as follows, everything appears to be normal.

...
#include <signal.h>
...
struct sigaction sa;

But when I attempt to assign a value to sa_handler, the member does not exist. Instead I see this: Image: shows __sigaction_handler : {sigaction.h:1092} instead of sa_handler

I looked through my signal.h and bits/sigaction.h (neither of which has 1092 lines in case you're wondering) and nothing seems amiss.

I also tried using this member name as is, but the compiler complains with

incomparable types when assigning to type 'union ' from type 'void (*)(int)'

This makes me think there is something wrong with how my compiler/IDE is handling the structure's definition, but that is above my head on how to diagnose.

Any help or suggestions would be appreciated.

System info:

  • Debian 8
  • linux 3.16.0-4-amd64
  • gcc 4.9.2 (Debian 4.9.2-10)
  • eclipse-cdt 3.8.1

Update - 8/3/2016

Found these two threads here and here, that suggested defining the preprocessor symbols _POSIX_C_SOURCE and _XOPEN_SOURCE respectively. I defined each (one at a time) and both 'fixed' the incompatable type issue (I successfully assigned a value to sa.__sigaction_handler). But they both also broke my software's ability to use type intptr_t (used for thread function management) and were removed for that reason.

Doing this fixed the issue, however. I can now assign a variable to sa.sa_handler without the compiler throwing an error. The IDE still shows it as a non-existent member (same as image linked above) but that is a minor issue IMHO.

Community
  • 1
  • 1
Nick
  • 56
  • 6

2 Answers2

2

Here's how struct sigaction is defined in my system headers:

/* Structure describing the action to be taken when a signal arrives.  */
struct sigaction
  {
    /* Signal handler.  */
#ifdef __USE_POSIX199309
    union
      {
    /* Used if SA_SIGINFO is not set.  */
    __sighandler_t sa_handler;
    /* Used if SA_SIGINFO is set.  */
    void (*sa_sigaction) (int, siginfo_t *, void *);
      }
    __sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction   __sigaction_handler.sa_sigaction
#else
    __sighandler_t sa_handler;
#endif

    /* Additional set of signals to be blocked.  */
    __sigset_t sa_mask;

    /* Special flags.  */
    int sa_flags;

    /* Restore handler.  */
    void (*sa_restorer) (void);
  };

Notice how, if __USE_POSIX199309 is defined (which it is on my system, and probably is on yours), then instead of having fields named sa_handler and sa_sigaction directly, it has a field named __sigaction_handler, of union type, which in turn has fields named sa_handler and sa_sigaction. So, the fields can be accessed via __sigaction_handler.sa_handler and __sigaction_handler.sa_sigaction, but to satisfy the specification, it also defines macros sa_handler and sa_sigaction, which expand to __sigaction_handler.sa_handler and __sigaction_handler.sa_sigaction, respectively, so you can use these macros to name the fields.

Now, Eclipse doesn't understand that these two macros are supposed to act as field names, so it doesn't offer than as completion proposals when you invoke content-assist.

Nonetheless, you should be able to use them as fields names in your code just fine. That is, just type:

ascdsig.sa_handler = &sig_handle;

and it will work fine.

HighCommander4
  • 50,428
  • 24
  • 122
  • 194
0

In <sigaction.h>, you will find the following #define:

# define sa_sigaction   __sigaction_handler.sa_sigaction

If you wish to fix this specific error, you can add this line to your code to resolve the issue or just access it directly:

sa.__sigaction_handler.sa_sigaction

However, I have a feeling this is indicative of deeper problems with your system headers. Can you check that <signal.h> has #include <bits/sigaction.h>? Can you check that sigaction.h has that #define?

  • I checked before posting, both signal.h and sigaction.h have the lines mentioned above. If I have never directly edited my system headers, is there any reason for a problem to arise with them? – Nick Aug 02 '16 at 19:14
  • 1
    Names starting with double underscore are reserved for the implementation. An application should not rely on them to be portable. – too honest for this site Aug 02 '16 at 19:21
  • @Nick that probably means the `__USE_POSIX199309` feature macro is not defined. Can you check if your `` has this defined? Are you compiling with `-std=c99`? `sigaction` is not a feature of the C99 standard and will undef `__USE_POSIX199309`, among other things . – Daniel Margosian Aug 02 '16 at 19:38
  • 1
    @Daniel `` defines `__USE_POSIX99309 1` if `(_POSIX_C_SOURCE - 0) >= 199309L`. `_POSIX_C_SOURCE` is defined if `((! __STRICT_ANSI__ || (_XOPEN_SOURCE -0) >= 500) && ! _POSIX_SOURCE && ! _POSIX_C_SOURCE)`. As far as I know these criteria should be met. – Nick Aug 03 '16 at 13:05
  • @Olaf, thanks for the advice. But worse case this software is being designed to run on a single system, so portability is not a big issue. – Nick Aug 03 '16 at 13:09