Signals: Correct implementation of sigset(). It is not just signal() with a different name; it has some additional signal mask handling functionality
This commit is contained in:
parent
fec1931def
commit
6653c5cbf3
@ -439,7 +439,7 @@ Refreshing Configurations
|
||||
be? Enter ? in response to the 'make oldconfig' prompt and it will show
|
||||
you the help text that goes with the option.
|
||||
|
||||
If you don't want to make any decisions are are willing to just accep the
|
||||
If you don't want to make any decisions are are willing to just accept the
|
||||
recommended default value for each new configuration item, an even easier
|
||||
way is:
|
||||
|
||||
|
@ -181,17 +181,10 @@
|
||||
* functions that deal with signal disposition.
|
||||
*/
|
||||
|
||||
#define SIG_ERR ((CODE void*)-1)
|
||||
#define SIG_DFL ((CODE void*)0)
|
||||
#define SIG_IGN ((CODE void*)0)
|
||||
|
||||
#if 0 /* Not yet supported */
|
||||
# define SIG_HOLD ((CODE void*)0)
|
||||
#endif
|
||||
|
||||
/* System V name compatibility */
|
||||
|
||||
#define sigset(s,f) signal(s,f)
|
||||
#define SIG_ERR ((CODE void *)-1) /* And error occurred */
|
||||
#define SIG_DFL ((CODE void *)0) /* Default is SIG_IGN for all signals */
|
||||
#define SIG_IGN ((CODE void *)0) /* Ignore the signal */
|
||||
#define SIG_HOLD ((CODE void *)1) /* Used only with sigset() */
|
||||
|
||||
/********************************************************************************
|
||||
* Public Type Definitions
|
||||
@ -289,29 +282,30 @@ extern "C"
|
||||
#endif
|
||||
|
||||
int kill(pid_t, int);
|
||||
int sigemptyset(FAR sigset_t *set);
|
||||
int sigfillset(FAR sigset_t *set);
|
||||
int sigaddset(FAR sigset_t *set, int signo);
|
||||
int sigdelset(FAR sigset_t *set, int signo);
|
||||
int sigismember(FAR const sigset_t *set, int signo);
|
||||
int sigaction(int sig, FAR const struct sigaction *act,
|
||||
FAR struct sigaction *oact);
|
||||
int sigaddset(FAR sigset_t *set, int signo);
|
||||
int sigdelset(FAR sigset_t *set, int signo);
|
||||
int sigemptyset(FAR sigset_t *set);
|
||||
int sigfillset(FAR sigset_t *set);
|
||||
int sighold(int signo);
|
||||
int sigismember(FAR const sigset_t *set, int signo);
|
||||
int sigignore(int signo);
|
||||
CODE void (*signal(int sig, CODE void (*func)(int signo)))(int signo);
|
||||
int sigprocmask(int how, FAR const sigset_t *set, FAR sigset_t *oset);
|
||||
int sigpause(int signo);
|
||||
int sigrelse(int signo);
|
||||
int sigpending(FAR sigset_t *set);
|
||||
int sighold(int signo);
|
||||
int sigsuspend(FAR const sigset_t *sigmask);
|
||||
int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *value);
|
||||
int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *value,
|
||||
FAR const struct timespec *timeout);
|
||||
#ifdef CONFIG_CAN_PASS_STRUCTS
|
||||
int sigqueue(int pid, int signo, union sigval value);
|
||||
#else
|
||||
int sigqueue(int pid, int signo, FAR void *sival_ptr);
|
||||
#endif
|
||||
int sigrelse(int signo);
|
||||
CODE void (*sigset(int sig, CODE void (*func)(int signo)))(int signo);
|
||||
int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *value,
|
||||
FAR const struct timespec *timeout);
|
||||
int sigsuspend(FAR const sigset_t *sigmask);
|
||||
int sigwaitinfo(FAR const sigset_t *set, FAR struct siginfo *value);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -1,7 +1,7 @@
|
||||
############################################################################
|
||||
# libc/signal/Make.defs
|
||||
#
|
||||
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
|
||||
# Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -39,7 +39,7 @@ ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||
|
||||
CSRCS += sig_emptyset.c sig_fillset.c sig_addset.c sig_delset.c
|
||||
CSRCS += sig_ismember.c sig_hold.c sig_relse.c sig_ignore.c sig_pause.c
|
||||
CSRCS += signal.c
|
||||
CSRCS += sig_set.c signal.c
|
||||
|
||||
# Add the signal directory to the build
|
||||
|
||||
|
@ -39,26 +39,6 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Publics Functions
|
||||
****************************************************************************/
|
||||
|
@ -39,26 +39,6 @@
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -47,8 +47,8 @@
|
||||
* Name: sigrelse
|
||||
*
|
||||
* Description:
|
||||
* The sigrelse() function will remove 'signo' to the calling process' signal
|
||||
* mask.
|
||||
* The sigrelse() function will remove 'signo' from the calling process'
|
||||
* signal mask.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
156
libc/signal/sig_set.c
Normal file
156
libc/signal/sig_set.c
Normal file
@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
* libc/signal/sig_set.c
|
||||
*
|
||||
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sigset
|
||||
*
|
||||
* Description:
|
||||
* The signal() function will modify signal dispositions. The 'signo'
|
||||
* argument specifies the signal. The 'func' argument specifies the
|
||||
* signal's disposition, which may be SIG_DFL, SIG_IGN, or the address
|
||||
* of a signal handler.
|
||||
*
|
||||
* The System V sigset function is very similar to the (obsolete) POSIX
|
||||
* signal() function except that it includes additional managment of the
|
||||
* tasks' signal mask. This function is then simply a wrapper around
|
||||
* signal() with this additional signal mask logic added.
|
||||
*
|
||||
* - The sigset set function also accepts the SIG_HOLD value for 'func':
|
||||
* If 'func' is equal to SIG_HOLD, 'signo' will be added to the signal
|
||||
* mask of the calling process and 'signo's disposition will remain
|
||||
* unchanged.
|
||||
* - If 'func' is not equal to SIG_HOLD, 'signo' will be removed from the
|
||||
* signal mask of the calling process.
|
||||
*
|
||||
* Input Parameters:
|
||||
* signo - Identifies the signal to operate on
|
||||
* func - The new disposition of the signal
|
||||
*
|
||||
* Returned Value:
|
||||
* Upon successful completion, sigset() shall return SIG_HOLD if the
|
||||
* signal had been blocked and the signal's previous disposition if it had
|
||||
* not been blocked. Otherwise, SIG_ERR shall be returned and errno set to
|
||||
* indicate the error.
|
||||
*
|
||||
* Hmm.. this wording is not clear to me. I assume this to mean:
|
||||
*
|
||||
* if (func == SIG_HOLD)
|
||||
* {
|
||||
* Set mask
|
||||
* if (mask successfuly set)
|
||||
* {
|
||||
* return SIG_HOLD
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* return SIG_ERR
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* Set disposition
|
||||
* if (disposition successfuly set)
|
||||
* {
|
||||
* return old disposition
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* return SIG_ERR
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* But you could also argue that the English means to return SIG_HOLD in
|
||||
* any case is the signal is blocked. And, in that case would you set the
|
||||
* disposition or not? Unclear.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
CODE void (*sigset(int signo, CODE void (*func)(int signo)))(int signo)
|
||||
{
|
||||
_sa_handler_t disposition;
|
||||
sigset_t set;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(GOOD_SIGNO(signo) && func != NULL);
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, signo);
|
||||
|
||||
/* Check if we are being asked to block the signal */
|
||||
|
||||
if (func == SIG_HOLD)
|
||||
{
|
||||
ret = sigprocmask(SIG_BLOCK, &set, NULL);
|
||||
disposition = ret < 0 ? SIG_ERR : SIG_HOLD;
|
||||
}
|
||||
|
||||
/* No.. then signal can handle the other cases */
|
||||
|
||||
else
|
||||
{
|
||||
/* Set the signal handler disposition */
|
||||
|
||||
disposition = signal(signo, func);
|
||||
if (disposition != SIG_ERR)
|
||||
{
|
||||
/* And unblock the signal */
|
||||
|
||||
ret = sigprocmask(SIG_UNBLOCK, &set, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Restore the original signal disposition and return and
|
||||
* error.
|
||||
*/
|
||||
|
||||
(void)signal(signo, disposition);
|
||||
disposition = SIG_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return disposition;
|
||||
}
|
@ -37,7 +37,10 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@ -50,29 +53,20 @@
|
||||
* The signal() function will modify signal dispositions. The 'signo'
|
||||
* argument specifies the signal. The 'func' argument specifies the
|
||||
* signal's disposition, which may be SIG_DFL, SIG_IGN, or the address
|
||||
* of a signal handler. If 'func' is the address of a signal handler, the
|
||||
* of a signal handler. If 'func' is the address of a signal handler, the
|
||||
* system will add 'signo' to the calling process' signal mask before
|
||||
* executing the signal handler; when the signal handler returns, the
|
||||
* system will restore the calling process' signal mask to its state prior
|
||||
* to the delivery of the signal. 'signo' will be removed from the calling
|
||||
* process' signal mask.
|
||||
*
|
||||
* NOTE: The value SIG_HOLD for 'func' is not supported. It should work
|
||||
* like this: If 'func' is equal to SIG_HOLD, 'signo' will be added to,
|
||||
* not removed from, the calling process' signal mask and 'signo''s
|
||||
* disposition will remain unchanged.
|
||||
* to the delivery of the signal.
|
||||
*
|
||||
* Input Parameters:
|
||||
* signo - Identifies the signal to operate on
|
||||
* func - The new disposition of the signal
|
||||
*
|
||||
* Returned Value:
|
||||
* Upon successful completion, signal() will the previous disposition of
|
||||
* the signal. Otherwise, SIG_ERR will be returned and errno set to
|
||||
* indicate the error.
|
||||
*
|
||||
* NOTE: signal() would return SIG_HOLD if the signal had been blocked and
|
||||
* the signal's previous disposition if it had not been blocked.
|
||||
* Upon successful completion, signal() will return the previous
|
||||
* disposition of the signal handling. Otherwise, SIG_ERR will be returned
|
||||
* and errno set to indicate the nature of the error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -82,6 +76,9 @@ CODE void (*signal(int signo, CODE void (*func)(int signo)))(int signo)
|
||||
struct sigaction oact;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(GOOD_SIGNO(signo) && func != NULL);
|
||||
DEBUGASSERT(func != SIG_ERR && func != SIG_HOLD);
|
||||
|
||||
/* Initialize the sigaction structure */
|
||||
|
||||
act.sa_handler = func;
|
||||
|
Loading…
Reference in New Issue
Block a user