Windows changes. Add handlers for CTRL-C, CTRL-Break, CLOSE, SHUTDOWN and LOGOFF. Please see CHANGES for more details.

git-svn-id: file:///home/jj/hercules.svn/trunk@5703 956126f8-22a0-4046-8f4a-272fa8102e63
This commit is contained in:
Paul Gorlinsky
2010-03-18 20:30:29 +00:00
parent 9f102a49d8
commit 110b48caca
8 changed files with 202 additions and 50 deletions

View File

@@ -1,3 +1,10 @@
18 Mar 2010 Windows changes. Add handlers for CTRL-C, CTRL-Break, CLOSE, SHUTDOWN
and LOGOFF. CTRL-C does not do anything (yet), CTRL-Break simulates the
External Interrupt Key being pressed, CLOSE, SHUTDOWN and LOGOFF all
initate an immediate shutdown of hercules in order to close all files
correctly. An orderly SHUTDOWN is not possible for the GUEST OS because
Windows allows just 5 seconds to complete any cleanup (when using the
cmd terminal interface).
16 Mar 2010 Panel changed to add MIPS and SIOS to bottom status line. MIPS and SIOS
are displayed if window is width >= 104. MIPS is displayed if window
width >= 90. If window width < 90 then neither is displayed.

13
hao.c
View File

@@ -83,7 +83,7 @@ static char ao_msgbuf[LOG_DEFSIZE+1]; /* (plus+1 for NULL termination) */
/*---------------------------------------------------------------------------*/
/* function prototypes */
/*---------------------------------------------------------------------------*/
DLL_EXPORT void hao_initialize(void);
DLL_EXPORT int hao_initialize(void);
DLL_EXPORT void hao_command(char *cmd);
DLL_EXPORT void hao_message(char *buf);
static void hao_clear(void);
@@ -100,9 +100,9 @@ static void* hao_thread(void* dummy);
/* This function is called at system startup by impl.c 'process_rc_file' */
/* It initializes all global variables. */
/*---------------------------------------------------------------------------*/
DLL_EXPORT void hao_initialize(void)
DLL_EXPORT int hao_initialize(void)
{
int i = 0;
int i = 0;
initialize_lock(&ao_lock);
@@ -119,14 +119,19 @@ DLL_EXPORT void hao_initialize(void)
/* initialize message buffer */
memset(ao_msgbuf, 0, sizeof(ao_msgbuf));
/* Start message monitoring thread */
if ( create_thread (&sysblk.haotid, JOINABLE,
hao_thread, NULL, "hao_thread") )
{
WRITEMSG(HHCIN004S, strerror(errno));
i = FALSE;
}
else
i = TRUE;
release_lock(&ao_lock);
return(i);
}
/*---------------------------------------------------------------------------*/

44
hdl.c
View File

@@ -110,29 +110,63 @@ DLL_EXPORT void hdl_shut (void)
{
HDLSHD *shdent;
#if defined( _MSVC_ )
HDLSHD *loggercall;
int logger_flag = 0;
#endif // defined( _MSVC_ )
WRITEMSG(HHCHD900I);
obtain_lock (&hdl_sdlock);
for(shdent = hdl_shdlist; shdent; shdent = hdl_shdlist)
{
WRITEMSG(HHCHD901I,shdent->shdname);
#if defined( _MSVC_ )
if ( strcmp( shdent->shdname, "logger_term" ) == 0 )
{
(shdent->shdcall) (shdent->shdarg);
loggercall = malloc(sizeof(HDLSHD));
loggercall->shdname = shdent->shdname;
loggercall->shdcall = shdent->shdcall;
loggercall->shdarg = shdent->shdarg;
logger_flag = 1;
}
WRITEMSG(HHCHD902I,shdent->shdname);
else
#endif // defined( _MSVC_ )
{
WRITEMSG(HHCHD901I,shdent->shdname);
{
(shdent->shdcall) (shdent->shdarg);
}
WRITEMSG(HHCHD902I,shdent->shdname);
}
/* Remove shutdown call entry to ensure it is called once */
hdl_shdlist = shdent->next;
free(shdent);
}
release_lock (&hdl_sdlock);
#if defined( _MSVC_ )
if ( logger_flag == 1 )
{
if ( sysblk.shutimmed )
/* shutdown of logger is skipped in a Windows Environment
* because we still have messages to write to the log file
*/
WRITEMSG(HHCHD903I, loggercall->shdname);
else
{
WRITEMSG(HHCHD901I, loggercall->shdname);
{
(loggercall->shdcall) (loggercall->shdarg);
}
WRITEMSG(HHCHD902I, loggercall->shdname);
}
}
#endif // defined( _MSVC_ )
WRITEMSG(HHCHD909I);
}
#if defined(OPTION_DYNAMIC_LOAD)

View File

@@ -226,7 +226,7 @@ HPAN_DLL_IMPORT void update_maxrates_hwm(); // (update high-water-mark values)
/* Functions in module hao.c (Hercules Automatic Operator) */
#if defined(OPTION_HAO)
HAO_DLL_IMPORT void hao_initialize(void); /* initialize hao */
HAO_DLL_IMPORT int hao_initialize(void); /* initialize hao */
HAO_DLL_IMPORT void hao_command(char *command); /* process hao command */
HAO_DLL_IMPORT void hao_message(char *message); /* process message */
#endif /* defined(OPTION_HAO) */

View File

@@ -260,14 +260,23 @@ static void do_shutdown_wait()
void do_shutdown()
{
TID tid;
if(is_wait_sigq_pending())
cancel_wait_sigq();
#if defined(_MSVC_)
if ( sysblk.shutimmed )
do_shutdown_now();
else
if(can_signal_quiesce() && !signal_quiesce(0,0))
create_thread(&tid, DETACHED, do_shutdown_wait,
NULL, "do_shutdown_wait");
{
#endif // defined(_MSVC_)
if(is_wait_sigq_pending())
cancel_wait_sigq();
else
do_shutdown_now();
if(can_signal_quiesce() && !signal_quiesce(0,0))
create_thread(&tid, DETACHED, do_shutdown_wait,
NULL, "do_shutdown_wait");
else
do_shutdown_now();
#if defined(_MSVC_)
}
#endif // defined(_MSVC_)
}
/*-------------------------------------------------------------------*/
/* The following 2 routines display an array of 32/64 registers */
@@ -484,8 +493,7 @@ void display_fregs (REGS *regs)
char cpustr[6] = {0}; /* "CPnn " or "" */
if(sysblk.cpus>1)
sprintf(cpustr, "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]),
regs->cpuad);
sprintf(cpustr, "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]), regs->cpuad);
if(regs->CR(0) & CR0_AFP)
logmsg
@@ -1152,8 +1160,7 @@ REGS *regs; /* Copied regs */
if ( sysblk.cpus > 1 )
{
n = sprintf ( buf, "%s%02X: ",
PTYPSTR(sysblk.ptyp[regs->cpuad]), regs->cpuad );
n = sprintf ( buf, "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]), regs->cpuad );
}
else
{
@@ -1304,8 +1311,7 @@ REGS *regs; /* Copied regs */
ACCTYPE_READ));
if ( sysblk.cpus > 1 )
{
logmsg ( "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]),
regs->cpuad );
logmsg ( "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]), regs->cpuad );
}
logmsg ("%s\n", buf);
}
@@ -1327,8 +1333,7 @@ REGS *regs; /* Copied regs */
if ( sysblk.cpus > 1 )
{
logmsg ( "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]),
regs->cpuad );
logmsg ( "%s%02X: ", PTYPSTR(sysblk.ptyp[regs->cpuad]), regs->cpuad );
}
logmsg ("%s\n", buf);
}
@@ -1489,7 +1494,7 @@ int herc_system (char* command)
#define SHELL_CMD_SHIM_PGM "conspawn "
int rc = strlen(SHELL_CMD_SHIM_PGM) + strlen(command) + 1;
int rc = (int)(strlen(SHELL_CMD_SHIM_PGM) + strlen(command) + 1);
char* pszNewCommandLine = malloc( rc );
strlcpy( pszNewCommandLine, SHELL_CMD_SHIM_PGM, rc );
strlcat( pszNewCommandLine, command, rc );

