/****************************************************************************
- * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
+ * Copyright 2020,2021 Thomas E. Dickey *
+ * Copyright 1998-2014,2017 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include <SigAction.h>
-#if SVR4_ACTION && !defined(_POSIX_SOURCE)
-#define _POSIX_SOURCE
-#endif
-
-MODULE_ID("$Id: lib_tstp.c,v 1.41 2010/05/15 21:31:12 tom Exp $")
+MODULE_ID("$Id: lib_tstp.c,v 1.51 2021/09/04 10:54:35 tom Exp $")
#if defined(SIGTSTP) && (HAVE_SIGACTION || HAVE_SIGVEC)
#define USE_SIGTSTP 1
* (this may include XENIX).
*
* This implementation will probably be changed to use signal(3) in
- * the future. If nothing else, it's simpler...
+ * the future. If nothing else, it is simpler...
*/
#if USE_SIGTSTP
static void
-tstp(int dummy GCC_UNUSED)
+handle_SIGTSTP(int dummy GCC_UNUSED)
{
SCREEN *sp = CURRENT_SCREEN;
sigset_t mask, omask;
int sigttou_blocked;
#endif
- T(("tstp() called"));
+ _nc_globals.have_sigtstp = 1;
+ T(("handle_SIGTSTP() called"));
/*
* The user may have changed the prog_mode tty bits, so save them.
* taken ownership of the tty and modified the settings when our
* parent was stopped before us, and we would likely pick up the
* settings already modified by the shell.
+ *
+ * Don't do this if we're not in curses -
*/
- if (sp != 0 && !sp->_endwin) /* don't do this if we're not in curses */
+ if (sp != 0 && (sp->_endwin == ewRunning))
#if HAVE_TCGETPGRP
if (tcgetpgrp(STDIN_FILENO) == getpgrp())
#endif
#endif /* USE_SIGTSTP */
static void
-cleanup(int sig)
+handle_SIGINT(int sig)
{
SCREEN *sp = CURRENT_SCREEN;
/*
- * Actually, doing any sort of I/O from within an signal handler is
- * "unsafe". But we'll _try_ to clean up the screen and terminal
- * settings on the way out.
+ * Much of this is unsafe from a signal handler. But we'll _try_ to clean
+ * up the screen and terminal settings on the way out.
+ *
+ * There are at least the following problems:
+ * 1) Walking the SCREEN list is unsafe, since all list management
+ * is done without any signal blocking.
+ * 2) On systems which have REENTRANT turned on, set_term() uses
+ * _nc_lock_global() which could deadlock or misbehave in other ways.
+ * 3) endwin() calls all sorts of stuff, many of which use stdio or
+ * other library functions which are clearly unsafe.
*/
if (!_nc_globals.cleanup_nested++
- && (sig == SIGINT
-#ifdef SIGQUIT
- || sig == SIGQUIT
-#endif
- )) {
+ && (sig == SIGINT || sig == SIGTERM)) {
#if HAVE_SIGACTION || HAVE_SIGVEC
sigaction_t act;
sigemptyset(&act.sa_mask);
SCREEN *scan;
for (each_screen(scan)) {
if (scan->_ofp != 0
- && isatty(fileno(scan->_ofp))) {
- scan->_cleanup = TRUE;
+ && NC_ISATTY(fileno(scan->_ofp))) {
scan->_outch = NCURSES_SP_NAME(_nc_outch);
}
set_term(scan);
NCURSES_SP_NAME(endwin) (NCURSES_SP_ARG);
if (sp)
- sp->_endwin = FALSE; /* in case we have an atexit! */
+ sp->_endwin = ewInitial; /* in case of reuse */
}
}
}
- exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
#if USE_SIGWINCH
static void
-sigwinch(int sig GCC_UNUSED)
+handle_SIGWINCH(int sig GCC_UNUSED)
{
_nc_globals.have_sigwinch = 1;
# if USE_PTHREADS_EINTR
* handler.
*/
static int
-CatchIfDefault(int sig, RETSIGTYPE (*handler) (int))
+CatchIfDefault(int sig, void (*handler) (int))
{
int result;
#if HAVE_SIGACTION || HAVE_SIGVEC
result = FALSE;
}
#else /* !HAVE_SIGACTION */
- RETSIGTYPE (*ohandler) (int);
+ void (*ohandler) (int);
ohandler = signal(sig, SIG_IGN);
if (ohandler == SIG_DFL
* the caller later changes its mind, but that doesn't seem correct.
*/
NCURSES_EXPORT(void)
-_nc_signal_handler(bool enable)
+_nc_signal_handler(int enable)
{
T((T_CALLED("_nc_signal_handler(%d)"), enable));
#if USE_SIGTSTP /* Xenix 2.x doesn't have SIGTSTP, for example */
#ifdef SA_RESTART
new_sigaction.sa_flags |= SA_RESTART;
#endif /* SA_RESTART */
- new_sigaction.sa_handler = tstp;
+ new_sigaction.sa_handler = handle_SIGTSTP;
(void) sigaction(SIGTSTP, &new_sigaction, NULL);
} else {
ignore_tstp = TRUE;
if (!_nc_globals.init_signals) {
if (enable) {
- CatchIfDefault(SIGINT, cleanup);
- CatchIfDefault(SIGTERM, cleanup);
+ CatchIfDefault(SIGINT, handle_SIGINT);
+ CatchIfDefault(SIGTERM, handle_SIGINT);
#if USE_SIGWINCH
- CatchIfDefault(SIGWINCH, sigwinch);
+ CatchIfDefault(SIGWINCH, handle_SIGWINCH);
#endif
_nc_globals.init_signals = TRUE;
}