replace signal() call with sigaction() for better portability

signal() is known to have portability problems. Some systems such as
old Unix systems and System V employ a behavior in which the signal
disposition is reset to SIG_DFL (default) upon invokation of a signal
handler by the delivery of a signal.

See issue #51 in which Solaris users experience signal-based issues.

Solaris is a system which employs the SIG_DFL reset behavior even in
version 11.1.

See http://docs.oracle.com/cd/E26502_01/html/E29034/signal-3c.html

> If signal() is used, disp is the address of a signal handler, and sig is not SIGILL,
> SIGTRAP, or SIGPWR, the system first sets the signal's disposition to SIG_DFL before
> executing the signal handler.

My theory is the signal is handled once on Solaris, after which the disposition is
reset to its default disposition. On Solaris the default signal disposition for SIGUSR1
is to exit the application.

See http://docs.oracle.com/cd/E26502_01/html/E29033/signal.h-3head.html

If so, the solution to this (and likely any other portability issues that may arise)
is to use sigaction() which has explicitly defined behavior as per the POSIX standards.

As you can see, it's a pretty drop-in solution. In fact, on some systems such as Linux,
glibc defines signal() as a wrapper around signal() to use BSD semantics (i.e. not the
behavior detailed above), which is likely why few others have experienced these problems.

See http://man7.org/linux/man-pages/man2/signal.2.html