fix reported crash of TTY_PERM_INVENT segfaulting
Options processing can be early, even before ttyDisplay is allocated. If we find that TTY_PERM_INVENT initialization is happening too early, just set a marker (iflags.perm_invent_pending) to try again a bit later. The changes in win/share are just to be able to sucessfully reproduce the original issue on Windows. It was easily reproduced on Unix, just by building with TTY_PERM_INVENT in include/config.h and setting OPTIONS=perm_invent in config file.
This commit is contained in:
@@ -2262,6 +2262,9 @@ extern int msgtype_type(const char *, boolean) NONNULLARG1;
|
|||||||
extern void hide_unhide_msgtypes(boolean, int);
|
extern void hide_unhide_msgtypes(boolean, int);
|
||||||
extern void msgtype_free(void);
|
extern void msgtype_free(void);
|
||||||
extern void options_free_window_colors(void);
|
extern void options_free_window_colors(void);
|
||||||
|
#ifdef TTY_PERM_INVENT
|
||||||
|
extern void check_perm_invent_again(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ### pager.c ### */
|
/* ### pager.c ### */
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ struct instance_flags {
|
|||||||
boolean news; /* print news */
|
boolean news; /* print news */
|
||||||
boolean num_pad; /* use numbers for movement commands */
|
boolean num_pad; /* use numbers for movement commands */
|
||||||
boolean perm_invent; /* display persistent inventory window */
|
boolean perm_invent; /* display persistent inventory window */
|
||||||
|
boolean perm_invent_pending; /* need to try again */
|
||||||
boolean renameallowed; /* can change hero name during role selection */
|
boolean renameallowed; /* can change hero name during role selection */
|
||||||
boolean renameinprogress; /* we are changing hero name */
|
boolean renameinprogress; /* we are changing hero name */
|
||||||
boolean sounds; /* master on/off switch for using soundlib */
|
boolean sounds; /* master on/off switch for using soundlib */
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ enum to_core_flags {
|
|||||||
too_small = 0x002,
|
too_small = 0x002,
|
||||||
prohibited = 0x004,
|
prohibited = 0x004,
|
||||||
no_init_done = 0x008,
|
no_init_done = 0x008,
|
||||||
|
too_early = 0x010,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum from_core_requests {
|
enum from_core_requests {
|
||||||
|
|||||||
@@ -720,6 +720,10 @@ init_sound_disp_gamewindows(void)
|
|||||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||||
clear_glyph_buffer();
|
clear_glyph_buffer();
|
||||||
display_nhwindow(WIN_MAP, FALSE);
|
display_nhwindow(WIN_MAP, FALSE);
|
||||||
|
#ifdef TTY_PERM_INVENT
|
||||||
|
if (iflags.perm_invent_pending)
|
||||||
|
check_perm_invent_again();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -6149,6 +6149,12 @@ sync_perminvent(void)
|
|||||||
|| in_perm_invent_toggled) {
|
|| in_perm_invent_toggled) {
|
||||||
wri = ctrl_nhwindow(WIN_INVEN, request_settings, &wri_info);
|
wri = ctrl_nhwindow(WIN_INVEN, request_settings, &wri_info);
|
||||||
if (wri != 0) {
|
if (wri != 0) {
|
||||||
|
if ((wri->tocore.tocore_flags & (too_early)) != 0) {
|
||||||
|
/* don't be too noisy about this as it's really
|
||||||
|
* a startup timing issue. Just set a marker. */
|
||||||
|
iflags.perm_invent_pending = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((wri->tocore.tocore_flags & (too_small | prohibited))
|
if ((wri->tocore.tocore_flags & (too_small | prohibited))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
/* sizes aren't good enough */
|
/* sizes aren't good enough */
|
||||||
|
|||||||
+19
-1
@@ -5384,7 +5384,11 @@ can_set_perm_invent(void)
|
|||||||
iflags.perminv_mode = InvOptOn;
|
iflags.perminv_mode = InvOptOn;
|
||||||
|
|
||||||
#ifdef TTY_PERM_INVENT
|
#ifdef TTY_PERM_INVENT
|
||||||
if (WINDOWPORT(tty) && !go.opt_initial) {
|
if ((WINDOWPORT(tty)
|
||||||
|
#ifdef WIN32
|
||||||
|
|| WINDOWPORT(safestartup)
|
||||||
|
#endif
|
||||||
|
) && !go.opt_initial) {
|
||||||
perm_invent_toggled(FALSE);
|
perm_invent_toggled(FALSE);
|
||||||
/* perm_invent_toggled()
|
/* perm_invent_toggled()
|
||||||
-> sync_perminvent()
|
-> sync_perminvent()
|
||||||
@@ -5401,6 +5405,20 @@ can_set_perm_invent(void)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TTY_PERM_INVENT
|
||||||
|
void
|
||||||
|
check_perm_invent_again(void)
|
||||||
|
{
|
||||||
|
if (iflags.perm_invent_pending) {
|
||||||
|
iflags.perm_invent = FALSE;
|
||||||
|
if (can_set_perm_invent())
|
||||||
|
iflags.perm_invent = TRUE;
|
||||||
|
iflags.perm_invent_pending = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
staticfn int
|
staticfn int
|
||||||
handler_menustyle(void)
|
handler_menustyle(void)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -510,13 +510,23 @@ safe_update_inventory(int arg UNUSED)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32CON
|
||||||
|
extern win_request_info *tty_ctrl_nhwindow(winid window UNUSED,
|
||||||
|
int request UNUSED,
|
||||||
|
win_request_info *wri UNUSED);
|
||||||
|
#endif
|
||||||
|
|
||||||
win_request_info *
|
win_request_info *
|
||||||
safe_ctrl_nhwindow(
|
safe_ctrl_nhwindow(
|
||||||
winid window UNUSED,
|
winid window UNUSED,
|
||||||
int request UNUSED,
|
int request UNUSED,
|
||||||
win_request_info *wri UNUSED)
|
win_request_info *wri UNUSED)
|
||||||
{
|
{
|
||||||
|
#ifdef WIN32CON
|
||||||
|
return (*tty_ctrl_nhwindow)(window, request, wri);
|
||||||
|
#else
|
||||||
return (win_request_info *) 0;
|
return (win_request_info *) 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
|
|||||||
+30
-15
@@ -2861,22 +2861,29 @@ tty_ctrl_nhwindow(
|
|||||||
wri->tocore = zero_tocore;
|
wri->tocore = zero_tocore;
|
||||||
tty_ok = assesstty(ttyinvmode, &offx, &offy, &rows, &cols, &maxcol,
|
tty_ok = assesstty(ttyinvmode, &offx, &offy, &rows, &cols, &maxcol,
|
||||||
&minrow, &maxrow);
|
&minrow, &maxrow);
|
||||||
wri->tocore.needrows = (int) (minrow + 1 + ROWNO + StatusRows());
|
if (!tty_ok && rows == 0 && cols == 0) {
|
||||||
wri->tocore.needcols = (int) tty_perminv_mincol;
|
/* something is terribly wrong, possibly too early in startup */
|
||||||
wri->tocore.haverows = (int) ttyDisplay->rows;
|
wri->tocore.tocore_flags |= too_early;
|
||||||
wri->tocore.havecols = (int) ttyDisplay->cols;
|
|
||||||
if (!tty_ok) {
|
|
||||||
#ifdef RESIZABLE
|
|
||||||
/* terminal isn't big enough right now but player might resize it
|
|
||||||
and then use 'm O' to try to set 'perm_invent' again */
|
|
||||||
wri->tocore.tocore_flags |= too_small;
|
|
||||||
#else
|
|
||||||
wri->tocore.tocore_flags |= prohibited;
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
maxslot = (maxrow - 2) * (!inuse_only ? 2 : 1);
|
wri->tocore.needrows = (int) (minrow + 1 + ROWNO + StatusRows());
|
||||||
wri->tocore.maxslot = maxslot;
|
wri->tocore.needcols = (int) tty_perminv_mincol;
|
||||||
}
|
wri->tocore.haverows = (int) ttyDisplay->rows;
|
||||||
|
wri->tocore.havecols = (int) ttyDisplay->cols;
|
||||||
|
if (!tty_ok) {
|
||||||
|
#ifdef RESIZABLE
|
||||||
|
/* terminal isn't big enough right now but player might
|
||||||
|
* resize it and then use 'm O' to try to set 'perm_invent'
|
||||||
|
* again
|
||||||
|
*/
|
||||||
|
wri->tocore.tocore_flags |= too_small;
|
||||||
|
#else
|
||||||
|
wri->tocore.tocore_flags |= prohibited;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
maxslot = (maxrow - 2) * (!inuse_only ? 2 : 1);
|
||||||
|
wri->tocore.maxslot = maxslot;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* TTY_PERM_INVENT */
|
#endif /* TTY_PERM_INVENT */
|
||||||
break;
|
break;
|
||||||
case set_menu_promptstyle:
|
case set_menu_promptstyle:
|
||||||
@@ -3542,6 +3549,14 @@ assesstty(
|
|||||||
show_gold = (invmode & InvShowGold) != 0 && !inuse_only;
|
show_gold = (invmode & InvShowGold) != 0 && !inuse_only;
|
||||||
int perminv_minrow = tty_perminv_minrow + (show_gold ? 1 : 0);
|
int perminv_minrow = tty_perminv_minrow + (show_gold ? 1 : 0);
|
||||||
|
|
||||||
|
if (!ttyDisplay) {
|
||||||
|
/* too early */
|
||||||
|
*offx = *offy = *rows = *cols = 0;
|
||||||
|
*maxcol = 0;
|
||||||
|
*minrow = *maxrow = 0;
|
||||||
|
return !(*rows < perminv_minrow || *cols < tty_perminv_mincol);
|
||||||
|
}
|
||||||
|
|
||||||
*offx = 0;
|
*offx = 0;
|
||||||
/* topline + map rows + status lines */
|
/* topline + map rows + status lines */
|
||||||
*offy = 1 + ROWNO + StatusRows(); /* 1 + 21 + (2 or 3) */
|
*offy = 1 + ROWNO + StatusRows(); /* 1 + 21 + (2 or 3) */
|
||||||
|
|||||||
Reference in New Issue
Block a user