[Question] signals

M

mark

hi i read that u should always use sigaction() to install a signal handler
and never signal(), is this right and if so why. thanks.
 
K

Keith Thompson

Richard Heathfield said:
mark said:


If not, why not? Because signal() is universally available to hosted
implementations, whereas sigaction() is not.

On the other hand, sigaction() does have some advantages over signal()
(I don't remember the details off the top of my head), so it can make
sense to use sigaction() rather than signal() *if* you don't mind the
loss of portability.

sigaction() is specified by POSIX. If you have any more questions
about it, try comp.unix.programmer.

(Avoiding silly abbreviations like "u" for "you" will make it more
likely that people will be willing to help you.)
 
M

Mark

Keith Thompson said:
(I don't remember the details off the top of my head), so it can make
sense to use sigaction() rather than signal() *if* you don't mind the
loss of portability.

[OT]
Why would using of 'sigaction()' cause loss of portability if it is defined
by POSIX? Every POSIX compliant system would provide it.
[/OT]
 
M

Mark

Gordon Burditt said:
You have a loss of portability if there is or could be in the future
at least one non-POSIX C implementation. There are many more than
that.

And there are a lot more ANSI C implementations then POSIX C ?
 
B

Beej Jorgensen

Richard Heathfield said:
mark said:

No.

"Always" is such a strong word. I'm going to say "in a POSIX
environment, always". :)

Wikipedia, the Linux man pages, POSIX, and W. Richard Stevens all say to
use sigaction() instead of signal(). I do not know of a single case*
where sigaction(), if available, is inferior to signal(), and in almost
all cases it is vastly superior.

* except, perhaps, that signal() is more terse.

For instance, using C99 signal() it's not clear how to portably and
reliably intercept every occurrence of, say, SIGINT, since an
implementation is allowed to reset to the default handler when the
signal is raised. The best you can do is call signal() again and try to
win the race. signal() is potentially hazardous under POSIX for this
reason--and Windows, too, but with POSIX signals are much more widely
used for a variety of very important things.

Use sigaction() if you want to:

call library routines from your handler other than a very very select
few (not all system calls are reentrant, but a great many of them are)

reliably intercept every signal

use signals in a multithreaded environment

control which signals are blocked during handling

control how system calls behave when interrupted

catch any POSIX signals (not that sigaction()'s a requirement for
that, but if you're going non-portable anyway, you might as well go
all the way)

etc.

It's an easy argument that among POSIX systems, sigaction() is *more*
portable than signal(), and between OSX, *BSD, Linux, and UN*X, that's a
lot of systems. (Perhaps another argument could be made that under
Windows signal() should not be used at all? I'm out of my element
there, though.) I don't mean to imply that All The World's A VAX, but I
do mean to imply that for any given platform, there's probably something
better than C99 signal(). :)
If not, why not? Because signal() is universally available to hosted
implementations, whereas sigaction() is not.

But the actual portability of signal() is truly quite limited, with the
spec allowing all kinds of liberties and implementation-defined
behavior. And this is proper, because the spec must tread very
conservatively with signal(), an OS-ish call, to not introduce any
OS-specific dependencies. It does, however, mean, that its not
particularly useful for... anything. To quote the Rationale:

# Signals are difficult to specify in a system-independent way. The C89
# Committee concluded that about the only thing a strictly conforming
# program can do in a signal handler is to assign a value to a volatile
# static variable which can be written uninterruptedly and promptly
# return.
#
# (The header <signal.h> specifies a type sig_atomic_t which can be so
# written.) It is further guaranteed that a signal handler will not
# corrupt the automatic storage of an instantiation of any executing
# function, even if that function is called within the signal handler.
# No such guarantees can be extended to library functions, with the
# explicit exceptions of longjmp (7.13.2.1) and signal (7.14.1.1), since
# the library functions may be arbitrarily interrelated and since some
# of them have profound effect on the environment.
#
# Calls to longjmp are problematic, despite the assurances of 7.13.2.1.
# The signal could have occurred during the execution of some library
# function which was in the process of updating external state and/or
# static variables.
#
# A second signal for the same handler could occur before the first is
# processed, and the Standard makes no guarantees as to what happens to
# the second signal.

I say if you have sigaction(), use it. If someone wants to port it to a
non-POSIX platform, they can replace the functionality with something
applicable to that system. And as with anything non-portable, wrap it
up.

-Beej

Information on porting signals code from Unix to Windows:

http://msdn.microsoft.com/en-us/library/ms811896.aspx#ucmgch09_topic3

complete with a variety of UB-invoking examples of signal().
 
K

Keith Thompson

Mark said:
And there are a lot more ANSI C implementations then POSIX C ?

I don't know about "a lot more", but since POSIX requires conformance
to the C standard, there are certainly *some* more ISO C
implementations that POSIX C implementations.

(If you count freestanding implementations, there are almost certainly
a large number of non-POSIX C implementations, but freestanding
implementations needn't support either signal() or sigaction().)
 
N

Nobody

hi i read that u should always use sigaction() to install a signal handler
and never signal(), is this right and if so why. thanks.

The advantage of sigaction() is that its semantics are more precisely
defined.

On Unix, there are two distinct sets of semantics for signal(), commonly
referred as BSD semantics and SysV semantics.

The SysV version removes the signal handler when a signal is caught. If
you want to catch future occurrences of the signal, you have to restore
the handler manually. If the signal occurs a second time before you can
restore the handler, it won't get caught, which may result in process
termination.

Also, the BSD semantics will cause most interrupted system calls to be
restarted automatically, while SysV semantics cause calls to fail with
EINTR.

If you use sigaction, you can control these features individually. The BSD
semantics can be obtained using the SA_RESTART flag, while using
SA_RESETHAND and SA_NODEFER provides the SysV semantics.

The disadvantage of using sigaction() is that it isn't available on
non-POSIX systems such as Windows or ancient Unices, while signal() exists
in all ANSI C implementations.
 
A

Andrew Smallshaw

It's an easy argument that among POSIX systems, sigaction() is *more*
portable than signal(), and between OSX, *BSD, Linux, and UN*X, that's a
lot of systems. (Perhaps another argument could be made that under
Windows signal() should not be used at all? I'm out of my element
there, though.) I don't mean to imply that All The World's A VAX, but I
do mean to imply that for any given platform, there's probably something
better than C99 signal(). :)

I'd agree with this but actually go further. Portability is not
some binary property of a program - a program is portable or it
isn't - but a continuum. Few real world programs are truly portable
even if they stick to the ANSI C API. This is one case but there
are plenty of others - assumptions about valid filenames would be
another that affect many, many programs.

Portability in the real world is more complex than that. A
"non-portable" may in fact be highly portable across a subset of
systems (not necessarily POSIX ssytems but that is an obvious one)
and even if it isn't, portability is still a measure of how easy
it is to get code working in a new environment. A program that
uses sigaction() may be easy to port to a system that lacks it -
it does not compile and an alternative solution needs to be found
right away. That can be a lot easier than diagnosing a problem
caused by false assumptions about signal() which pass through the
compiler without comment. That is even assuming that the problem
is caught in testing at all.
 
R

Richard Bos

Mark said:
And there are a lot more ANSI C implementations then POSIX C ?

Erm, yes.

The one I use most regularly isn't POSIC, and doesn't provide
sigaction().

Richard
 
K

Keith Thompson

Erm, yes.

The one I use most regularly isn't POSIC, and doesn't provide
sigaction().

Just out curiousity, is it a hosted implementation or a freestanding
implementation? If the later, it needn't necessarily provide signal()
either.
 
R

Richard Bos

Keith Thompson said:
Just out curiousity, is it a hosted implementation or a freestanding
implementation? If the later, it needn't necessarily provide signal()
either.

Hosted. And yes, it does provide signal().

Richard
 
A

Antoninus Twink

mark said:

No.

Excellent, comprehensive answers have been given in this thread by Beej
and "Nobody". Why don't you show a tiny bit of humility and learn from
what they've written, instead of parading your ignorance before the
world and wilfully misleading the OP?
 
N

Nobody

Excellent, comprehensive answers have been given in this thread by Beej
and "Nobody". Why don't you show a tiny bit of humility and learn from
what they've written, instead of parading your ignorance before the
world and wilfully misleading the OP?

I think that you should read Richard's reply literally.

The OP asked if one should *always* use sigaction() and *never* signal().
To which, "no" is a perfectly reasonable response. He didn't say that
you *should* use signal(), just that saying *never* to use it is too
extreme.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top