mirror of https://github.com/joan2937/pigpio
Improve signal handling. (#532)
This commit is contained in:
parent
27b5ea9c58
commit
3e0a5085f1
230
pigpio.c
230
pigpio.c
|
@ -984,6 +984,10 @@ typedef struct
|
||||||
callbk_t func;
|
callbk_t func;
|
||||||
unsigned ex;
|
unsigned ex;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
struct sigaction old;
|
||||||
|
unsigned set;
|
||||||
|
unsigned dfl;
|
||||||
|
unsigned skip; // preset || SIG_IGN
|
||||||
} gpioSignal_t;
|
} gpioSignal_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -1232,6 +1236,7 @@ static volatile uint32_t hw_clk_max_freq = PI_HW_CLK_MAX_FREQ;
|
||||||
|
|
||||||
static int libInitialised = 0;
|
static int libInitialised = 0;
|
||||||
|
|
||||||
|
|
||||||
/* initialise every gpioInitialise */
|
/* initialise every gpioInitialise */
|
||||||
|
|
||||||
static struct timespec libStarted;
|
static struct timespec libStarted;
|
||||||
|
@ -1313,6 +1318,7 @@ static spiInfo_t spiInfo [PI_SPI_SLOTS];
|
||||||
static gpioScript_t gpioScript [PI_MAX_SCRIPTS];
|
static gpioScript_t gpioScript [PI_MAX_SCRIPTS];
|
||||||
|
|
||||||
static gpioSignal_t gpioSignal [PI_MAX_SIGNUM+1];
|
static gpioSignal_t gpioSignal [PI_MAX_SIGNUM+1];
|
||||||
|
static struct sigaction defaultSigaction;
|
||||||
|
|
||||||
static gpioTimer_t gpioTimer [PI_MAX_TIMER+1];
|
static gpioTimer_t gpioTimer [PI_MAX_TIMER+1];
|
||||||
|
|
||||||
|
@ -1515,6 +1521,12 @@ int gpioWaveTxStart(unsigned wave_mode); /* deprecated */
|
||||||
|
|
||||||
static void closeOrphanedNotifications(int slot, int fd);
|
static void closeOrphanedNotifications(int slot, int fd);
|
||||||
|
|
||||||
|
static void signalInstaller(void);
|
||||||
|
static int setSignalInstaller(unsigned signum);
|
||||||
|
static void defaultSigHandler(int signum);
|
||||||
|
static void customSigHandler(int signum);
|
||||||
|
|
||||||
|
static void initKillDMA(volatile uint32_t *dmaAddr);
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
@ -5582,6 +5594,40 @@ static void dmaInitCbs(void)
|
||||||
|
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
static void defaultSigHandler(int signum)
|
||||||
|
{
|
||||||
|
/* kill DMA channels & unlink pid file */
|
||||||
|
if (dmaReg != MAP_FAILED)
|
||||||
|
{
|
||||||
|
initKillDMA(dmaIn);
|
||||||
|
initKillDMA(dmaOut);
|
||||||
|
dmaReg = MAP_FAILED; // OS will munmap on termination
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fdLock != -1)
|
||||||
|
{
|
||||||
|
close(fdLock);
|
||||||
|
unlink(PI_LOCKFILE);
|
||||||
|
fdLock = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* raise signal again, this time using *system* default action */
|
||||||
|
sigaction(signum, &gpioSignal[signum].old, NULL);
|
||||||
|
raise(signum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void customSigHandler(int signum)
|
||||||
|
{
|
||||||
|
if (signum == SIGUSR1)
|
||||||
|
gpioCfg.dbgLevel = (gpioCfg.dbgLevel > DBG_MIN_LEVEL) ?
|
||||||
|
--gpioCfg.dbgLevel :
|
||||||
|
DBG_MIN_LEVEL;
|
||||||
|
|
||||||
|
if (signum == SIGUSR2)
|
||||||
|
gpioCfg.dbgLevel = (gpioCfg.dbgLevel < DBG_MAX_LEVEL) ?
|
||||||
|
++gpioCfg.dbgLevel :
|
||||||
|
DBG_MAX_LEVEL;
|
||||||
|
}
|
||||||
|
|
||||||
static void sigHandler(int signum)
|
static void sigHandler(int signum)
|
||||||
{
|
{
|
||||||
|
@ -5643,21 +5689,105 @@ static void sigHandler(int signum)
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void sigSetHandler(void)
|
static void signalInstaller(void)
|
||||||
{
|
{
|
||||||
int i;
|
int signum;
|
||||||
struct sigaction new;
|
struct sigaction new, tmp;
|
||||||
|
gpioSignal_t *sig;
|
||||||
|
|
||||||
for (i=PI_MIN_SIGNUM; i<=PI_MAX_SIGNUM; i++)
|
if (gpioCfg.internals & PI_CFG_NOSIGHANDLER)
|
||||||
{
|
{
|
||||||
|
DBG(DBG_USER, "Signal installer disabled, PI_CFG_NOSIGHANDLER")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&new, 0, sizeof(new));
|
sigemptyset(&new.sa_mask);
|
||||||
new.sa_handler = sigHandler;
|
new.sa_flags = 0;
|
||||||
|
|
||||||
sigaction(i, &new, NULL);
|
for (signum=PI_MIN_SIGNUM; signum<=PI_MAX_SIGNUM; signum++)
|
||||||
|
{
|
||||||
|
sig = &gpioSignal[signum];
|
||||||
|
|
||||||
|
/* skip if invalid */
|
||||||
|
if (sigaction(signum, NULL, &tmp) < 0)
|
||||||
|
{
|
||||||
|
sig->skip = 1;
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: invalid\n", signum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip if not system default handler */
|
||||||
|
if (tmp.sa_handler != SIG_DFL)
|
||||||
|
{
|
||||||
|
sig->skip = 1;
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: !SIG_DFL\n", signum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(signum)
|
||||||
|
{
|
||||||
|
/* job control signals - allow gpioSetSignalFunc*/
|
||||||
|
case SIGCONT:
|
||||||
|
case SIGTSTP:
|
||||||
|
case SIGTTIN:
|
||||||
|
case SIGTTOU:
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* ignore signals - skip gpioSetSignalFunc */
|
||||||
|
case SIGPIPE:
|
||||||
|
case SIGWINCH:
|
||||||
|
case SIGCHLD:
|
||||||
|
new.sa_handler = SIG_IGN;
|
||||||
|
sigaction(signum, &new, &sig->old);
|
||||||
|
sig->set = 1;
|
||||||
|
sig->skip = 1; // protect from cancellation
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: skip=1, ignored\n", signum);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* install custom handler */
|
||||||
|
case SIGUSR1:
|
||||||
|
case SIGUSR2:
|
||||||
|
sigaddset(&new.sa_mask, SIGUSR1);
|
||||||
|
sigaddset(&new.sa_mask, SIGUSR2);
|
||||||
|
new.sa_handler = customSigHandler;
|
||||||
|
sigaction(signum, &new, &sig->old);
|
||||||
|
sig->set = 1;
|
||||||
|
|
||||||
|
// restore defaultSigaction if canceled
|
||||||
|
sig->dfl = 1;
|
||||||
|
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: set=1, customSigHandler installed\n", signum);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sigaction(signum, &defaultSigaction, &sig->old);
|
||||||
|
sig->dfl = 1;
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: dfl=1, defaultSigHandler installed\n", signum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void signalUninstaller(void)
|
||||||
|
{
|
||||||
|
int signum;
|
||||||
|
gpioSignal_t *sig;
|
||||||
|
|
||||||
|
for (signum=PI_MIN_SIGNUM; signum<=PI_MAX_SIGNUM; signum++)
|
||||||
|
{
|
||||||
|
sig = &gpioSignal[signum];
|
||||||
|
|
||||||
|
if (sig->set || sig->dfl)
|
||||||
|
{
|
||||||
|
sigaction(signum, &sig->old, NULL);
|
||||||
|
sig->set = 0;
|
||||||
|
sig->dfl = 0;
|
||||||
|
DBG(DBG_INTERNAL, "Signal %d: Restored, system default handler\n", signum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
/*
|
/*
|
||||||
freq mics net
|
freq mics net
|
||||||
0 1000 1000 900
|
0 1000 1000 900
|
||||||
|
@ -8021,8 +8151,15 @@ static void initClearGlobals(void)
|
||||||
gpioSignal[i].func = NULL;
|
gpioSignal[i].func = NULL;
|
||||||
gpioSignal[i].ex = 0;
|
gpioSignal[i].ex = 0;
|
||||||
gpioSignal[i].userdata = NULL;
|
gpioSignal[i].userdata = NULL;
|
||||||
|
gpioSignal[i].set = 0;
|
||||||
|
gpioSignal[i].dfl = 0;
|
||||||
|
memset(&gpioSignal[i].old, 0, sizeof(gpioSignal[i].old));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultSigaction.sa_handler = defaultSigHandler;
|
||||||
|
defaultSigaction.sa_flags = 0;
|
||||||
|
sigfillset(&defaultSigaction.sa_mask);
|
||||||
|
|
||||||
for (i=0; i<=PI_MAX_TIMER; i++)
|
for (i=0; i<=PI_MAX_TIMER; i++)
|
||||||
{
|
{
|
||||||
gpioTimer[i].running = 0;
|
gpioTimer[i].running = 0;
|
||||||
|
@ -8324,7 +8461,7 @@ int initInitialise(void)
|
||||||
|
|
||||||
#ifndef EMBEDDED_IN_VM
|
#ifndef EMBEDDED_IN_VM
|
||||||
if (!(gpioCfg.internals & PI_CFG_NOSIGHANDLER))
|
if (!(gpioCfg.internals & PI_CFG_NOSIGHANDLER))
|
||||||
sigSetHandler();
|
signalInstaller();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (initPeripherals() < 0) return PI_INIT_FAILED;
|
if (initPeripherals() < 0) return PI_INIT_FAILED;
|
||||||
|
@ -8767,8 +8904,10 @@ void gpioTerminate(void)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\n#####################################################\n\n\n");
|
"\n#####################################################\n\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
signalUninstaller();
|
||||||
|
|
||||||
initReleaseResources();
|
initReleaseResources();
|
||||||
|
|
||||||
fflush(NULL);
|
fflush(NULL);
|
||||||
|
@ -12845,24 +12984,79 @@ int gpioDeleteScript(unsigned script_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
static int setSignalInstaller(unsigned signum)
|
||||||
|
{
|
||||||
|
gpioSignal_t *sig = &gpioSignal[signum];
|
||||||
|
struct sigaction new;
|
||||||
|
|
||||||
|
if (sig->skip)
|
||||||
|
return PI_SIG_SKIPPED;
|
||||||
|
|
||||||
|
/* set: save old signal action and set new */
|
||||||
|
|
||||||
|
if (sig->func)
|
||||||
|
{
|
||||||
|
if (sig->set == 0)
|
||||||
|
{
|
||||||
|
DBG(DBG_INTERNAL, "Set new handler for signal %d" ,signum);
|
||||||
|
memset(&new, 0, sizeof(new));
|
||||||
|
new.sa_handler = sigHandler;
|
||||||
|
sigfillset(&new.sa_mask);
|
||||||
|
sig->set = 1;
|
||||||
|
|
||||||
|
if (sig->dfl == 0)
|
||||||
|
return sigaction(signum, &new, &sig->old);
|
||||||
|
|
||||||
|
else
|
||||||
|
return sigaction(signum, &new, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PI_SIGNUM_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cancel and restore old signal action */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sig->set)
|
||||||
|
{
|
||||||
|
DBG(DBG_INTERNAL, "Cancel and restore handler for signal %d" ,signum);
|
||||||
|
sig->set = 0;
|
||||||
|
|
||||||
|
if (sig->dfl == 0)
|
||||||
|
return sigaction(signum, &sig->old, NULL);
|
||||||
|
|
||||||
|
else
|
||||||
|
return sigaction(signum, &defaultSigaction, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PI_SIG_UNK_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
|
int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
|
||||||
{
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
DBG(DBG_USER, "signum=%d function=%08"PRIXPTR, signum, (uintptr_t)f);
|
DBG(DBG_USER, "signum=%d function=%08"PRIXPTR, signum, (uintptr_t)f);
|
||||||
|
|
||||||
CHECK_INITED;
|
CHECK_INITED;
|
||||||
|
|
||||||
|
if (gpioCfg.internals & PI_CFG_NOSIGHANDLER)
|
||||||
|
return PI_NOSIGHANDLER;
|
||||||
|
|
||||||
if (signum > PI_MAX_SIGNUM)
|
if (signum > PI_MAX_SIGNUM)
|
||||||
SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
|
SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
|
||||||
|
|
||||||
gpioSignal[signum].ex = 0;
|
gpioSignal[signum].ex = 0;
|
||||||
gpioSignal[signum].userdata = NULL;
|
gpioSignal[signum].userdata = NULL;
|
||||||
|
|
||||||
gpioSignal[signum].func = f;
|
gpioSignal[signum].func = f;
|
||||||
|
|
||||||
return 0;
|
rv = setSignalInstaller(signum);
|
||||||
|
return (rv == -1) ? PI_SIG_UNK_ACTION : rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12871,20 +13065,25 @@ int gpioSetSignalFunc(unsigned signum, gpioSignalFunc_t f)
|
||||||
int gpioSetSignalFuncEx(unsigned signum, gpioSignalFuncEx_t f,
|
int gpioSetSignalFuncEx(unsigned signum, gpioSignalFuncEx_t f,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
DBG(DBG_USER, "signum=%d function=%08"PRIXPTR" userdata=%08"PRIXPTR,
|
DBG(DBG_USER, "signum=%d function=%08"PRIXPTR" userdata=%08"PRIXPTR,
|
||||||
signum, (uintptr_t)f, (uintptr_t)userdata);
|
signum, (uintptr_t)f, (uintptr_t)userdata);
|
||||||
|
|
||||||
CHECK_INITED;
|
CHECK_INITED;
|
||||||
|
|
||||||
|
if (gpioCfg.internals & PI_CFG_NOSIGHANDLER)
|
||||||
|
return PI_NOSIGHANDLER;
|
||||||
|
|
||||||
if (signum > PI_MAX_SIGNUM)
|
if (signum > PI_MAX_SIGNUM)
|
||||||
SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
|
SOFT_ERROR(PI_BAD_SIGNUM, "bad signum (%d)", signum);
|
||||||
|
|
||||||
gpioSignal[signum].ex = 1;
|
gpioSignal[signum].ex = 1;
|
||||||
gpioSignal[signum].userdata = userdata;
|
gpioSignal[signum].userdata = userdata;
|
||||||
|
|
||||||
gpioSignal[signum].func = f;
|
gpioSignal[signum].func = f;
|
||||||
|
|
||||||
return 0;
|
rv = setSignalInstaller(signum);
|
||||||
|
return (rv == -1) ? PI_SIG_UNK_ACTION : rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14025,7 +14224,9 @@ int gpioCfgNetAddr(int numSockAddr, uint32_t *sockAddr)
|
||||||
|
|
||||||
uint32_t gpioCfgGetInternals(void)
|
uint32_t gpioCfgGetInternals(void)
|
||||||
{
|
{
|
||||||
return gpioCfg.internals;
|
return ((gpioCfg.internals & 0xffffff00)
|
||||||
|
| gpioCfg.alertFreq << 4
|
||||||
|
| gpioCfg.dbgLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gpioCfgSetInternals(uint32_t cfgVal)
|
int gpioCfgSetInternals(uint32_t cfgVal)
|
||||||
|
@ -14041,4 +14242,3 @@ int gpioCfgSetInternals(uint32_t cfgVal)
|
||||||
/* include any user customisations */
|
/* include any user customisations */
|
||||||
|
|
||||||
#include "custom.cext"
|
#include "custom.cext"
|
||||||
|
|
||||||
|
|
5
pigpio.h
5
pigpio.h
|
@ -6528,6 +6528,11 @@ after this command is issued.
|
||||||
#define PI_CMD_INTERRUPTED -144 // Used by Python
|
#define PI_CMD_INTERRUPTED -144 // Used by Python
|
||||||
#define PI_NOT_ON_BCM2711 -145 // not available on BCM2711
|
#define PI_NOT_ON_BCM2711 -145 // not available on BCM2711
|
||||||
#define PI_ONLY_ON_BCM2711 -146 // only available on BCM2711
|
#define PI_ONLY_ON_BCM2711 -146 // only available on BCM2711
|
||||||
|
#define PI_NOSIGHANDLER -147 // signal handling is disabled (gpioCfg.internals)
|
||||||
|
#define PI_SIGNUM_INVALID -148 // invalid signal number requested (signal.h)
|
||||||
|
#define PI_SIGNUM_SET -149 // handler for signal is already installed
|
||||||
|
#define PI_SIG_UNK_ACTION -150 // default signal handler is not installed
|
||||||
|
#define PI_SIG_SKIPPED -151 // set/cancel signal handler is not allowed
|
||||||
|
|
||||||
#define PI_PIGIF_ERR_0 -2000
|
#define PI_PIGIF_ERR_0 -2000
|
||||||
#define PI_PIGIF_ERR_99 -2099
|
#define PI_PIGIF_ERR_99 -2099
|
||||||
|
|
110
x_pigpio.c
110
x_pigpio.c
|
@ -22,6 +22,7 @@ sudo ./x_pigpio
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#include "pigpio.h"
|
#include "pigpio.h"
|
||||||
|
|
||||||
|
@ -900,6 +901,114 @@ void tc()
|
||||||
CHECK(12, 99, e, 0, 0, "spiClose");
|
CHECK(12, 99, e, 0, 0, "spiClose");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int signum;
|
||||||
|
enum signalType {Invalid, Default, Ignore, Catch};
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
enum signalType type;
|
||||||
|
struct sigaction action;
|
||||||
|
} sigArr_t;
|
||||||
|
sigArr_t sigArr[PI_MAX_SIGNUM+1];
|
||||||
|
struct sigaction query, preset;
|
||||||
|
void voidHandler(int signum) {}
|
||||||
|
|
||||||
|
void td(void)
|
||||||
|
{
|
||||||
|
/* Categorize all handlers */
|
||||||
|
|
||||||
|
for (signum = 0; signum<=PI_MAX_SIGNUM; signum++)
|
||||||
|
{
|
||||||
|
if (sigaction(signum, NULL, &sigArr[signum].action) < 0)
|
||||||
|
sigArr[signum].type = Invalid;
|
||||||
|
|
||||||
|
else if (sigArr[signum].action.sa_handler == SIG_DFL)
|
||||||
|
sigArr[signum].type = Default;
|
||||||
|
|
||||||
|
else if (sigArr[signum].action.sa_handler == SIG_IGN)
|
||||||
|
sigArr[signum].type = Ignore;
|
||||||
|
|
||||||
|
else sigArr[signum].type = Catch; // Preset, Set or Dfl
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check signals affected by default installer. */
|
||||||
|
|
||||||
|
CHECK(13,1, sigArr[SIGCHLD].type, Ignore, 0, "SIGCHLD ignored");
|
||||||
|
CHECK(13,2, sigArr[SIGPIPE].type, Ignore, 0, "SIGPIPE Ignored");
|
||||||
|
CHECK(13,3, sigArr[SIGWINCH].type, Ignore, 0, "SIGWINCH ignored");
|
||||||
|
CHECK(13,4, sigArr[SIGUSR1].type, Catch, 0, "SIGUSR1 installed");
|
||||||
|
CHECK(13,5, sigArr[SIGUSR2].type, Catch, 0, "SIGUSR2 installed");
|
||||||
|
|
||||||
|
/* Set and restore handler on cancellation. */
|
||||||
|
|
||||||
|
CHECK(13,6, gpioSetSignalFunc(SIGSEGV, voidHandler), 0, 0, "set signal");
|
||||||
|
CHECK(13,7, gpioSetSignalFunc(SIGSEGV, NULL), 0, 0, "cancel signal");
|
||||||
|
CHECK(13,8, sigaction(SIGSEGV, NULL, &query), 0, 0, "query sigaction");
|
||||||
|
CHECK(13,9, (intptr_t)query.sa_handler, (intptr_t)sigArr[SIGSEGV].action.sa_handler, 0, "gpioSetSignalFunc");
|
||||||
|
|
||||||
|
|
||||||
|
/* check custom handler function */
|
||||||
|
|
||||||
|
raise(SIGUSR2); // increment dgbLevel
|
||||||
|
time_sleep(0.1);
|
||||||
|
CHECK(13,10, gpioCfgGetInternals() & 0x0f, 1, 0, "SIGUSR2");
|
||||||
|
|
||||||
|
raise(SIGUSR1); // decrement dgbLevel
|
||||||
|
time_sleep(0.1);
|
||||||
|
CHECK(13,11, gpioCfgGetInternals() & 0x0f, 0, 0, "SIGUSR1");
|
||||||
|
|
||||||
|
|
||||||
|
/* check gpioTermination restores all signal handlers to their pre-initialise state. */
|
||||||
|
|
||||||
|
gpioTerminate();
|
||||||
|
|
||||||
|
unsigned catchNotRestored = 0;
|
||||||
|
unsigned ignoreNotRestored = 0;
|
||||||
|
for (signum = 0; signum<=PI_MAX_SIGNUM; signum++)
|
||||||
|
{
|
||||||
|
if (sigArr[signum].type == Catch)
|
||||||
|
if (sigaction(signum, NULL, &query) == 0)
|
||||||
|
if (query.sa_handler != SIG_DFL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "signal %d not restored\n", signum);
|
||||||
|
catchNotRestored++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigArr[signum].type == Ignore)
|
||||||
|
if (sigaction(signum, NULL, &query) == 0)
|
||||||
|
if (query.sa_handler != SIG_DFL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "signal %d not restored\n", signum);
|
||||||
|
ignoreNotRestored++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CHECK(13,12, catchNotRestored, 0, 0, "caught signals not restored");
|
||||||
|
CHECK(13,13, ignoreNotRestored, 0, 0, "ignored signals not restored");
|
||||||
|
|
||||||
|
/* check handlers prior to gpioInitialise are preserved */
|
||||||
|
|
||||||
|
preset = sigArr[SIGINT].action;
|
||||||
|
memset(&preset, 0, sizeof(preset));
|
||||||
|
preset.sa_handler = voidHandler;
|
||||||
|
CHECK(13,14, sigaction(SIGINT, &preset, &query), 0, 0, "preset action");
|
||||||
|
|
||||||
|
CHECK(13,15, gpioInitialise(), 79, 0, "gpioInitialise"); // FIX version dependency
|
||||||
|
CHECK(13,16, gpioSetSignalFunc(SIGINT, voidHandler), PI_SIG_SKIPPED, 0, "preset override");
|
||||||
|
|
||||||
|
// can not set ignored signals
|
||||||
|
CHECK(13,17, gpioSetSignalFunc(SIGPIPE, voidHandler), PI_SIG_SKIPPED, 0, "set ignore");
|
||||||
|
|
||||||
|
|
||||||
|
/* Test signal handlers disabled */
|
||||||
|
|
||||||
|
gpioTerminate();
|
||||||
|
gpioCfgSetInternals(gpioCfgGetInternals() | PI_CFG_NOSIGHANDLER);
|
||||||
|
gpioInitialise();
|
||||||
|
|
||||||
|
sigaction(SIGHUP, NULL, &query);
|
||||||
|
CHECK(13,18, (intptr_t)query.sa_handler, (intptr_t)SIG_DFL, 0, "default disabled");
|
||||||
|
CHECK(13,19, gpioSetSignalFunc(SIGHUP, NULL), PI_NOSIGHANDLER, 0, "set disabled");
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, t, c, status;
|
int i, t, c, status;
|
||||||
|
@ -944,6 +1053,7 @@ int main(int argc, char *argv[])
|
||||||
if (strchr(test, 'a')) ta();
|
if (strchr(test, 'a')) ta();
|
||||||
if (strchr(test, 'b')) tb();
|
if (strchr(test, 'b')) tb();
|
||||||
if (strchr(test, 'c')) tc();
|
if (strchr(test, 'c')) tc();
|
||||||
|
if (strchr(test, 'd')) td();
|
||||||
|
|
||||||
gpioTerminate();
|
gpioTerminate();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue