1*ce099b40Smartin /* $NetBSD: sigset.c,v 1.2 2008/04/28 20:22:59 martin Exp $ */
230a90a73Skleink
330a90a73Skleink /*-
430a90a73Skleink * Copyright (c) 2003 The NetBSD Foundation, Inc.
530a90a73Skleink * All rights reserved.
630a90a73Skleink *
730a90a73Skleink * This code is derived from software contributed to The NetBSD Foundation
830a90a73Skleink * by Klaus Klein.
930a90a73Skleink *
1030a90a73Skleink * Redistribution and use in source and binary forms, with or without
1130a90a73Skleink * modification, are permitted provided that the following conditions
1230a90a73Skleink * are met:
1330a90a73Skleink * 1. Redistributions of source code must retain the above copyright
1430a90a73Skleink * notice, this list of conditions and the following disclaimer.
1530a90a73Skleink * 2. Redistributions in binary form must reproduce the above copyright
1630a90a73Skleink * notice, this list of conditions and the following disclaimer in the
1730a90a73Skleink * documentation and/or other materials provided with the distribution.
1830a90a73Skleink *
1930a90a73Skleink * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2030a90a73Skleink * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2130a90a73Skleink * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2230a90a73Skleink * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2330a90a73Skleink * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2430a90a73Skleink * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2530a90a73Skleink * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2630a90a73Skleink * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2730a90a73Skleink * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2830a90a73Skleink * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2930a90a73Skleink * POSSIBILITY OF SUCH DAMAGE.
3030a90a73Skleink */
3130a90a73Skleink
3230a90a73Skleink #include <sys/cdefs.h>
3330a90a73Skleink #if defined(LIBC_SCCS) && !defined(lint)
34*ce099b40Smartin __RCSID("$NetBSD: sigset.c,v 1.2 2008/04/28 20:22:59 martin Exp $");
3530a90a73Skleink #endif
3630a90a73Skleink
3730a90a73Skleink #include "namespace.h"
3830a90a73Skleink #include <errno.h>
3930a90a73Skleink #include <signal.h>
4030a90a73Skleink #include <stddef.h>
4130a90a73Skleink
4230a90a73Skleink sig_t
sigset(int sig,void (* disp)(int))4330a90a73Skleink sigset(int sig, void (*disp)(int))
4430a90a73Skleink {
4530a90a73Skleink sigset_t set, oset;
4630a90a73Skleink struct sigaction sa, osa;
4730a90a73Skleink
4830a90a73Skleink osa.sa_handler = SIG_ERR;
4930a90a73Skleink
5030a90a73Skleink if (disp == SIG_HOLD) {
5130a90a73Skleink /* Add sig to current signal mask. */
5230a90a73Skleink if (sigemptyset(&set) != 0)
5330a90a73Skleink goto out;
5430a90a73Skleink if (sigaddset(&set, sig) != 0)
5530a90a73Skleink goto out;
5630a90a73Skleink if (sigprocmask(SIG_BLOCK, &set, &oset) != 0)
5730a90a73Skleink goto out;
5830a90a73Skleink
5930a90a73Skleink if (sigismember(&oset, sig)) {
6030a90a73Skleink /* Had been masked before, return SIG_HOLD. */
6130a90a73Skleink osa.sa_handler = SIG_HOLD;
6230a90a73Skleink } else {
6330a90a73Skleink /* Return previous disposition. */
6430a90a73Skleink (void)sigaction(sig, NULL, &osa);
6530a90a73Skleink }
6630a90a73Skleink } else if (disp == SIG_ERR) {
6730a90a73Skleink errno = EINVAL;
6830a90a73Skleink } else {
6930a90a73Skleink /* Set up and install new disposition. */
7030a90a73Skleink sa.sa_handler = disp;
7130a90a73Skleink if (sigemptyset(&sa.sa_mask) != 0)
7230a90a73Skleink goto out;
7330a90a73Skleink sa.sa_flags = 0;
7430a90a73Skleink
7530a90a73Skleink if (sigaction(sig, &sa, &osa) != 0) {
7630a90a73Skleink osa.sa_handler = SIG_ERR;
7730a90a73Skleink goto out;
7830a90a73Skleink }
7930a90a73Skleink
8030a90a73Skleink /* Delete sig from current signal mask. */
8130a90a73Skleink if (sigemptyset(&set) != 0)
8230a90a73Skleink return (SIG_ERR);
8330a90a73Skleink if (sigaddset(&set, sig) != 0)
8430a90a73Skleink return (SIG_ERR);
8530a90a73Skleink if (sigprocmask(SIG_UNBLOCK, &set, &oset) != 0)
8630a90a73Skleink return (SIG_ERR);
8730a90a73Skleink
8830a90a73Skleink /* If had been masked before, return SIG_HOLD. */
8930a90a73Skleink if (sigismember(&oset, sig))
9030a90a73Skleink osa.sa_handler = SIG_HOLD;
9130a90a73Skleink }
9230a90a73Skleink
9330a90a73Skleink out:
9430a90a73Skleink return (osa.sa_handler);
9530a90a73Skleink }
96