Changeset View
Standalone View
lib/libc/sys/sigaction.c
Show All 28 Lines | |||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <machine/atomic.h> | |||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdlib.h> | |||||
#include "libc_private.h" | #include "libc_private.h" | ||||
__weak_reference(__sys_sigaction, __sigaction); | __weak_reference(__sys_sigaction, __sigaction); | ||||
__weak_reference(sigaction, __libc_sigaction); | __weak_reference(sigaction, __libc_sigaction); | ||||
/* | |||||
* Used to track signals that are given a non-ignored handler so that other | |||||
* parts of libc, notably posix_spawn, can easily and safely reset these to | |||||
* default handler before unblocking signals again and proceeding without | |||||
* the possibility of a signal handler altering process state in the middle of | |||||
* the vfork. | |||||
* | |||||
* This set of used signals should not be treated as an ultimate source of | |||||
* truth, but rather as a 'best guess'. | |||||
*/ | |||||
static uint32_t _used_sigs[_SIG_WORDS]; | |||||
kib: There is no need in the underscore prefix. The symbol is static.
Why you cannot use sigset_t ? | |||||
kevansAuthorUnsubmitted Done Inline ActionsI hadn't spent any time considering any concurrency issues that may happen here, so I opted for the bare minimum uint32[_SIG_WORDS] that I can operate on atomically -- a luxury not provided by sigset operations last I had looked. kevans: I hadn't spent any time considering any concurrency issues that may happen here, so I opted for… | |||||
void | |||||
__libc_used_signal_reset(void) | |||||
{ | |||||
int sig; | |||||
struct sigaction sa; | |||||
sa.sa_handler = SIG_DFL; | |||||
jillesUnsubmitted Not Done Inline Actionssa_flags and sa_mask should be initialized as well. jilles: `sa_flags` and `sa_mask` should be initialized as well. | |||||
kevansAuthorUnsubmitted Done Inline ActionsI thought I had a memset here -- must have been lost in transit across machines. =( Will address this in another revision. kevans: I thought I had a `memset` here -- must have been lost in transit across machines. =( Will… | |||||
for (sig = 1; sig < _SIG_MAXSIG; ++sig) { | |||||
if ((_used_sigs[_SIG_WORD(sig)] & _SIG_BIT(sig)) != 0) | |||||
__libc_sigaction(sig, &sa, NULL); | |||||
jillesUnsubmitted Not Done Inline ActionsCalling libthr's version prevents resetting SIGCANCEL/SIGTHR and does additional sigprocmask and rwlock calls. jilles: Calling libthr's version prevents resetting SIGCANCEL/SIGTHR and does additional sigprocmask… | |||||
} | |||||
} | |||||
#pragma weak sigaction | #pragma weak sigaction | ||||
int | int | ||||
sigaction(int sig, const struct sigaction *act, struct sigaction *oact) | sigaction(int sig, const struct sigaction *act, struct sigaction *oact) | ||||
{ | { | ||||
if (act != NULL && _SIG_VALID(sig) && | |||||
((act->sa_flags & SA_SIGINFO) != 0 || act->sa_handler != SIG_IGN)) | |||||
kibUnsubmitted Not Done Inline ActionsSIG_DFL can be ignored as well. You may also clear bits when SIG_IGN and SIG_DFL are specified. kib: SIG_DFL can be ignored as well. You may also clear bits when SIG_IGN and SIG_DFL are specified. | |||||
jillesUnsubmitted Not Done Inline ActionsClearing bits may be incorrect when two threads issue sigaction for the same signal at the same time, one setting a handler and one setting the default action. libthr does not guarantee that the previously installed handler cannot be called after a sigaction with SIG_DFL returns, but does appear to lock the change properly otherwise. jilles: Clearing bits may be incorrect when two threads issue sigaction for the same signal at the same… | |||||
kevansAuthorUnsubmitted Done Inline ActionsThe initial concern I had is invalid when I address your concerns about using libthr versions of sig* operations, but I did not want to clear these initially because I didn't want to clobber _used_sigs in the vfork parent when the child resets everything. kevans: The initial concern I had is invalid when I address your concerns about using libthr versions… | |||||
atomic_set_32(&_used_sigs[_SIG_WORD(sig)], _SIG_BIT(sig)); | |||||
jillesUnsubmitted Not Done Inline ActionsSince libthr's setting of SIGCANCEL/SIGTHR does not pass through here, it needs to be accounted for differently. jilles: Since libthr's setting of SIGCANCEL/SIGTHR does not pass through here, it needs to be accounted… | |||||
kevansAuthorUnsubmitted Done Inline ActionsIs there any reason I shouldn't have __libc_used_signal_reset just reset these ones unconditionally? kevans: Is there any reason I shouldn't have `__libc_used_signal_reset` just reset these ones… | |||||
return (((int (*)(int, const struct sigaction *, struct sigaction *)) | return (((int (*)(int, const struct sigaction *, struct sigaction *)) | ||||
__libc_interposing[INTERPOS_sigaction])(sig, act, oact)); | __libc_interposing[INTERPOS_sigaction])(sig, act, oact)); | ||||
} | } |
There is no need in the underscore prefix. The symbol is static.
Why you cannot use sigset_t ?
SIGCANCEL should be added unconditionally to the set.