Fedora Linux Support Community & Resources Center
  #1  
Old 5th February 2012, 04:23 PM
satyammishra60 Offline
Registered User
 
Join Date: Aug 2009
Posts: 43
linuxfirefox
Using Sigaction handler

Code:
#include<signal.h>
#include<stdio.h>
#include<unistd.h>

void ouch(int sig){
	printf("OUCH! - I got signal %d\n",sig);
}

int main(){
	struct sigaction act;
	act.__sigaction_handler.sa_handler=ouch;
	sigemptyset(&act.sa_mask);
	act.sa_flags=0;

	sigaction(SIGINT,&act,0);
	while(1){
		printf("Hello world!\n");
		sleep(1);
	}
	return 0;
}

In this example , i have trie dot create a handler funciton ouch and assign to this sigaction.sa_handler


Now i guess in my system there is union defined for sigaction.sa_handler and sigaction.sa_sigaction


but i m not sure how to assign the handler value properly.. u can see that I have tried belwo

act.__sigaction_handler.sa_handler=ouch;

but it is of no use. it says ‘union <anonymous>’ has no member named ‘__sigaction_handler’


please advice, thanks in advance
Reply With Quote
  #2  
Old 5th February 2012, 07:09 PM
sanhozay Offline
Registered User
 
Join Date: Jan 2012
Location: Manchester, UK
Posts: 33
linuxfirefox
Re: Using Sigaction handler

Try this:

Code:
act.sa_handler = ouch;
Reply With Quote
  #3  
Old 5th February 2012, 07:47 PM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Using Sigaction handler

It also never hurts to actually read the include files. Sometimes difficult to track some things down, but it is doable.
Reply With Quote
  #4  
Old 6th February 2012, 02:04 AM
stevea's Avatar
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,300
linuxfirefox
Re: Using Sigaction handler

main problem is that you aren't using the prescribed interface.

Just b/c you know that a struct has an element sa_handler or _sigaction_handler.sa_handler DOES NOT mean you can just jam a data of the right type in and everything will work. Maybe there are other side-effects than need to be setup.

THis is functionally equivalent to your attempt ...
Code:
....
int main(){
	signal(SIGINT, ouch);

	while(1){
		printf("Hello world!\n");
		sleep(1);
	}
	return 0;
}
__________________
None are more hopelessly enslaved than those who falsely believe they are free.
Johann Wolfgang von Goethe
Reply With Quote
  #5  
Old 6th February 2012, 04:49 AM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Using Sigaction handler

Yes. But I believe this is depreciated code as the signal function does not have the capabilities that is provided by the sigaction library - signal blocking, atomic support, auxiliary information/closure, alternate stack support...

Much more flexible, and reliable. Yes, signal is implemented by using sigaction, but most of the capabilities are not available.

Always useful to read the manpage if available.
Reply With Quote
  #6  
Old 6th February 2012, 05:54 AM
satyammishra60 Offline
Registered User
 
Join Date: Aug 2009
Posts: 43
windows_xp_2003ie
Re: Using Sigaction handler

Quote:
Originally Posted by stevea View Post
main problem is that you aren't using the prescribed interface.

Just b/c you know that a struct has an element sa_handler or _sigaction_handler.sa_handler DOES NOT mean you can just jam a data of the right type in and everything will work. Maybe there are other side-effects than need to be setup.

THis is functionally equivalent to your attempt ...
Code:
....
int main(){
	signal(SIGINT, ouch);

	while(1){
		printf("Hello world!\n");
		sleep(1);
	}
	return 0;
}





I guess signal funciton is no longer use din newer codes, so we should prefer to to use sigaction.
and moreover.
as sigaction struct has sigaction.sa_handler and sigaction.sa_sigaction. but on few machines it is defined with Union(as in mine case).

So it is better to use sigaction.__sigaction_handler.this __sigaction_handler contains inturn those two variable.
SO my question is whay this approch is not working
Reply With Quote
  #7  
Old 6th February 2012, 05:56 AM
satyammishra60 Offline
Registered User
 
Join Date: Aug 2009
Posts: 43
windows_xp_2003ie
Sigaction handler

This thread is going to be about sigaction handler..
Please join intrested folks
Reply With Quote
  #8  
Old 6th February 2012, 06:17 AM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Using Sigaction handler

The approach is fine.

Just use the proper names for the fields.

From the manpage:
Code:
struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };
That means your line "act.__sigaction_handler.sa_handler=ouch;" is wrong. There is no "__sigaction_handler" structure used in the sigaction structure.

Your line should be "act.sa_handler=ouch;", as pointed out already.
Reply With Quote
  #9  
Old 6th February 2012, 06:24 AM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Sigaction handler

It seems this should be the same thread as " Using Sigaction handler"....
Reply With Quote
  #10  
Old 6th February 2012, 06:26 AM
satyammishra60 Offline
Registered User
 
Join Date: Aug 2009
Posts: 43
windows_xp_2003ie
Re: Using Sigaction handler

Quote:
Originally Posted by jpollard View Post
The approach is fine.

Just use the proper names for the fields.

From the manpage:
Code:
struct sigaction {
               void     (*sa_handler)(int);
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };
That means your line "act.__sigaction_handler.sa_handler=ouch;" is wrong. There is no "__sigaction_handler" structure used in the sigaction structure.

Your line should be "act.sa_handler=ouch;", as pointed out already.



I agree this for some architecture only.
If we try to see some below in man pages.
It says that onsome machiene it may be defined as a union.

and the sa_handler and sa_sigaction are part of this union.

I agree that that act.sa_handler will work perfectly fine, and i have tried this as well
but i m trying to do this in union way. (I am unsing eclipse, on that when I try to put "act" and press '.' it auotmatically shows me sigaction.__sigaction_handler and the two member of this union.)
So by eclipse i m sure my machine is using union implementation
Reply With Quote
  #11  
Old 6th February 2012, 06:59 AM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Using Sigaction handler

No, your machine is not using union implementation, and even if it were, it wouldn't be that way, in both cases, the fields are sa_handler and sa_sigaction. The manpage specifically says "do not assign to both".

Use one or the other, and the name to use is specified by the sa_flags field. If you specify SA_SIGINFO in the sa_flags field, then assign to sa_sigaction, and NOT to sa_handler. This is because the two fields are defined differently. The end result (a function to call) is the same, which is why both fields can be defined via a union (unnamed I believe), but are not required to be.

eclipse appears to be reporting improperly.

I may have been a bit short earlier...

Now if you define the symbol "__USE_POSIX199309" (or the compiler does due to some options selected) then it will be using the __sigaction_handler union name. But if you look at the include file (/usr/include/signal.h includes /usr/include/bits/sigaction) you will find the following:
Code:
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);
  };
Note that when the "__USE_POSIX199309" is defined, the names "sa_handler" AND "sa_sigaction" are also both defined (the "#define ..." lines). This makes using __sigaction_handler.sa_handler OR __sigaction_handler.sa_sigaction superfluous as these are the same names when NOT using the "__USE_POSIX199309".

That means that it works either way to say "act.sa_handler" or "act.sa_sigaction", but DON'T use both. All the extra union does is to eliminate storage for an extra pointer (the flag SA_SIGINFO determines which will be used). Using the sa_sigaction or sa_handler is therefore made portable. The code should work for either implementation of the sigaction structure.

Saving this space is nearly pointless (pun deliberate) as the sigaction structure is only used to initialize some kernel process parameters for use when invoking the signal handler. After that, the structure could be discarded, as it can be when the declaration is on the stack (as your example has, though it is in the main function).

Last edited by jpollard; 6th February 2012 at 07:30 AM. Reason: correcting/expanding explaination.
Reply With Quote
  #12  
Old 6th February 2012, 08:25 AM
leigh123linux's Avatar
leigh123linux Offline
Retired Administrator
 
Join Date: Oct 2006
Posts: 21,509
linuxfirefox
Re: Using Sigaction handler

Quote:
Originally Posted by satyammishra60 View Post
Code:
#include<signal.h>
#include<stdio.h>
#include<unistd.h>

void ouch(int sig){
    printf("OUCH! - I got signal %d\n",sig);
}

int main(){
    struct sigaction act;
    act.__sigaction_handler.sa_handler=ouch;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;

    sigaction(SIGINT,&act,0);
    while(1){
        printf("Hello world!\n");
        sleep(1);
    }
    return 0;
}
In this example , i have trie dot create a handler funciton ouch and assign to this sigaction.sa_handler


Now i guess in my system there is union defined for sigaction.sa_handler and sigaction.sa_sigaction


but i m not sure how to assign the handler value properly.. u can see that I have tried belwo

act.__sigaction_handler.sa_handler=ouch;

but it is of no use. it says ‘union <anonymous>’ has no member named ‘__sigaction_handler’


please advice, thanks in advance

Threads merged, don't double post again ( this is your last warning).
Reply With Quote
  #13  
Old 6th February 2012, 11:08 AM
sanhozay Offline
Registered User
 
Join Date: Jan 2012
Location: Manchester, UK
Posts: 33
linuxfirefox
Re: Using Sigaction handler

To add to jpollard's explanations ...

Eclipse appears to be offering completions that are really for internal use within the library. Presumably it's just looking at the headers and collecting the symbols. Don't place too much trust in what Eclipse is offering. As a general rule, avoid using variables beginning with an underscore in your program that you didn't define.

(There are exceptions to this rule, but the only ones that immediately spring to mind are from the preprocessor - things like "__LINE__" and "__FILE__").
Reply With Quote
  #14  
Old 7th February 2012, 04:29 PM
stevea's Avatar
stevea Offline
Registered User
 
Join Date: Apr 2006
Location: Ohio, USA
Posts: 8,300
linuxfirefox
Re: Using Sigaction handler

Your approach is, as I said wrong-headed.

sigaction is part of the POSIX real-time extensions where it's use is well defined. There are only two valid ways to use an API - ideally for portability - follow the documentation, or with far lesser portability - pull the source code and read and understand the entire interface. I can't address the eclipse issue, it may well have problems.

You should never hunt through the include files and ASSUME you can jam data into undocumente structures you see and expect to get good results. So this attitude:
Quote:
It also never hurts to actually read the include files.
is harmful. Yes it hurts portability to read ONE example implementation and then assume it applies to others. So read - but only with a clear understanding the result isn't general or portable except to the extent the include file is general and portable.

Again you have two options to understand any API - read the documentation or read the source code. You can readily pull the glibc sources if you wish to see the local-implementation details. The include files are just artefacts of the design - you cannot base a design on their content.

Here: http://rtems.org/onlinedocs/doc-curr..._users_33.html
Quote:
The structure sigaction has the following members:

void(*)(int) sa_handler

Pointer to a signal-catching function or one of the macros SIG_IGN or SIG_DFL.
sigset_t sa_mask

Additional set of signals to be blocked during execution of signal-catching function.
int sa_flags

Special flags to affect behavior of signal.
void(*)(int, siginfo_t*, void*) sa_sigaction

Alternative pointer to a signal-catching function.

sa_handler and sa_sigaction should never be used at the same time as their storage may overlap.
....

So when you do things like this ....
Code:
	act.__sigaction_handler.sa_handler=ouch;
you've gone away from the documented API. You are just jamming data into things that appear to be similar to the documented API and the results are non-portable and unpredictable.


=====

I think you and JP need to re-real the signal(2) man page again. The function is not deprecate and is part of the POSIX.1-2001 standard. The man page SUGGESTS not using it except for a few special cases, and the justification by reciting part of the history fo this function and limits to it's portability.

The Original POSIX std defined 'signal()' but allowed several different semantics - the functionality operated differently on different systems. This made most signal handling incompatible - say between BSD Unices and Linux. After a series of incremental improvements the sigaction functionality was defined and is *reasonably* portable - but still has loose ends that need special ifdef's and attention.

The bottom line - if the plan is to get the job done and to be portable just across modern Linux distros there is nothing wrong with the current implementation of signal. signal() has been implemented as calls to sigaction() in glibc for years. If you need to be portable to most BSDs and *some* of the embedded POSIXy-kernels, but not ancient versions of any OS and only in systems with this POSIX RT extension (some systems don't support sigaction) - then sigaction is a better choice. At least with sigaction - you get the same functionality.

There is no ideal solution for portability of signals.

Hunting through the include files and making guesstimates about the semantics of the undocumented data structures you find there is bad. It's truly bad if eclipse lead you down this dead-end. I would have assumed it had templates for POSIX data structures. Maybe there is an add-on package for that.

====

Minor nits -
check your return codes, and compile with -Wall to check for detailed issues I thin kyo uar emissing some casts, depending on defaults.
__________________
None are more hopelessly enslaved than those who falsely believe they are free.
Johann Wolfgang von Goethe

Last edited by stevea; 7th February 2012 at 04:33 PM.
Reply With Quote
  #15  
Old 7th February 2012, 04:45 PM
jpollard Online
Registered User
 
Join Date: Aug 2009
Location: Waldorf, Maryland
Posts: 6,097
linuxfedorafirefox
Re: Using Sigaction handler

signal is not exactly compatible with threading... as implied by "Realtime Signals Extension option not supported"... And the use of signal gets lost when threading as a specific signal can be dropped (race conditions), which is why I didn't suggest using signal.

And "read the source code" requires reading the include files.

To follow any implementation requires reading the include files. Yes, that is ONE implementation. In fact, I suspect that there is a bug in the include files. If __USE_POSIX199309 is NOT defined then neither is "sa_sigaction"... and the documentation shows it as defined whether or not it is in a union structure... Bug? or a bug in the documentation...

And the only way to understand the structures is to actually use them... but be willing to read the include files when something goes a bit haywire...

And the documentation on signal indicates that the only portable use is to set SIG_DFL or SIG_IGN... which eliminates its use for setting signal handlers in a portable way.

Last edited by jpollard; 7th February 2012 at 04:54 PM.
Reply With Quote
Reply

Tags
handler, sigaction

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
thunderbird as mailto handler mkudro Using Fedora 10 14th June 2011 01:21 PM
Assigning HID Handler? zenox Hardware & Laptops 0 31st August 2006 08:22 PM
Perl Session handler jlr Using Fedora 1 16th February 2004 07:04 PM


Current GMT-time: 04:50 (Monday, 20-05-2013)

TopSubscribe to XML RSS for all Threads in all ForumsFedoraForumDotOrg Archive
logo

All trademarks, and forum posts in this site are property of their respective owner(s).
FedoraForum.org is privately owned and is not directly sponsored by the Fedora Project or Red Hat, Inc.

Privacy Policy | Term of Use | Posting Guidelines | Archive | Contact Us | Founding Members

Powered by vBulletin® Copyright ©2000 - 2012, vBulletin Solutions, Inc.

FedoraForum is Powered by RedHat