Fixed proper restore of cttl-C in msg rcv
Rename and move plugin_context_check to clixon_resource_check
This commit is contained in:
parent
f25a77734e
commit
558a0df1f3
9 changed files with 268 additions and 261 deletions
|
|
@ -96,6 +96,7 @@
|
|||
#include <syslog.h>
|
||||
#include <grp.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#ifdef HAVE_SETNS /* linux network namespaces */
|
||||
#include <sched.h> /* setns / unshare */
|
||||
#endif
|
||||
|
|
@ -159,6 +160,17 @@ struct process_entry_t {
|
|||
proc_cb_t *pe_callback; /* Wrapper function, may be called from process_operation */
|
||||
};
|
||||
|
||||
/*! Structure for checking resources before and after a call
|
||||
*
|
||||
* Currently signal settings: blocked and handlers, and termios
|
||||
* @see clixon_resource_check
|
||||
*/
|
||||
struct resource_context {
|
||||
sigset_t rc_sigset; /* See sigprocmask(2) */
|
||||
struct sigaction rc_sigaction_vec[32]; /* See sigaction(2) */
|
||||
struct termios rc_termios; /* See termios(3) */
|
||||
};
|
||||
|
||||
/* Forward declaration */
|
||||
static int clixon_process_sched_register(clixon_handle h, int delay);
|
||||
static int clixon_process_delete_only(process_entry_t *pe);
|
||||
|
|
@ -1100,3 +1112,181 @@ clixon_process_waitpid(clixon_handle h)
|
|||
clixon_debug(CLIXON_DBG_DEFAULT, "%s retval:%d", __FUNCTION__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Get system context, eg signal procmask (for blocking) and sigactions
|
||||
*
|
||||
* Call this before a plugin
|
||||
* @retval pc Plugin context structure, use free() to deallocate
|
||||
* @retval NULL Error
|
||||
* */
|
||||
static void *
|
||||
resource_context_get(void)
|
||||
{
|
||||
int i;
|
||||
struct resource_context *rc = NULL;
|
||||
|
||||
if ((rc = malloc(sizeof(*rc))) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(rc, 0, sizeof(*rc));
|
||||
if (sigprocmask(0, NULL, &rc->rc_sigset) < 0){
|
||||
clixon_err(OE_UNIX, errno, "sigprocmask");
|
||||
goto done;
|
||||
}
|
||||
for (i=1; i<32; i++){
|
||||
if (sigaction(i, NULL, &rc->rc_sigaction_vec[i]) < 0){
|
||||
clixon_err(OE_UNIX, errno, "sigaction");
|
||||
goto done;
|
||||
}
|
||||
/* Mask SA_RESTORER: Not intended for application use.
|
||||
* Note that it may not be included in user space so may be hardcoded below
|
||||
*/
|
||||
#ifdef SA_RESTORER
|
||||
rc->rc_sigaction_vec[i].sa_flags &= ~SA_RESTORER;
|
||||
#else
|
||||
rc->rc_sigaction_vec[i].sa_flags &= ~0x04000000;
|
||||
#endif
|
||||
}
|
||||
if (isatty(0) && tcgetattr(0, &rc->rc_termios) < 0){
|
||||
clixon_err(OE_UNIX, errno, "tcgetattr %d", errno);
|
||||
goto done;
|
||||
}
|
||||
return rc;
|
||||
done:
|
||||
if (rc)
|
||||
free(rc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Check terminal+signal context, check if anything has changed
|
||||
*
|
||||
* Called twice:
|
||||
* 1) Make a check of resources
|
||||
* 2) Make a new check and compare with the old check, return 1 on success, 0 on fail
|
||||
* Log if there is a difference at loglevel WARNING.
|
||||
* Controlled by CLICON_PLUGIN_CALLBACK_CHECK:
|
||||
* 0 : No checks
|
||||
* 1 : warning logs on failure
|
||||
* 2 : log and abort on failure
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in,out] wh Either: NULL for init, will be assigned, OR previous handle (will be freed)
|
||||
* @param[in] name Name of plugin for logging. Can be other name, context dependent
|
||||
* @param[in] fn Typically name of callback, or caller function
|
||||
* @retval 1 OK
|
||||
* @retval 0 Fail, log on syslog using LOG_WARNING
|
||||
* @retval -1 Error
|
||||
* @note Only logs error, does not generate error
|
||||
* @note name and fn are context dependent, since the env of callback calls are very different
|
||||
* @see CLICON_PLUGIN_CALLBACK_CHECK Enable to activate these checks
|
||||
* The naming "PLUGIN" is of historical reasons.
|
||||
*/
|
||||
int
|
||||
clixon_resource_check(clixon_handle h,
|
||||
void **wh,
|
||||
const char *name,
|
||||
const char *fn)
|
||||
{
|
||||
int retval = -1;
|
||||
int failed = 0;
|
||||
int i;
|
||||
struct resource_context *oldrc;
|
||||
struct resource_context *newrc = NULL;
|
||||
int option;
|
||||
|
||||
if (h == NULL){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
option = clicon_option_int(h, "CLICON_PLUGIN_CALLBACK_CHECK");
|
||||
/* Check if plugion checks are enabled */
|
||||
if (option == 0)
|
||||
return 1;
|
||||
if (wh == NULL){
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (*wh == NULL){
|
||||
*wh = resource_context_get();
|
||||
return 1;
|
||||
}
|
||||
oldrc = (struct resource_context *)*wh;
|
||||
if ((newrc = resource_context_get()) == NULL)
|
||||
goto done;
|
||||
if (oldrc->rc_termios.c_iflag != newrc->rc_termios.c_iflag){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed termios input modes from 0x%x to 0x%x", __FUNCTION__,
|
||||
name, fn,
|
||||
oldrc->rc_termios.c_iflag,
|
||||
newrc->rc_termios.c_iflag);
|
||||
failed++;
|
||||
}
|
||||
if (oldrc->rc_termios.c_oflag != newrc->rc_termios.c_oflag){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed termios output modes from 0x%x to 0x%x", __FUNCTION__,
|
||||
name, fn,
|
||||
oldrc->rc_termios.c_oflag,
|
||||
newrc->rc_termios.c_oflag);
|
||||
failed++;
|
||||
}
|
||||
if (oldrc->rc_termios.c_cflag != newrc->rc_termios.c_cflag){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed termios control modes from 0x%x to 0x%x", __FUNCTION__,
|
||||
name, fn,
|
||||
oldrc->rc_termios.c_cflag,
|
||||
newrc->rc_termios.c_cflag);
|
||||
failed++;
|
||||
}
|
||||
if (oldrc->rc_termios.c_lflag != newrc->rc_termios.c_lflag){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed termios local modes from 0x%x to 0x%x", __FUNCTION__,
|
||||
name, fn,
|
||||
oldrc->rc_termios.c_lflag,
|
||||
newrc->rc_termios.c_lflag);
|
||||
failed++;
|
||||
}
|
||||
/* XXX rc_termios.cc_t c_cc[NCCS] not checked */
|
||||
/* Abort if option is 2 or above on failure
|
||||
*/
|
||||
if (option > 1 && failed)
|
||||
abort();
|
||||
for (i=1; i<32; i++){
|
||||
if (sigismember(&oldrc->rc_sigset, i) != sigismember(&newrc->rc_sigset, i)){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed blocking of signal %s(%d) from %d to %d", __FUNCTION__,
|
||||
name, fn, strsignal(i), i,
|
||||
sigismember(&oldrc->rc_sigset, i),
|
||||
sigismember(&newrc->rc_sigset, i)
|
||||
);
|
||||
failed++;
|
||||
}
|
||||
if (oldrc->rc_sigaction_vec[i].sa_flags != newrc->rc_sigaction_vec[i].sa_flags){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed flags of signal %s(%d) from 0x%x to 0x%x", __FUNCTION__,
|
||||
name, fn, strsignal(i), i,
|
||||
oldrc->rc_sigaction_vec[i].sa_flags,
|
||||
newrc->rc_sigaction_vec[i].sa_flags);;
|
||||
failed++;
|
||||
}
|
||||
if (oldrc->rc_sigaction_vec[i].sa_sigaction != newrc->rc_sigaction_vec[i].sa_sigaction){
|
||||
clixon_log(h, LOG_WARNING, "%s Plugin context %s %s: Changed action of signal %s(%d) from %p to %p", __FUNCTION__,
|
||||
name, fn, strsignal(i), i,
|
||||
oldrc->rc_sigaction_vec[i].sa_sigaction,
|
||||
newrc->rc_sigaction_vec[i].sa_sigaction);
|
||||
failed++;
|
||||
}
|
||||
/* Abort if option is 2 or above on failure
|
||||
*/
|
||||
if (option > 1 && failed)
|
||||
abort();
|
||||
}
|
||||
if (failed)
|
||||
goto fail;
|
||||
retval = 1; /* OK */
|
||||
done:
|
||||
if (newrc)
|
||||
free(newrc);
|
||||
if (oldrc)
|
||||
free(oldrc);
|
||||
if (wh && *wh)
|
||||
*wh = NULL;
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue