mirror of
https://git.zap.org.au/git/trader.git
synced 2024-11-03 17:27:29 -05:00
Add a signal handler for SIGINT and SIGTERM
Add a signal handler for SIGINT and SIGTERM, as well as sprinklings of checks to abort_game. Although Ncurses DOES define handlers for SIGINT and SIGTERM, they do not always seem to work correctly under many operating systems.
This commit is contained in:
parent
91eb4d65d8
commit
bbdae69de4
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,11 +21,11 @@ Makefile.in
|
|||||||
/build-aux/install-sh
|
/build-aux/install-sh
|
||||||
/build-aux/missing
|
/build-aux/missing
|
||||||
|
|
||||||
|
/build-aux/snippet/_Noreturn.h
|
||||||
/build-aux/snippet/arg-nonnull.h
|
/build-aux/snippet/arg-nonnull.h
|
||||||
/build-aux/snippet/c++defs.h
|
/build-aux/snippet/c++defs.h
|
||||||
/build-aux/snippet/unused-parameter.h
|
/build-aux/snippet/unused-parameter.h
|
||||||
/build-aux/snippet/warn-on-use.h
|
/build-aux/snippet/warn-on-use.h
|
||||||
/build-aux/snippet/_Noreturn.h
|
|
||||||
|
|
||||||
/po/POTFILES
|
/po/POTFILES
|
||||||
/po/remove-potcdate.sed
|
/po/remove-potcdate.sed
|
||||||
|
21
lib/.gitignore
vendored
21
lib/.gitignore
vendored
@ -1,17 +1,17 @@
|
|||||||
Makefile.am
|
Makefile.am
|
||||||
alloca.in.h
|
alloca.in.h
|
||||||
asnprintf.c
|
asnprintf.c
|
||||||
ctype.in.h
|
|
||||||
c-ctype.c
|
c-ctype.c
|
||||||
c-ctype.h
|
c-ctype.h
|
||||||
c-strcase.h
|
c-strcase.h
|
||||||
c-strcasecmp.c
|
c-strcasecmp.c
|
||||||
c-strncasecmp.c
|
c-strncasecmp.c
|
||||||
|
ctype.in.h
|
||||||
dosname.h
|
dosname.h
|
||||||
errno.in.h
|
errno.in.h
|
||||||
|
float+.h
|
||||||
float.c
|
float.c
|
||||||
float.in.h
|
float.in.h
|
||||||
float+.h
|
|
||||||
fprintf.c
|
fprintf.c
|
||||||
fpucw.h
|
fpucw.h
|
||||||
frexp.c
|
frexp.c
|
||||||
@ -34,19 +34,18 @@ iconv_open-osf.gperf
|
|||||||
iconv_open-solaris.gperf
|
iconv_open-solaris.gperf
|
||||||
iconv_open.c
|
iconv_open.c
|
||||||
isnan.c
|
isnan.c
|
||||||
isnand.c
|
|
||||||
isnand-nolibm.h
|
isnand-nolibm.h
|
||||||
isnanf.c
|
isnand.c
|
||||||
isnanf-nolibm.h
|
isnanf-nolibm.h
|
||||||
isnanl.c
|
isnanf.c
|
||||||
isnanl-nolibm.h
|
isnanl-nolibm.h
|
||||||
|
isnanl.c
|
||||||
langinfo.in.h
|
langinfo.in.h
|
||||||
locale.in.h
|
locale.in.h
|
||||||
malloc.c
|
malloc.c
|
||||||
math.in.h
|
math.in.h
|
||||||
memchr.c
|
memchr.c
|
||||||
memchr.valgrind
|
memchr.valgrind
|
||||||
printf.c
|
|
||||||
printf-args.c
|
printf-args.c
|
||||||
printf-args.h
|
printf-args.h
|
||||||
printf-frexp.c
|
printf-frexp.c
|
||||||
@ -55,9 +54,14 @@ printf-frexpl.c
|
|||||||
printf-frexpl.h
|
printf-frexpl.h
|
||||||
printf-parse.c
|
printf-parse.c
|
||||||
printf-parse.h
|
printf-parse.h
|
||||||
|
printf.c
|
||||||
|
sig-handler.h
|
||||||
|
sigaction.c
|
||||||
|
signal.in.h
|
||||||
signbitd.c
|
signbitd.c
|
||||||
signbitf.c
|
signbitf.c
|
||||||
signbitl.c
|
signbitl.c
|
||||||
|
sigprocmask.c
|
||||||
size_max.h
|
size_max.h
|
||||||
snprintf.c
|
snprintf.c
|
||||||
stat.c
|
stat.c
|
||||||
@ -65,16 +69,16 @@ stdarg.in.h
|
|||||||
stdbool.in.h
|
stdbool.in.h
|
||||||
stddef.in.h
|
stddef.in.h
|
||||||
stdint.in.h
|
stdint.in.h
|
||||||
stdio.in.h
|
|
||||||
stdio-impl.h
|
stdio-impl.h
|
||||||
|
stdio.in.h
|
||||||
stdlib.in.h
|
stdlib.in.h
|
||||||
|
str-two-way.h
|
||||||
strdup.c
|
strdup.c
|
||||||
striconv.c
|
striconv.c
|
||||||
striconv.h
|
striconv.h
|
||||||
string.in.h
|
string.in.h
|
||||||
strncat.c
|
strncat.c
|
||||||
strstr.c
|
strstr.c
|
||||||
str-two-way.h
|
|
||||||
sys_stat.in.h
|
sys_stat.in.h
|
||||||
sys_time.in.h
|
sys_time.in.h
|
||||||
time.in.h
|
time.in.h
|
||||||
@ -103,6 +107,7 @@ iconv_open-solaris.h
|
|||||||
langinfo.h
|
langinfo.h
|
||||||
locale.h
|
locale.h
|
||||||
math.h
|
math.h
|
||||||
|
signal.h
|
||||||
stdio.h
|
stdio.h
|
||||||
stdlib.h
|
stdlib.h
|
||||||
string.h
|
string.h
|
||||||
|
15
m4/.gitignore
vendored
15
m4/.gitignore
vendored
@ -19,8 +19,8 @@ frexpl.m4
|
|||||||
getopt.m4
|
getopt.m4
|
||||||
gettext.m4
|
gettext.m4
|
||||||
gettimeofday.m4
|
gettimeofday.m4
|
||||||
glibc21.m4
|
|
||||||
glibc2.m4
|
glibc2.m4
|
||||||
|
glibc21.m4
|
||||||
gnulib-common.m4
|
gnulib-common.m4
|
||||||
gnulib-comp.m4
|
gnulib-comp.m4
|
||||||
gnulib-tool.m4
|
gnulib-tool.m4
|
||||||
@ -30,8 +30,8 @@ iconv_open.m4
|
|||||||
include_next.m4
|
include_next.m4
|
||||||
inline.m4
|
inline.m4
|
||||||
intdiv0.m4
|
intdiv0.m4
|
||||||
intldir.m4
|
|
||||||
intl.m4
|
intl.m4
|
||||||
|
intldir.m4
|
||||||
intlmacosx.m4
|
intlmacosx.m4
|
||||||
intmax.m4
|
intmax.m4
|
||||||
intmax_t.m4
|
intmax_t.m4
|
||||||
@ -59,16 +59,19 @@ multiarch.m4
|
|||||||
nls.m4
|
nls.m4
|
||||||
nocrash.m4
|
nocrash.m4
|
||||||
po.m4
|
po.m4
|
||||||
printf.m4
|
|
||||||
printf-frexp.m4
|
printf-frexp.m4
|
||||||
printf-frexpl.m4
|
printf-frexpl.m4
|
||||||
printf-posix.m4
|
|
||||||
printf-posix-rpl.m4
|
printf-posix-rpl.m4
|
||||||
|
printf-posix.m4
|
||||||
|
printf.m4
|
||||||
progtest.m4
|
progtest.m4
|
||||||
|
sigaction.m4
|
||||||
|
signal_h.m4
|
||||||
|
signalblocking.m4
|
||||||
signbit.m4
|
signbit.m4
|
||||||
size_max.m4
|
size_max.m4
|
||||||
snprintf.m4
|
|
||||||
snprintf-posix.m4
|
snprintf-posix.m4
|
||||||
|
snprintf.m4
|
||||||
stat.m4
|
stat.m4
|
||||||
stdarg.m4
|
stdarg.m4
|
||||||
stdbool.m4
|
stdbool.m4
|
||||||
@ -90,8 +93,8 @@ unistd_h.m4
|
|||||||
vasnprintf.m4
|
vasnprintf.m4
|
||||||
vfprintf-posix.m4
|
vfprintf-posix.m4
|
||||||
visibility.m4
|
visibility.m4
|
||||||
vsnprintf.m4
|
|
||||||
vsnprintf-posix.m4
|
vsnprintf-posix.m4
|
||||||
|
vsnprintf.m4
|
||||||
warn-on-use.m4
|
warn-on-use.m4
|
||||||
wchar_h.m4
|
wchar_h.m4
|
||||||
wchar_t.m4
|
wchar_t.m4
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
|
|
||||||
# Specification in the form of a command-line invocation:
|
# Specification in the form of a command-line invocation:
|
||||||
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl assert config-h ctype fprintf-posix getopt-gnu gettext gettext-h gettimeofday langinfo locale printf-posix snprintf-posix stat stdarg stdbool stdio strdup-posix striconv string strncat strstr sys_stat sys_time unistd vfprintf-posix vsnprintf-posix
|
# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl assert config-h ctype fprintf-posix getopt-gnu gettext gettext-h gettimeofday langinfo locale printf-posix sigaction signal snprintf-posix stat stdarg stdbool stdio strdup-posix striconv string strncat strstr sys_stat sys_time unistd vfprintf-posix vsnprintf-posix
|
||||||
|
|
||||||
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
# Specification in the form of a few gnulib-tool.m4 macro invocations:
|
||||||
gl_LOCAL_DIR([])
|
gl_LOCAL_DIR([])
|
||||||
@ -31,6 +31,8 @@ gl_MODULES([
|
|||||||
langinfo
|
langinfo
|
||||||
locale
|
locale
|
||||||
printf-posix
|
printf-posix
|
||||||
|
sigaction
|
||||||
|
signal
|
||||||
snprintf-posix
|
snprintf-posix
|
||||||
stat
|
stat
|
||||||
stdarg
|
stdarg
|
||||||
|
15
src/exch.c
15
src/exch.c
@ -211,6 +211,9 @@ void exchange_stock (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,6 +259,9 @@ void visit_bank (void)
|
|||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
buf = malloc(BUFSIZE);
|
buf = malloc(BUFSIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
err_exit_nomem();
|
err_exit_nomem();
|
||||||
@ -328,6 +334,9 @@ void visit_bank (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,6 +491,9 @@ void trade_shares (int num, bool *bid_used)
|
|||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(num >= 0 && num < MAX_COMPANIES);
|
assert(num >= 0 && num < MAX_COMPANIES);
|
||||||
assert(company[num].on_map);
|
assert(company[num].on_map);
|
||||||
|
|
||||||
@ -581,6 +593,9 @@ void trade_shares (int num, bool *bid_used)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
src/game.c
42
src/game.c
@ -126,6 +126,9 @@ void init_game (void)
|
|||||||
while (number_players == 0) {
|
while (number_players == 0) {
|
||||||
int choice = ask_number_players();
|
int choice = ask_number_players();
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (choice == ERR) {
|
if (choice == ERR) {
|
||||||
abort_game = true;
|
abort_game = true;
|
||||||
return;
|
return;
|
||||||
@ -133,6 +136,9 @@ void init_game (void)
|
|||||||
} else if (choice == 0) {
|
} else if (choice == 0) {
|
||||||
choice = ask_game_number();
|
choice = ask_game_number();
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (choice != ERR) {
|
if (choice != ERR) {
|
||||||
game_num = choice;
|
game_num = choice;
|
||||||
|
|
||||||
@ -162,6 +168,9 @@ void init_game (void)
|
|||||||
|
|
||||||
ask_player_names();
|
ask_player_names();
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
deltxwin(); // "Number of players" window
|
deltxwin(); // "Number of players" window
|
||||||
txrefresh();
|
txrefresh();
|
||||||
|
|
||||||
@ -221,7 +230,6 @@ void init_game (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
quit_selected = false;
|
quit_selected = false;
|
||||||
abort_game = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -277,6 +285,9 @@ static int ask_number_players (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return ERR;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,6 +344,9 @@ int ask_game_number (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return ERR;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,6 +362,9 @@ int ask_game_number (void)
|
|||||||
|
|
||||||
void ask_player_names (void)
|
void ask_player_names (void)
|
||||||
{
|
{
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (number_players == 1) {
|
if (number_players == 1) {
|
||||||
// Ask for the player's name
|
// Ask for the player's name
|
||||||
|
|
||||||
@ -362,6 +379,9 @@ void ask_player_names (void)
|
|||||||
while (true) {
|
while (true) {
|
||||||
int ret = gettxstr(curwin, &player[0].name, NULL, false,
|
int ret = gettxstr(curwin, &player[0].name, NULL, false,
|
||||||
2, x, w, attr_input_field);
|
2, x, w, attr_input_field);
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ret == OK && strlen(player[0].name) != 0) {
|
if (ret == OK && strlen(player[0].name) != 0) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -371,7 +391,7 @@ void ask_player_names (void)
|
|||||||
|
|
||||||
newtxwin(5, 44, 6, WCENTER, true, attr_normal_window);
|
newtxwin(5, 44, 6, WCENTER, true, attr_normal_window);
|
||||||
mvwaddstr(curwin, 2, 2, "Do you need any instructions?");
|
mvwaddstr(curwin, 2, 2, "Do you need any instructions?");
|
||||||
if (answer_yesno(curwin, attr_keycode)) {
|
if (answer_yesno(curwin, attr_keycode) == true) {
|
||||||
show_help();
|
show_help();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +452,9 @@ void ask_player_names (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ERR:
|
case ERR:
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -468,7 +491,7 @@ void ask_player_names (void)
|
|||||||
|
|
||||||
newtxwin(5, 50, 6, WCENTER, true, attr_normal_window);
|
newtxwin(5, 50, 6, WCENTER, true, attr_normal_window);
|
||||||
mvwaddstr(curwin, 2, 2, "Does any player need instructions?");
|
mvwaddstr(curwin, 2, 2, "Does any player need instructions?");
|
||||||
if (answer_yesno(curwin, attr_keycode)) {
|
if (answer_yesno(curwin, attr_keycode) == true) {
|
||||||
show_help();
|
show_help();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,10 +510,8 @@ void end_game (void)
|
|||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
|
||||||
if (abort_game) {
|
if (abort_game)
|
||||||
// init_game() was cancelled by user
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
buf = malloc(BUFSIZE);
|
buf = malloc(BUFSIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
@ -510,6 +531,9 @@ void end_game (void)
|
|||||||
show_status(i);
|
show_status(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (number_players == 1) {
|
if (number_players == 1) {
|
||||||
l_strfmon(buf, BUFSIZE, "%1n", total_value(0));
|
l_strfmon(buf, BUFSIZE, "%1n", total_value(0));
|
||||||
|
|
||||||
@ -571,6 +595,9 @@ void show_map (bool closewin)
|
|||||||
int n, x, y;
|
int n, x, y;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
newtxwin(MAX_Y + 4, WIN_COLS, 1, WCENTER, true, attr_map_window);
|
newtxwin(MAX_Y + 4, WIN_COLS, 1, WCENTER, true, attr_map_window);
|
||||||
|
|
||||||
// Draw various borders
|
// Draw various borders
|
||||||
@ -670,6 +697,9 @@ void show_status (int num)
|
|||||||
int i, line;
|
int i, line;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
assert(num >= 0 && num < number_players);
|
assert(num >= 0 && num < number_players);
|
||||||
|
|
||||||
newtxwin(MAX_COMPANIES + 15, WIN_COLS, 1, WCENTER, true,
|
newtxwin(MAX_COMPANIES + 15, WIN_COLS, 1, WCENTER, true,
|
||||||
|
@ -84,12 +84,13 @@ bool game_loaded = false; // True if game was loaded from disk
|
|||||||
int game_num = 0; // Game number (1-9)
|
int game_num = 0; // Game number (1-9)
|
||||||
|
|
||||||
bool quit_selected = false; // Is a player trying to quit the game?
|
bool quit_selected = false; // Is a player trying to quit the game?
|
||||||
bool abort_game = false; // Abort game without declaring winner?
|
|
||||||
|
|
||||||
bool option_no_color = false; // True if --no-color was specified
|
bool option_no_color = false; // True if --no-color was specified
|
||||||
bool option_dont_encrypt = false; // True if --dont-encrypt was specified
|
bool option_dont_encrypt = false; // True if --dont-encrypt was specified
|
||||||
int option_max_turn = 0; // Max. turns if --max-turn was specified
|
int option_max_turn = 0; // Max. turns if --max-turn was specified
|
||||||
|
|
||||||
|
volatile sig_atomic_t abort_game = false; // Abort game as quickly as possible?
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
// End of file
|
// End of file
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -195,11 +196,12 @@ extern bool game_loaded; // True if game was loaded from disk
|
|||||||
extern int game_num; // Game number (1-9)
|
extern int game_num; // Game number (1-9)
|
||||||
|
|
||||||
extern bool quit_selected; // Is a player trying to quit the game?
|
extern bool quit_selected; // Is a player trying to quit the game?
|
||||||
extern bool abort_game; // Abort game without declaring winner?
|
|
||||||
|
|
||||||
extern bool option_no_color; // True if --no-color was specified
|
extern bool option_no_color; // True if --no-color was specified
|
||||||
extern bool option_dont_encrypt; // True if --dont-encrypt was specified
|
extern bool option_dont_encrypt; // True if --dont-encrypt was specified
|
||||||
extern int option_max_turn; // Max. turns if --max-turn was specified
|
extern int option_max_turn; // Max. turns if --max-turn was specified
|
||||||
|
|
||||||
|
extern volatile sig_atomic_t abort_game; // Abort game as quickly as possible?
|
||||||
|
|
||||||
|
|
||||||
#endif /* included_GLOBALS_H */
|
#endif /* included_GLOBALS_H */
|
||||||
|
@ -162,6 +162,9 @@ void show_help (void)
|
|||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
// Count how many pages appear in the help text
|
// Count how many pages appear in the help text
|
||||||
for (numpages = 0; help_text[numpages] != NULL; numpages++)
|
for (numpages = 0; help_text[numpages] != NULL; numpages++)
|
||||||
;
|
;
|
||||||
@ -356,6 +359,9 @@ void show_help (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
curpage++;
|
curpage++;
|
||||||
done = (curpage == numpages);
|
done = (curpage == numpages);
|
||||||
}
|
}
|
||||||
|
53
src/intf.c
53
src/intf.c
@ -101,6 +101,7 @@ txwin_t *firstwin = NULL; // First (bottom-most) txwin structure
|
|||||||
Parameters: dest - Destination buffer of size BUFSIZE
|
Parameters: dest - Destination buffer of size BUFSIZE
|
||||||
src - Source buffer of size BUFSIZE
|
src - Source buffer of size BUFSIZE
|
||||||
isfloat - True if src contains a floating point number
|
isfloat - True if src contains a floating point number
|
||||||
|
Returns: (nothing)
|
||||||
|
|
||||||
This helper function copies the string in src to dest, performing
|
This helper function copies the string in src to dest, performing
|
||||||
certain fixups along the way. In particular, thousands separators are
|
certain fixups along the way. In particular, thousands separators are
|
||||||
@ -114,6 +115,17 @@ static void txinput_fixup (char *restrict dest, char *restrict src,
|
|||||||
bool isfloat);
|
bool isfloat);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: sigterm_handler - Handle program termination signals
|
||||||
|
Parameters: sig - Signal number
|
||||||
|
Returns: (nothing)
|
||||||
|
|
||||||
|
This function handles termination signals (like SIGINT and SIGTERM) by
|
||||||
|
setting the global variable abort_game to true.
|
||||||
|
*/
|
||||||
|
static void sigterm_handler (int sig);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Basic text input/output function definitions *
|
* Basic text input/output function definitions *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@ -126,6 +138,22 @@ static void txinput_fixup (char *restrict dest, char *restrict src,
|
|||||||
|
|
||||||
void init_screen (void)
|
void init_screen (void)
|
||||||
{
|
{
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
|
|
||||||
|
// Initialise signal handlers
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sa.sa_handler = sigterm_handler;
|
||||||
|
|
||||||
|
if (sigaction(SIGINT, &sa, NULL) == -1) {
|
||||||
|
errno_exit("sigaction(SIGINT)");
|
||||||
|
}
|
||||||
|
if (sigaction(SIGTERM, &sa, NULL) == -1) {
|
||||||
|
errno_exit("sigaction(SIGTERM)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the screen
|
||||||
initscr();
|
initscr();
|
||||||
|
|
||||||
if (COLS < MIN_COLS || LINES < MIN_LINES) {
|
if (COLS < MIN_COLS || LINES < MIN_LINES) {
|
||||||
@ -259,6 +287,21 @@ void end_screen (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
// sigterm_handler: Handle program termination signals
|
||||||
|
|
||||||
|
void sigterm_handler (int sig)
|
||||||
|
{
|
||||||
|
/* Note that sigterm_handler() simply sets a volatile variable
|
||||||
|
instead of directly terminating, as functions like endwin() and
|
||||||
|
end_screen() are NOT reentrant. A side-effect of doing this,
|
||||||
|
however, is that the main program needs to have abort_game checks
|
||||||
|
scattered all over it. */
|
||||||
|
|
||||||
|
abort_game = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
// newtxwin: Create a new window, inserted into window stack
|
// newtxwin: Create a new window, inserted into window stack
|
||||||
|
|
||||||
@ -642,8 +685,10 @@ int gettxline (WINDOW *win, char *buf, int bufsize, bool *restrict modified,
|
|||||||
|
|
||||||
key = wgetch(win);
|
key = wgetch(win);
|
||||||
if (key == ERR) {
|
if (key == ERR) {
|
||||||
// Do nothing on ERR
|
if (abort_game) {
|
||||||
;
|
ret = ERR;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
} else if ((key == KEY_DEFAULTVAL1 || key == KEY_DEFAULTVAL2)
|
} else if ((key == KEY_DEFAULTVAL1 || key == KEY_DEFAULTVAL2)
|
||||||
&& defaultval != NULL && len == 0) {
|
&& defaultval != NULL && len == 0) {
|
||||||
// Initialise buffer with the default value
|
// Initialise buffer with the default value
|
||||||
@ -1447,7 +1492,7 @@ int gettxlong (WINDOW *win, long int *restrict result, long int min,
|
|||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
// answer_yesno: Wait for a Yes/No answer
|
// answer_yesno: Wait for a Yes/No answer
|
||||||
|
|
||||||
bool answer_yesno (WINDOW *win, chtype attr_keys)
|
int answer_yesno (WINDOW *win, chtype attr_keys)
|
||||||
{
|
{
|
||||||
int key;
|
int key;
|
||||||
bool done;
|
bool done;
|
||||||
@ -1474,6 +1519,8 @@ bool answer_yesno (WINDOW *win, chtype attr_keys)
|
|||||||
|
|
||||||
if (key == 'Y' || key == 'N') {
|
if (key == 'Y' || key == 'N') {
|
||||||
done = true;
|
done = true;
|
||||||
|
} else if (abort_game) {
|
||||||
|
return ERR;
|
||||||
} else {
|
} else {
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
|
11
src/intf.h
11
src/intf.h
@ -534,16 +534,17 @@ extern int gettxlong (WINDOW *win, long int *restrict result, long int min,
|
|||||||
Function: answer_yesno - Wait for a Yes/No answer
|
Function: answer_yesno - Wait for a Yes/No answer
|
||||||
Parameters: win - Window to use (should be curwin)
|
Parameters: win - Window to use (should be curwin)
|
||||||
attr_keys - Window rendition to use for key choices
|
attr_keys - Window rendition to use for key choices
|
||||||
Returns: bool - True if Yes was selected, false if No
|
Returns: int - 1 if Yes was selected, 0 if No, ERR if error
|
||||||
|
|
||||||
This function prompts the user by printing " [Y/N] " using appropriate
|
This function prompts the user by printing " [Y/N] " using appropriate
|
||||||
character renditions ("Y" and "N" in attr_keys, the rest in the current
|
character renditions ("Y" and "N" in attr_keys, the rest in the current
|
||||||
rendition), then waits for the user to press either "Y" (for Yes) or
|
rendition), then waits for the user to press either "Y" (for Yes) or
|
||||||
"N" (for No) on the keyboard, then prints the answer using A_BOLD.
|
"N" (for No) on the keyboard, then prints the answer using A_BOLD. If
|
||||||
True is returned if "Y" was selected, false if "N". Note that the
|
"Y" was selected, 1 is returned, if "N", 0 is returned. ERR is
|
||||||
cursor becomes invisible after calling this function.
|
returned if abort_game becomes true. Note that the cursor becomes
|
||||||
|
invisible after calling this function.
|
||||||
*/
|
*/
|
||||||
extern bool answer_yesno (WINDOW *win, chtype attr_keys);
|
extern int answer_yesno (WINDOW *win, chtype attr_keys);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
52
src/move.c
52
src/move.c
@ -159,6 +159,9 @@ void select_moves (void)
|
|||||||
bool unique;
|
bool unique;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
// How many empty spaces are there in the galaxy map?
|
// How many empty spaces are there in the galaxy map?
|
||||||
count = 0;
|
count = 0;
|
||||||
for (x = 0; x < MAX_X; x++) {
|
for (x = 0; x < MAX_X; x++) {
|
||||||
@ -318,6 +321,9 @@ selection_t get_move (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return SEL_QUIT;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,10 +341,13 @@ selection_t get_move (void)
|
|||||||
|
|
||||||
// Ask the player to confirm their choice
|
// Ask the player to confirm their choice
|
||||||
mvwaddstr(curwin, 2, 22, "Are you sure?");
|
mvwaddstr(curwin, 2, 22, "Are you sure?");
|
||||||
if (! answer_yesno(curwin, attr_keycode)) {
|
if (answer_yesno(curwin, attr_keycode) != true) {
|
||||||
selection = SEL_NONE;
|
selection = SEL_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return SEL_QUIT;
|
||||||
|
|
||||||
// Save the game if required
|
// Save the game if required
|
||||||
if (selection == SEL_SAVE) {
|
if (selection == SEL_SAVE) {
|
||||||
bool saved = false;
|
bool saved = false;
|
||||||
@ -397,6 +406,9 @@ selection_t get_move (void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (abort_game)
|
||||||
|
return SEL_QUIT;
|
||||||
|
|
||||||
beep();
|
beep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -444,12 +456,13 @@ selection_t get_move (void)
|
|||||||
|
|
||||||
void process_move (selection_t selection)
|
void process_move (selection_t selection)
|
||||||
{
|
{
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (selection == SEL_QUIT) {
|
if (selection == SEL_QUIT) {
|
||||||
// The players want to end the game
|
// The players want to end the game
|
||||||
quit_selected = true;
|
quit_selected = true;
|
||||||
}
|
|
||||||
|
|
||||||
if (quit_selected || abort_game) {
|
|
||||||
deltxwin(); // "Select move" window
|
deltxwin(); // "Select move" window
|
||||||
deltxwin(); // Galaxy map window
|
deltxwin(); // Galaxy map window
|
||||||
txrefresh();
|
txrefresh();
|
||||||
@ -495,6 +508,9 @@ void process_move (selection_t selection)
|
|||||||
assign_vals(x, y, left, right, up, down);
|
assign_vals(x, y, left, right, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_MAP_COMPANY(left) && IS_MAP_COMPANY(up)
|
if (IS_MAP_COMPANY(left) && IS_MAP_COMPANY(up)
|
||||||
&& left != up) {
|
&& left != up) {
|
||||||
galaxy_map[x][y] = left;
|
galaxy_map[x][y] = left;
|
||||||
@ -502,6 +518,9 @@ void process_move (selection_t selection)
|
|||||||
assign_vals(x, y, left, right, up, down);
|
assign_vals(x, y, left, right, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_MAP_COMPANY(left) && IS_MAP_COMPANY(down)
|
if (IS_MAP_COMPANY(left) && IS_MAP_COMPANY(down)
|
||||||
&& left != down) {
|
&& left != down) {
|
||||||
galaxy_map[x][y] = left;
|
galaxy_map[x][y] = left;
|
||||||
@ -509,6 +528,9 @@ void process_move (selection_t selection)
|
|||||||
assign_vals(x, y, left, right, up, down);
|
assign_vals(x, y, left, right, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_MAP_COMPANY(right) && IS_MAP_COMPANY(up)
|
if (IS_MAP_COMPANY(right) && IS_MAP_COMPANY(up)
|
||||||
&& right != up) {
|
&& right != up) {
|
||||||
galaxy_map[x][y] = right;
|
galaxy_map[x][y] = right;
|
||||||
@ -516,6 +538,9 @@ void process_move (selection_t selection)
|
|||||||
assign_vals(x, y, left, right, up, down);
|
assign_vals(x, y, left, right, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_MAP_COMPANY(right) && IS_MAP_COMPANY(down)
|
if (IS_MAP_COMPANY(right) && IS_MAP_COMPANY(down)
|
||||||
&& right != down) {
|
&& right != down) {
|
||||||
galaxy_map[x][y] = right;
|
galaxy_map[x][y] = right;
|
||||||
@ -523,6 +548,9 @@ void process_move (selection_t selection)
|
|||||||
assign_vals(x, y, left, right, up, down);
|
assign_vals(x, y, left, right, up, down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_MAP_COMPANY(up) && IS_MAP_COMPANY(down)
|
if (IS_MAP_COMPANY(up) && IS_MAP_COMPANY(down)
|
||||||
&& up != down) {
|
&& up != down) {
|
||||||
galaxy_map[x][y] = up;
|
galaxy_map[x][y] = up;
|
||||||
@ -531,6 +559,9 @@ void process_move (selection_t selection)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
// See if an existing company can be expanded
|
// See if an existing company can be expanded
|
||||||
nearby = (IS_MAP_COMPANY(left) ? left :
|
nearby = (IS_MAP_COMPANY(left) ? left :
|
||||||
(IS_MAP_COMPANY(right) ? right :
|
(IS_MAP_COMPANY(right) ? right :
|
||||||
@ -596,6 +627,9 @@ void next_player (void)
|
|||||||
bool all_out;
|
bool all_out;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
all_out = true;
|
all_out = true;
|
||||||
for (i = 0; i < number_players; i++) {
|
for (i = 0; i < number_players; i++) {
|
||||||
if (player[i].in_game) {
|
if (player[i].in_game) {
|
||||||
@ -636,6 +670,9 @@ void bankrupt_player (bool forced)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
/* It would be nice if we had functions that would do word-wrapping
|
/* It would be nice if we had functions that would do word-wrapping
|
||||||
for us automatically! */
|
for us automatically! */
|
||||||
|
|
||||||
@ -790,6 +827,9 @@ void merge_companies (map_val_t a, map_val_t b)
|
|||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
buf = malloc(BUFSIZE);
|
buf = malloc(BUFSIZE);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
err_exit_nomem();
|
err_exit_nomem();
|
||||||
@ -952,6 +992,9 @@ void adjust_values (void)
|
|||||||
int which;
|
int which;
|
||||||
|
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
// Declare a company bankrupt!
|
// Declare a company bankrupt!
|
||||||
if (randf() > (1.0 - COMPANY_BANKRUPTCY)) {
|
if (randf() > (1.0 - COMPANY_BANKRUPTCY)) {
|
||||||
which = randi(MAX_COMPANIES);
|
which = randi(MAX_COMPANIES);
|
||||||
@ -1085,6 +1128,9 @@ void adjust_values (void)
|
|||||||
interest_rate /= randf() + INTEREST_RATE_DIVIDER;
|
interest_rate /= randf() + INTEREST_RATE_DIVIDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abort_game)
|
||||||
|
return;
|
||||||
|
|
||||||
// Calculate current player's debt
|
// Calculate current player's debt
|
||||||
player[current_player].debt *= interest_rate + 1.0;
|
player[current_player].debt *= interest_rate + 1.0;
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
// Headers defined by X/Open Single Unix Specification v4
|
// Headers defined by X/Open Single Unix Specification v4
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <monetary.h>
|
#include <monetary.h>
|
||||||
|
@ -180,7 +180,7 @@ int main (int argc, char *argv[])
|
|||||||
|
|
||||||
// Finish up...
|
// Finish up...
|
||||||
end_program();
|
end_program();
|
||||||
return EXIT_SUCCESS;
|
return abort_game ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user