Thread: sigaction structure initialisation

  1. #1
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373

    sigaction structure initialisation

    To initialise structures, instead of using memset() I've got used to doing e.g.

    Code:
    struct sockaddr_in serv = {0};
    I'm learning about the sigaction() function and

    Code:
    struct sigaction sa = {0};
    produces following warnings?

    warning: missing braces around initializer
    warning: (near initialization for 'sa.__sigaction_handler')

    I'm using gcc compiler in Puppy Linux.

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    that structure must have some nested elements and the compiler is picky that the initializer conform to the nesting. if you were explicitly initializing all members, you would have a nesting of braces to match the structure format. so you have two choices: ignore the warning, the code will still work. or fix your initializer to match the structure nesting.

  3. #3
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    The standard sigaction structure doesn't have any nested structures. I'm guessing that sa_sigaction and sa_handler are stored in a union named "sa" in the structure on this system (since the two handler callbacks are mutually exclusive anyway), and those names are aliases (macros) for sa.__sigaction_handler and (I'm guessing) sa.__sigaction_sigaction.

    I'd leave the initializer the way it is and ignore the warning, or leave out the initializer and use memset if the warning bothers you.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You could try something like this
    Code:
        struct sigaction sa = { { 0 } };
    But beware of this:
    Code:
    union foo {
        int a;
        char b[100];
    } var = { 0 };
    A union initialiser only initialises the first named element of a union.
    If you then try to use another member, it will NOT be initialised as you would expect.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    For gcc, this warning only shows up with -Wextra (-Wall doesn't show it).

    In the following nested structure (x) I could only get the warning to go away by doing this:
    Code:
        struct X x = { 0, 0, 0, {0, 0} };
    Interestingly, there's a difference between doing this and using memset, in that the "holes" in the structure are not zeroed with the initializer method, as demonstrated by this program:
    Code:
    #include <stdio.h>
    
    struct Y {
        char d;
        int e;
    };
    
    struct X {
        char   a;
        int    b;
        double c;
        struct Y y;
    };
    
    int main(void) {
        struct X x = { 0, 0, 0, {0, 0} };
        char *p, *pend = (char*)&x + sizeof(x);
    
        for (p = (char*)&x; p < pend; p++)
            if (*p != 0)
                printf("%d\n", p - (char*)&x);
    
        return 0;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by oogabooga View Post
    Interestingly, there's a difference between doing this and using memset, in that the "holes" in the structure are not zeroed with the initializer method, as demonstrated by this program:
    Certainly, but the (padding) holes shouldn't be accessed in most cases anyway.

  7. #7
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    I'm still struggling with this program, it's a server program that uses signal() to trap SIGCHLD.

    I thought it would be easy to convert to sigaction but the output seems to show spurious child processes being created,most often when another child process has just terminated.

    The original program works perfectly.

    I'm still using the same handling function which is

    Code:
    void sigchld_handler(int signo)
    {
        while(waitpid(-1,NULL,WNOHANG)>0);
    }

    the call to signal was

    Code:
    signal(SIGCHLD,sigchld_handler);

    so I created the sigaction struct and replaced signal with this sigaction call

    Code:
    struct sigaction san;
    memset(&san,0,sizeof(san));
    san.sa_handler = &sigchld_handler;
    
    
    sigaction(SIGCHLD,&san,NULL);

    That's the only changes.

  8. #8
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    [QUOTE=Salem;1123361]You could try something like this
    Code:
        struct sigaction sa = { { 0 } };
    yup, that works.

    excellent!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pass variables to sigaction
    By memcpy in forum C Programming
    Replies: 0
    Last Post: 12-16-2011, 05:29 PM
  2. struct sigaction
    By ssharish2005 in forum C Programming
    Replies: 1
    Last Post: 07-17-2011, 08:41 AM
  3. signal vs sigaction
    By bhrugu in forum C Programming
    Replies: 1
    Last Post: 01-18-2010, 12:50 AM
  4. Reaping zombies with sigaction()
    By heras in forum Linux Programming
    Replies: 4
    Last Post: 03-12-2008, 01:05 PM
  5. sigaction() and ANSI C
    By awoodland in forum Linux Programming
    Replies: 4
    Last Post: 04-25-2004, 01:48 AM