tty SIGHUP

We still don't know whether this will be of any help against
disconnected processes that hog the CPU instead of exiting, but I
don't think it imposes significant overhead on ones which aren't
disconnected.  Install it before it suffers from more bit rot.
This commit is contained in:
PatR
2018-12-15 16:24:59 -08:00
parent 27a515a4cc
commit 594cb5f226
2 changed files with 64 additions and 7 deletions

View File

@@ -354,6 +354,8 @@ tty: significant optimizations for performance and per field rendering
tty: use WC2_FLUSH_STATUS to buffer changes until BL_FLUSH is received tty: use WC2_FLUSH_STATUS to buffer changes until BL_FLUSH is received
tty: support BL_RESET in status_update to force an update to all status fields tty: support BL_RESET in status_update to force an update to all status fields
tty: stop hitpointbar from jumping to 100% health at zero hit points tty: stop hitpointbar from jumping to 100% health at zero hit points
tty: try harder to prevent a disconnected terminal (SIGHUP) from running amok
and using up all available CPU time
MacOSX: add curses window port MacOSX: add curses window port
MacOSX: add Xcode project to sys/unixNetHack.xcodeproj MacOSX: add Xcode project to sys/unixNetHack.xcodeproj
MacOSX: add Xcode supporting files README.xcode and XCode.xcconfig MacOSX: add Xcode supporting files README.xcode and XCode.xcconfig

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 wintty.c $NHDT-Date: 1544842261 2018/12/15 02:51:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.188 $ */ /* NetHack 3.6 wintty.c $NHDT-Date: 1544919891 2018/12/16 00:24:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.189 $ */
/* Copyright (c) David Cohrs, 1991 */ /* Copyright (c) David Cohrs, 1991 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -45,6 +45,33 @@ extern short glyph2tile[];
#define AVTC_INLINE_SYNC 3 #define AVTC_INLINE_SYNC 3
#endif #endif
#ifdef HANGUP_HANDLING
/*
* NetHack's core switches to a dummy windowing interface when it
* detects SIGHUP, but that's no help for any interface routine which
* is already in progress at the time, and there have been reports of
* runaway disconnected processes which use up all available CPU time.
* HUPSKIP() and HUPSKIP_RETURN(x) are used to try to cut them off so
* that they return to the core instead attempting more terminal I/O.
*/
#define HUPSKIP() \
do { \
if (program_state.done_hup) { \
morc = '\033'; \
return; \
} \
} while (0)
/* morc=ESC - in case we bypass xwaitforspace() which sets that */
#define HUPSKIP_RESULT(RES) \
do { \
if (program_state.done_hup) \
return (RES); \
} while (0)
#else /* !HANGUP_HANDLING */
#define HUPSKIP() /*empty*/
#define HUPSKIP_RESULT(RES) /*empty*/
#endif /* ?HANGUP_HANDLING */
extern char mapped_menu_cmds[]; /* from options.c */ extern char mapped_menu_cmds[]; /* from options.c */
/* this is only needed until tty_status_* routines are written */ /* this is only needed until tty_status_* routines are written */
@@ -208,6 +235,7 @@ void
print_vt_code(i, c, d) print_vt_code(i, c, d)
int i, c, d; int i, c, d;
{ {
HUPSKIP();
if (iflags.vt_tiledata) { if (iflags.vt_tiledata) {
if (c >= 0) { if (c >= 0) {
if (i == AVTC_SELECT_WINDOW) { if (i == AVTC_SELECT_WINDOW) {
@@ -1170,8 +1198,7 @@ tty_askname()
bail("Giving up after 10 tries.\n"); bail("Giving up after 10 tries.\n");
tty_curs(BASE_WINDOW, 1, wins[BASE_WINDOW]->cury - 1); tty_curs(BASE_WINDOW, 1, wins[BASE_WINDOW]->cury - 1);
tty_putstr(BASE_WINDOW, 0, "Enter a name for your character..."); tty_putstr(BASE_WINDOW, 0, "Enter a name for your character...");
/* erase previous prompt (in case of ESC after partial response) /* erase previous prompt (in case of ESC after partial response) */
*/
tty_curs(BASE_WINDOW, 1, wins[BASE_WINDOW]->cury), cl_end(); tty_curs(BASE_WINDOW, 1, wins[BASE_WINDOW]->cury), cl_end();
} }
tty_putstr(BASE_WINDOW, 0, who_are_you); tty_putstr(BASE_WINDOW, 0, who_are_you);
@@ -1261,6 +1288,7 @@ tty_get_nh_event()
STATIC_OVL void STATIC_OVL void
getret() getret()
{ {
HUPSKIP();
xputs("\n"); xputs("\n");
if (flags.standout) if (flags.standout)
standoutbeg(); standoutbeg();
@@ -1516,6 +1544,7 @@ winid window;
{ {
register struct WinDesc *cw = 0; register struct WinDesc *cw = 0;
HUPSKIP();
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
panic(winpanicstr, window); panic(winpanicstr, window);
ttyDisplay->lastwin = window; ttyDisplay->lastwin = window;
@@ -1602,6 +1631,7 @@ const char *s; /* valid responses */
const char *prompt = cw->morestr ? cw->morestr : defmorestr; const char *prompt = cw->morestr ? cw->morestr : defmorestr;
int offset = (cw->type == NHW_TEXT) ? 1 : 2; int offset = (cw->type == NHW_TEXT) ? 1 : 2;
HUPSKIP();
tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + offset, tty_curs(BASE_WINDOW, (int) ttyDisplay->curx + offset,
(int) ttyDisplay->cury); (int) ttyDisplay->cury);
if (flags.standout) if (flags.standout)
@@ -1622,6 +1652,7 @@ tty_menu_item *item;
{ {
char ch = item->selected ? (item->count == -1L ? '+' : '#') : '-'; char ch = item->selected ? (item->count == -1L ? '+' : '#') : '-';
HUPSKIP();
tty_curs(window, 4, lineno); tty_curs(window, 4, lineno);
term_start_attr(item->attr); term_start_attr(item->attr);
(void) putchar(ch); (void) putchar(ch);
@@ -1789,6 +1820,7 @@ struct WinDesc *cw;
/* loop until finished */ /* loop until finished */
while (!finished) { while (!finished) {
HUPSKIP();
if (reset_count) { if (reset_count) {
counting = FALSE; counting = FALSE;
count = 0; count = 0;
@@ -2117,6 +2149,7 @@ struct WinDesc *cw;
register char *cp; register char *cp;
for (n = 0, i = 0; i < cw->maxrow; i++) { for (n = 0, i = 0; i < cw->maxrow; i++) {
HUPSKIP();
if (!cw->offx && (n + cw->offy == ttyDisplay->rows - 1)) { if (!cw->offx && (n + cw->offy == ttyDisplay->rows - 1)) {
tty_curs(window, 1, n); tty_curs(window, 1, n);
cl_end(); cl_end();
@@ -2183,6 +2216,7 @@ boolean blocking; /* with ttys, all windows are blocking */
register struct WinDesc *cw = 0; register struct WinDesc *cw = 0;
short s_maxcol; short s_maxcol;
HUPSKIP();
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
panic(winpanicstr, window); panic(winpanicstr, window);
if (cw->flags & WIN_CANCELLED) if (cw->flags & WIN_CANCELLED)
@@ -2275,6 +2309,7 @@ winid window;
{ {
register struct WinDesc *cw = 0; register struct WinDesc *cw = 0;
HUPSKIP();
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
panic(winpanicstr, window); panic(winpanicstr, window);
@@ -2345,6 +2380,7 @@ register int x, y; /* not xchar: perhaps xchar is unsigned and
int cx = ttyDisplay->curx; int cx = ttyDisplay->curx;
int cy = ttyDisplay->cury; int cy = ttyDisplay->cury;
HUPSKIP();
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
panic(winpanicstr, window); panic(winpanicstr, window);
ttyDisplay->lastwin = window; ttyDisplay->lastwin = window;
@@ -2359,6 +2395,7 @@ register int x, y; /* not xchar: perhaps xchar is unsigned and
#ifdef DEBUG #ifdef DEBUG
if (x < 0 || y < 0 || y >= cw->rows || x > cw->cols) { if (x < 0 || y < 0 || y >= cw->rows || x > cw->cols) {
const char *s = "[unknown type]"; const char *s = "[unknown type]";
switch (cw->type) { switch (cw->type) {
case NHW_MESSAGE: case NHW_MESSAGE:
s = "[topl window]"; s = "[topl window]";
@@ -2442,6 +2479,7 @@ char ch;
{ {
register struct WinDesc *cw = 0; register struct WinDesc *cw = 0;
HUPSKIP();
if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0) if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
panic(winpanicstr, window); panic(winpanicstr, window);
@@ -2511,6 +2549,7 @@ const char *str;
register long j; register long j;
#endif #endif
HUPSKIP();
/* Assume there's a real problem if the window is missing -- /* Assume there's a real problem if the window is missing --
* probably a panic message * probably a panic message
*/ */
@@ -2780,6 +2819,7 @@ boolean preselected; /* item is marked as selected */
const char *newstr; const char *newstr;
char buf[4 + BUFSZ]; char buf[4 + BUFSZ];
HUPSKIP();
if (str == (const char *) 0) if (str == (const char *) 0)
return; return;
@@ -2991,6 +3031,7 @@ char let;
int how; int how;
const char *mesg; const char *mesg;
{ {
HUPSKIP();
/* "menu" without selection; use ordinary pline, no more() */ /* "menu" without selection; use ordinary pline, no more() */
if (how == PICK_NONE) { if (how == PICK_NONE) {
pline("%s", mesg); pline("%s", mesg);
@@ -3026,12 +3067,14 @@ tty_update_inventory()
void void
tty_mark_synch() tty_mark_synch()
{ {
HUPSKIP();
(void) fflush(stdout); (void) fflush(stdout);
} }
void void
tty_wait_synch() tty_wait_synch()
{ {
HUPSKIP();
/* we just need to make sure all windows are synch'd */ /* we just need to make sure all windows are synch'd */
if (!ttyDisplay || ttyDisplay->rawprint) { if (!ttyDisplay || ttyDisplay->rawprint) {
getret(); getret();
@@ -3061,6 +3104,7 @@ register int xmin, ymax;
register int y; register int y;
register struct WinDesc *cw = wins[WIN_MAP]; register struct WinDesc *cw = wins[WIN_MAP];
HUPSKIP();
#if 0 /* this optimization is not valuable enough to justify #if 0 /* this optimization is not valuable enough to justify
abusing core internals... */ abusing core internals... */
if (u.uswallow) { /* Can be done more efficiently */ if (u.uswallow) { /* Can be done more efficiently */
@@ -3109,6 +3153,7 @@ register int xmin, ymax;
void void
end_glyphout() end_glyphout()
{ {
HUPSKIP();
#if defined(ASCIIGRAPH) && !defined(NO_TERMS) #if defined(ASCIIGRAPH) && !defined(NO_TERMS)
if (GFlag) { if (GFlag) {
GFlag = FALSE; GFlag = FALSE;
@@ -3130,6 +3175,7 @@ int in_ch;
{ {
register char ch = (char) in_ch; register char ch = (char) in_ch;
HUPSKIP();
#if defined(ASCIIGRAPH) && !defined(NO_TERMS) #if defined(ASCIIGRAPH) && !defined(NO_TERMS)
if (SYMHANDLING(H_IBM) || iflags.eight_bit_tty) { if (SYMHANDLING(H_IBM) || iflags.eight_bit_tty) {
/* IBM-compatible displays don't need other stuff */ /* IBM-compatible displays don't need other stuff */
@@ -3174,6 +3220,7 @@ int x, y;
extern boolean restoring; extern boolean restoring;
int oldx = clipx, oldy = clipy; int oldx = clipx, oldy = clipy;
HUPSKIP();
if (!clipping) if (!clipping)
return; return;
if (x < clipx + 5) { if (x < clipx + 5) {
@@ -3218,6 +3265,7 @@ int bkglyph UNUSED;
int color; int color;
unsigned special; unsigned special;
HUPSKIP();
#ifdef CLIPPING #ifdef CLIPPING
if (clipping) { if (clipping) {
if (x <= clipx || y < clipy || x >= clipxmax || y >= clipymax) if (x <= clipx || y < clipy || x >= clipxmax || y >= clipymax)
@@ -3288,6 +3336,7 @@ void
tty_raw_print(str) tty_raw_print(str)
const char *str; const char *str;
{ {
HUPSKIP();
if (ttyDisplay) if (ttyDisplay)
ttyDisplay->rawprint++; ttyDisplay->rawprint++;
print_vt_code2(AVTC_SELECT_WINDOW, NHW_BASE); print_vt_code2(AVTC_SELECT_WINDOW, NHW_BASE);
@@ -3303,6 +3352,7 @@ void
tty_raw_print_bold(str) tty_raw_print_bold(str)
const char *str; const char *str;
{ {
HUPSKIP();
if (ttyDisplay) if (ttyDisplay)
ttyDisplay->rawprint++; ttyDisplay->rawprint++;
print_vt_code2(AVTC_SELECT_WINDOW, NHW_BASE); print_vt_code2(AVTC_SELECT_WINDOW, NHW_BASE);
@@ -3335,6 +3385,7 @@ tty_nhgetch()
char nestbuf; char nestbuf;
#endif #endif
HUPSKIP_RESULT('\033');
print_vt_code1(AVTC_INLINE_SYNC); print_vt_code1(AVTC_INLINE_SYNC);
(void) fflush(stdout); (void) fflush(stdout);
/* Note: if raw_print() and wait_synch() get called to report terminal /* Note: if raw_print() and wait_synch() get called to report terminal
@@ -3366,6 +3417,7 @@ tty_nhgetch()
{ {
/* hack to force output of the window select code */ /* hack to force output of the window select code */
int tmp = vt_tile_current_window; int tmp = vt_tile_current_window;
vt_tile_current_window++; vt_tile_current_window++;
print_vt_code2(AVTC_SELECT_WINDOW, tmp); print_vt_code2(AVTC_SELECT_WINDOW, tmp);
} }
@@ -3383,8 +3435,10 @@ int
tty_nh_poskey(x, y, mod) tty_nh_poskey(x, y, mod)
int *x, *y, *mod; int *x, *y, *mod;
{ {
#if defined(WIN32CON)
int i; int i;
HUPSKIP_RESULT('\033');
#if defined(WIN32CON)
(void) fflush(stdout); (void) fflush(stdout);
/* Note: if raw_print() and wait_synch() get called to report terminal /* Note: if raw_print() and wait_synch() get called to report terminal
* initialization problems, then wins[] and ttyDisplay might not be * initialization problems, then wins[] and ttyDisplay might not be
@@ -3398,14 +3452,14 @@ int *x, *y, *mod;
i = '\033'; /* map NUL or EOF to ESC, nethack doesn't expect either */ i = '\033'; /* map NUL or EOF to ESC, nethack doesn't expect either */
if (ttyDisplay && ttyDisplay->toplin == 1) if (ttyDisplay && ttyDisplay->toplin == 1)
ttyDisplay->toplin = 2; ttyDisplay->toplin = 2;
return i;
#else /* !WIN32CON */ #else /* !WIN32CON */
nhUse(x); nhUse(x);
nhUse(y); nhUse(y);
nhUse(mod); nhUse(mod);
return tty_nhgetch(); i = tty_nhgetch();
#endif /* ?WIN32CON */ #endif /* ?WIN32CON */
return i;
} }
void void
@@ -4182,6 +4236,7 @@ render_status(VOID_ARGS)
} }
for (row = 0; row < 2; ++row) { for (row = 0; row < 2; ++row) {
HUPSKIP();
curs(WIN_STATUS, 1, row); curs(WIN_STATUS, 1, row);
for (i = 0; fieldorder[row][i] != BL_FLUSH; ++i) { for (i = 0; fieldorder[row][i] != BL_FLUSH; ++i) {
int idx = fieldorder[row][i]; int idx = fieldorder[row][i];
@@ -4359,7 +4414,7 @@ render_status(VOID_ARGS)
tty_putstatusfield(nullfield, " ", x++, y); tty_putstatusfield(nullfield, " ", x++, y);
} }
} }
/* reset .redraw, .dirty, .padright now that they've been rendered */ /* reset .redraw, .dirty, .padright now that they're rendered */
tty_status[NOW][idx].dirty = FALSE; tty_status[NOW][idx].dirty = FALSE;
tty_status[NOW][idx].redraw = FALSE; tty_status[NOW][idx].redraw = FALSE;
tty_status[NOW][idx].last_on_row = FALSE; tty_status[NOW][idx].last_on_row = FALSE;