View File

@@ -526,6 +526,9 @@ struct SYSBLK {
inststep:1, /* 1 = Instruction step */
shutdown:1, /* 1 = shutdown requested */
shutfini:1, /* 1 = shutdown complete */
#if defined( _MSVC_ )
shutimmed:1, /* 1 = shutdown req immed */
#endif // defined( _MSVC_ )
main_clear:1, /* 1 = mainstor is cleared */
xpnd_clear:1, /* 1 = xpndstor is cleared */
showregsfirst:1, /* 1 = show regs before inst */

126
impl.c
View File

@@ -82,7 +82,7 @@ DLL_EXPORT void registerLogCallback(LOGCALLBACK lcb)
/*-------------------------------------------------------------------*/
static void sigint_handler (int signo)
{
// logmsg ("config: sigint handler entered for thread %lu\n",/*debug*/
// logmsg ("impl.c: sigint handler entered for thread %lu\n",/*debug*/
// thread_id()); /*debug*/
UNREFERENCED(signo);
@@ -114,7 +114,7 @@ static void sigint_handler (int signo)
/*-------------------------------------------------------------------*/
static void sigterm_handler (int signo)
{
// logmsg ("config: sigterm handler entered for thread %lu\n",/*debug*/
// logmsg ("impl.c: sigterm handler entered for thread %lu\n",/*debug*/
// thread_id()); /*debug*/
UNREFERENCED(signo);
@@ -130,6 +130,82 @@ static void sigterm_handler (int signo)
return;
} /* end function sigterm_handler */
#if defined( _MSVC_ )
/*-------------------------------------------------------------------*/
/* Signal handler for Windows signals */
/*-------------------------------------------------------------------*/
BOOL WINAPI console_ctrl_handler (DWORD signo)
{
int i;
SetConsoleCtrlHandler(console_ctrl_handler, FALSE); // turn handler off while processing
switch ( signo )
{
case CTRL_BREAK_EVENT:
WRITEMSG (HHCIN050I);
OBTAIN_INTLOCK(NULL);
ON_IC_INTKEY;
/* Signal waiting CPUs that an interrupt is pending */
WAKEUP_CPUS_MASK (sysblk.waiting_mask);
RELEASE_INTLOCK(NULL);
SetConsoleCtrlHandler(console_ctrl_handler, TRUE); // reset handler
return TRUE;
break;
case CTRL_C_EVENT:
WRITEMSG(HHCIN022I);
SetConsoleCtrlHandler(console_ctrl_handler, TRUE); // reset handler
return TRUE;
break;
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
case CTRL_LOGOFF_EVENT:
if ( !sysblk.shutdown ) // (system shutdown not initiated)
{
WRITEMSG(HHCIN021I);
sysblk.shutimmed = TRUE;
do_shutdown();
// logmsg("%s(%d): return from shutdown\n", __FILE__, __LINE__ ); /* debug */
for ( i = 0; i < 120; i++ )
{
if ( sysblk.shutdown && sysblk.shutfini )
{
// logmsg("%s(%d): %d shutdown completed\n", /* debug */
// __FILE__, __LINE__, i ); /* debug */
sleep(1);
break;
}
else
{
// logmsg("%s(%d): %d waiting for shutdown to complete\n", /* debug */
// __FILE__, __LINE__, i ); /* debug */
sleep(1);
}
}
socket_deinit();
}
else
{
WRITEMSG(HHCIN023W);
}
usleep(10000);
return FALSE;
break;
default:
return FALSE;
}
} /* end function console_ctrl_handler */
#endif
#if !defined(NO_SIGABEND_HANDLER)
static void *watchdog_thread(void *arg)
@@ -256,7 +332,8 @@ int i; /* (work) */
#if defined(OPTION_HAO)
/* Initialize the Hercules Automatic Operator */
hao_initialize();
if ( !hao_initialize() )
WRITEMSG(HHCIN004S, strerror(errno));
#endif /* defined(OPTION_HAO) */
/* Run the script processor for this file */
@@ -264,8 +341,7 @@ int i; /* (work) */
if (process_script_file(rcname,1) != 0)
if (ENOENT == errno)
if (!is_default_rc)
logmsg(_("HHCPN995E .RC file \"%s\" not found.\n"),
rcname);
WRITEMSG(HHCPN995E, rcname);
// (else error message already issued)
return NULL;
@@ -382,7 +458,7 @@ TID logcbtid; /* RC file thread identifier */
{
usleep(10000); /* (give logger thread time to issue
preceding HHCHD007E message) */
logmsg(_("HHCIN008S DYNGUI.DLL load failed; Hercules terminated.\n"));
WRITEMSG(HHCIN008S);
delayed_exit(1);
}
#endif /* defined(OPTION_DYNAMIC_LOAD) */
@@ -451,26 +527,32 @@ TID logcbtid; /* RC file thread identifier */
/* Register the SIGINT handler */
if ( signal (SIGINT, sigint_handler) == SIG_ERR )
{
logmsg(_("HHCIN001S Cannot register SIGINT handler: %s\n"),
strerror(errno));
WRITEMSG(HHCIN001S, strerror(errno));
delayed_exit(1);
}
/* Register the SIGTERM handler */
if ( signal (SIGTERM, sigterm_handler) == SIG_ERR )
{
logmsg(_("HHCIN009S Cannot register SIGTERM handler: %s\n"),
strerror(errno));
WRITEMSG(HHCIN009S, strerror(errno));
delayed_exit(1);
}
#if defined( _MSVC_ )
/* Register the Window console ctrl handlers */
if (SetConsoleCtrlHandler(console_ctrl_handler, TRUE) == FALSE)
{
WRITEMSG(HHCIN010S, strerror(errno));
delayed_exit(1);
}
#endif
#if defined(HAVE_DECL_SIGPIPE) && HAVE_DECL_SIGPIPE
/* Ignore the SIGPIPE signal, otherwise Hercules may terminate with
Broken Pipe error if the printer driver writes to a closed pipe */
if ( signal (SIGPIPE, SIG_IGN) == SIG_ERR )
{
logmsg(_("HHCIN002E Cannot suppress SIGPIPE signal: %s\n"),
strerror(errno));
WRITEMSG(HHCIN002E, strerror(errno));
}
#endif
@@ -507,9 +589,7 @@ TID logcbtid; /* RC file thread identifier */
|| sigaction(SIGUSR1, &sa, NULL)
|| sigaction(SIGUSR2, &sa, NULL) )
{
logmsg(_("HHCIN003S Cannot register SIGILL/FPE/SEGV/BUS/USR "
"handler: %s\n"),
strerror(errno));
WRITEMSG(HHCIN003S, strerror(errno));
delayed_exit(1);
}
}
@@ -532,8 +612,7 @@ TID logcbtid; /* RC file thread identifier */
if ( create_thread (&sysblk.wdtid, DETACHED,
watchdog_thread, NULL, "watchdog_thread") )
{
logmsg(_("HHCIN004S Cannot create watchdog thread: %s\n"),
strerror(errno));
WRITEMSG(HHCIN005S, strerror(errno));
delayed_exit(1);
}
#endif /*!defined(NO_SIGABEND_HANDLER)*/
@@ -544,8 +623,7 @@ TID logcbtid; /* RC file thread identifier */
if ( create_thread (&sysblk.shrdtid, DETACHED,
shared_server, NULL, "shared_server") )
{
logmsg(_("HHCIN006S Cannot create shared_server thread: %s\n"),
strerror(errno));
WRITEMSG(HHCIN006S, strerror(errno));
delayed_exit(1);
}
@@ -560,8 +638,7 @@ TID logcbtid; /* RC file thread identifier */
*dev->hnd->init, dev, "device connecting thread")
)
{
logmsg(_("HHCIN007S Cannot create %4.4X connection thread: %s\n"),
dev->devnum, strerror(errno));
WRITEMSG(HHCIN007S, dev->devnum, strerror(errno));
delayed_exit(1);
}
}
@@ -616,12 +693,13 @@ TID logcbtid; /* RC file thread identifier */
FishHangAtExit();
#endif
#ifdef _MSVC_
SetConsoleCtrlHandler(console_ctrl_handler, FALSE);
socket_deinit();
#endif
#ifdef DEBUG
fprintf(stdout, _("IMPL EXIT\n"));
#endif
fprintf(stdout, _("HHCIN099I Hercules terminated\n"));
fprintf(stdout, _("HHCIN099I "HHCIN099I"\n"));
fflush(stdout);
usleep(10000);
return 0;
@@ -633,7 +711,7 @@ TID logcbtid; /* RC file thread identifier */
/*-------------------------------------------------------------------*/
DLL_EXPORT void system_cleanup (void)
{
// logmsg("HHCIN950I Begin system cleanup\n");
// WRITEMSG(HHCIN950I);
/*
Currently only called by hdlmain,c's HDL_FINAL_SECTION
after the main 'hercules' module has been unloaded, but
@@ -643,5 +721,5 @@ DLL_EXPORT void system_cleanup (void)
function currently doesn't do anything yet. Once it DOES
something, they should be uncommented.
*/
// logmsg("HHCIN959I System cleanup complete\n");
// WRITEMSG(HHCIN959I);
}

View File

@@ -311,7 +311,6 @@
#define HHCRY002I " Active: %s"
/* hao.c */
#define HHCIN004S "Cannot create HAO thread: (%s)"
#define HHCAO001I "Thread started tid(" TIDPAT "), pid(%d), prio(%d), name(%s)"
#define HHCAO002I "Thread ended tid(" TIDPAT "), pid(%d), prio(%d), name(%s)"
#define HHCAO003I "Firing command: (%s)"
@@ -362,6 +361,7 @@
#define HHCHD900I "Begin shutdown sequence"
#define HHCHD901I "Calling (%s)"
#define HHCHD902I "(%s) complete"
#define HHCHD903I "(%s) skipped during Windows SHUTDOWN immediate"
#define HHCHD909I "Shutdown sequence complete"
#define HHCHD950I "Begin HDL termination sequence"
#define HHCHD951I "Calling module(%s) cleanup routine"
@@ -386,6 +386,26 @@
#define HHCHT013I "Using HTTPROOT directory (%s)"
#define HHCCF066E "Invalid HTTPROOT: (%s): (%s)"
/* impl.c */
#define HHCIN001S "Cannot register SIGINT handler: %s"
#define HHCIN002E "Cannot suppress SIGPIPE signal: %s"
#define HHCIN003S "Cannot register SIGILL/FPE/SEGV/BUS/USR handler: %s"
#define HHCIN004S "Cannot create HAO thread: %s"
#define HHCIN005S "Cannot create watchdog thread: %s"
#define HHCIN006S "Cannot create shared_server thread: %s"
#define HHCIN007S "Cannot create %4.4X connection thread: %s"
#define HHCIN008S "DYNGUI.DLL load failed; Hercules terminated."
#define HHCIN009S "Cannot register SIGTERM handler: %s"
#define HHCIN010S "Cannot register ConsoleCtrl handler: %s"
#define HHCIN021I "CLOSE Event received, SHUTDOWN Immediate starting..."
#define HHCIN022I "Ctrl-C intercepted"
#define HHCIN023W "CLOSE Event received, SHUTDOWN previously requested..."
#define HHCIN050I "Ctrl-Break intercepted. Interrupt Key depressed simulated."
#define HHCIN099I "Hercules terminated"
#define HHCIN950I "Begin system cleanup"
#define HHCIN959I "System cleanup complete"
#define HHCPN995E ".RC file \"%s\" not found."
/* panel.c */
#define HHCPN001I "Thread started tid(" TIDPAT "), pid(%d), prio(%d), name(%s)"
#define HHCPN002S "Cannot obtain keyboard buffer: (%s)"