Should I just avoid them?
I have heard many bad things about them
1) if you set a signal handler, you can't really ignore the signal and
continue with normal program execution, because after that undefined
behavior is invoked.
This is not universally true and, in the cases where it is true, is a
red herring.
If you have a signal handler that was invoked as a result of your program
calling raise(), then the signal is handled in a well-defined manner and
you can continue your program exactly the same way as if you had just
called the signal handler directly (unless you call raise() or abort()
in the signal handler; in that case you've invoked undefined behavior
before the normal program execution continues (N869 7.14.1.1#4)).
If a signal handler is invoked asynchronously because of an external event
unrelated to a computational exception, then normal program execution
continues after the handler returns, without invoking undefined behavior
(unless you've invoked undefined behavior in the handler by calling a
library function other than the ones you're specifically permitted to
call) (N869 7.14.1.1#3).
If a signal handler is invoked because of a computational exception, the
program has already invoked undefined behavior (f'rexample, by dividing
by zero or dereferencing a bad pointer) (N869 7.14.1.1#3); the signal
handler is your chance to clean up some things and terminate somewhat less
ungracefully (which, unless you can do it without calling any library
functions, invokes more undefined behavior), or possibly fix the cause
of the error (the way to do that will be completely system-specific),
also invoking undefined behavior.
So the only way undefined behavior can be invoked by a signal handler
ignoring the cause of the signal and returning (allowing the program to
continue) is if the signal was raised because something in the program
already invoked undefined behavior.
2) if you have a signal handler set for say SIG_INT and you continue
to reset the handler after you received the signal, to continue normal
program execution, and the signal is received twice or something you
end up invoking undefined behavior and re-entry of a signal handler
function causing major problems
I'm not quite sure what you're trying to say here, but if you're worried
about the signal handler getting re-invoked because a signal is raised
before the handler finishes, I don't think that's a problem.
Implementations are allowed to do one of two things to deal with this:
-Temporarily block a set of signals that includes the one the handler
is dealing with until the handler finishes. In this case the signal
handler cannot be re-entered as a result of another signal being
received, so there is no problem.
-Reset the handler for that signal to SIG_DFL before invoking the handler.
In this case, the user-defined handler will not be re-entered unless
the handler reinstates itself for that signal. If the handler does
things that shouldn't be done in overlapping calls, then just don't
reinstate the signal until those things are complete. Since a signal
handler is explicitly permitted to reinstate itself (N869 7.14.1.1#5),
the implementation is responsible for making sure that nothing invokes
undefined behavior by stepping on its toes after it's done so.
what are some other things i should be aware of for signals?
The standard specification of signal handling (section 7.14 in N869 (and
I assume C99 as well), or its equivalent in C90), plus the platform's
specification of signal handling for every platform you're supporting.
and what should i do about points 1 and 2?
Understand them well enough to know better than to worry about them.
there really is no alternative to a portable function like signal but
signal itself seems to be a hazardous piece of crap
The portable parts aren't dangerous, and the dangerous parts aren't
portable, so I don't see a problem here.
signal itself really isn't as portable as it looks; all it does is provide
a portable way to hook into system-specific behavior (like computational
exceptions and external interruptions) or know that the implementation
doesn't support it.
It's perfectly valid for signal() to always return SIG_ERR, which will
make it pretty much useless for anything you wanted to do with it.
dave