1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00

New system for handling SSH signals.

This is in much the same style as the ttymodes revamp, using a header
file which can be included in different ways to either iterate over
_all_ the signals in the known list or just the ones for which a
definition exists on the target OS.

So this doesn't actually _remove_ the horrid pile of ifdefs in
mainchan_rcvd_exit_signal, but at least it puts it somewhere less
intrusive and more reusable.
This commit is contained in:
Simon Tatham 2018-10-14 10:05:23 +01:00
parent dead35dd0f
commit 72eca76d20
3 changed files with 93 additions and 97 deletions

View File

@ -432,57 +432,20 @@ static int mainchan_rcvd_exit_signal(
char *signame_str;
/*
* Translate the signal description back into a locally
* meaningful number.
* Translate the signal description back into a locally meaningful
* number, or 128 if the string didn't match any we recognise.
*/
exitcode = 128;
if (0)
;
#define TRANSLATE_SIGNAL(s) \
else if (ptrlen_eq_string(signame, #s)) \
exitcode = 128 + SIG ## s
#ifdef SIGABRT
TRANSLATE_SIGNAL(ABRT);
#endif
#ifdef SIGALRM
TRANSLATE_SIGNAL(ALRM);
#endif
#ifdef SIGFPE
TRANSLATE_SIGNAL(FPE);
#endif
#ifdef SIGHUP
TRANSLATE_SIGNAL(HUP);
#endif
#ifdef SIGILL
TRANSLATE_SIGNAL(ILL);
#endif
#ifdef SIGINT
TRANSLATE_SIGNAL(INT);
#endif
#ifdef SIGKILL
TRANSLATE_SIGNAL(KILL);
#endif
#ifdef SIGPIPE
TRANSLATE_SIGNAL(PIPE);
#endif
#ifdef SIGQUIT
TRANSLATE_SIGNAL(QUIT);
#endif
#ifdef SIGSEGV
TRANSLATE_SIGNAL(SEGV);
#endif
#ifdef SIGTERM
TRANSLATE_SIGNAL(TERM);
#endif
#ifdef SIGUSR1
TRANSLATE_SIGNAL(USR1);
#endif
#ifdef SIGUSR2
TRANSLATE_SIGNAL(USR2);
#endif
#undef TRANSLATE_SIGNAL
else
exitcode = 128;
#define SIGNAL_SUB(s) \
if (ptrlen_eq_string(signame, #s)) \
exitcode = 128 + SIG ## s;
#define SIGNAL_MAIN(s, text) SIGNAL_SUB(s)
#define SIGNALS_LOCAL_ONLY
#include "sshsignals.h"
#undef SIGNAL_SUB
#undef SIGNAL_MAIN
#undef SIGNALS_LOCAL_ONLY
ssh_got_exitcode(mc->ppl->ssh, exitcode);
if (exitcode == 128)
@ -509,31 +472,6 @@ static int mainchan_rcvd_exit_signal_numeric(
return TRUE;
}
/*
* List of signal names defined by RFC 4254. These include all the ISO
* C signals, but are a subset of the POSIX required signals.
*
* The list macro takes parameters MAIN and SUB, which is an arbitrary
* UI decision to expose the signals we think users are most likely to
* want, with extra descriptive text, and relegate the less probable
* ones to a submenu for people who know what they're doing.
*/
#define SIGNAL_LIST(MAIN, SUB) \
MAIN(INT, "Interrupt") \
MAIN(TERM, "Terminate") \
MAIN(KILL, "Kill") \
MAIN(QUIT, "Quit") \
MAIN(HUP, "Hangup") \
SUB(ABRT) \
SUB(ALRM) \
SUB(FPE) \
SUB(ILL) \
SUB(PIPE) \
SUB(SEGV) \
SUB(USR1) \
SUB(USR2) \
/* end of list */
void mainchan_get_specials(
mainchan *mc, add_special_fn_t add_special, void *ctx)
{
@ -541,36 +479,36 @@ void mainchan_get_specials(
add_special(ctx, "Break", SS_BRK, 0);
#define ADD_MAIN(name, desc) \
#define SIGNAL_MAIN(name, desc) \
add_special(ctx, "SIG" #name " (" desc ")", SS_SIG ## name, 0);
#define ADD_SUB(name) \
add_special(ctx, "SIG" #name, SS_SIG ## name, 0);
#define SIGNAL_SUB(name)
#include "sshsignals.h"
#undef SIGNAL_MAIN
#undef SIGNAL_SUB
#define NO_ADD_SUB(name)
#define NO_ADD_MAIN(name, desc)
SIGNAL_LIST(ADD_MAIN, NO_ADD_SUB);
add_special(ctx, "More signals", SS_SUBMENU, 0);
SIGNAL_LIST(NO_ADD_MAIN, ADD_SUB);
add_special(ctx, NULL, SS_EXITMENU, 0);
#undef ADD_MAIN
#undef ADD_SUB
#undef NO_ADD_MAIN
#undef NO_ADD_SUB
#define SIGNAL_MAIN(name, desc)
#define SIGNAL_SUB(name) \
add_special(ctx, "SIG" #name, SS_SIG ## name, 0);
#include "sshsignals.h"
#undef SIGNAL_MAIN
#undef SIGNAL_SUB
add_special(ctx, NULL, SS_EXITMENU, 0);
}
static const char *ssh_signal_lookup(SessionSpecialCode code)
{
#define CHECK_SUB(name) \
#define SIGNAL_SUB(name) \
if (code == SS_SIG ## name) return #name;
#define CHECK_MAIN(name, desc) CHECK_SUB(name)
#define SIGNAL_MAIN(name, desc) SIGNAL_SUB(name)
#include "sshsignals.h"
#undef SIGNAL_MAIN
#undef SIGNAL_SUB
SIGNAL_LIST(CHECK_MAIN, CHECK_SUB);
/* If none of those clauses matched, fail lookup. */
return NULL;
#undef CHECK_MAIN
#undef CHECK_SUB
}
void mainchan_special_cmd(mainchan *mc, SessionSpecialCode code, int arg)

13
putty.h
View File

@ -211,11 +211,16 @@ typedef enum {
/*
* Send a POSIX-style signal. (Useful in SSH and also pterm.)
*
* We use the master list in sshsignals.h to define these enum
* values, which will come out looking like names of the form
* SS_SIGABRT, SS_SIGINT etc.
*/
SS_SIGABRT, SS_SIGALRM, SS_SIGFPE, SS_SIGHUP, SS_SIGILL,
SS_SIGINT, SS_SIGKILL, SS_SIGPIPE, SS_SIGQUIT, SS_SIGSEGV,
SS_SIGTERM, SS_SIGUSR1, SS_SIGUSR2,
#define SIGNAL_MAIN(name, text) SS_SIG ## name,
#define SIGNAL_SUB(name) SS_SIG ## name,
#include "sshsignals.h"
#undef SIGNAL_MAIN
#undef SIGNAL_SUB
/*
* These aren't really special commands, but they appear in the

53
sshsignals.h Normal file
View File

@ -0,0 +1,53 @@
/*
* List of signal names known to SSH, indicating whether PuTTY's UI
* for special session commands likes to put them in the main specials
* menu or in a submenu (and if the former, what title they have).
*
* This is a separate header file rather than my usual style of a
* parametric list macro, because in this case I need to be able to
* #ifdef out each mode in case it's not defined on a particular
* target system.
*
* If you want only the locally defined signals, #define
* SIGNALS_LOCAL_ONLY before including this header.
*/
#if !defined SIGNALS_LOCAL_ONLY || defined SIGINT
SIGNAL_MAIN(INT, "Interrupt")
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGTERM
SIGNAL_MAIN(TERM, "Terminate")
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGKILL
SIGNAL_MAIN(KILL, "Kill")
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGQUIT
SIGNAL_MAIN(QUIT, "Quit")
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGHUP
SIGNAL_MAIN(HUP, "Hangup")
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGABRT
SIGNAL_SUB(ABRT)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGALRM
SIGNAL_SUB(ALRM)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGFPE
SIGNAL_SUB(FPE)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGILL
SIGNAL_SUB(ILL)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGPIPE
SIGNAL_SUB(PIPE)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGSEGV
SIGNAL_SUB(SEGV)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGUSR1
SIGNAL_SUB(USR1)
#endif
#if !defined SIGNALS_LOCAL_ONLY || defined SIGUSR2
SIGNAL_SUB(USR2)
#endif