Fix a Windows-specific FIXME in signal handling code.
This commit is contained in:
parent
e89d987056
commit
29a7b250e6
|
@ -13,10 +13,15 @@
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
/// Exit status to use. This can be changed with set_exit_status().
|
/// Exit status to use. This can be changed with set_exit_status().
|
||||||
static enum exit_status_type exit_status = E_SUCCESS;
|
static enum exit_status_type exit_status = E_SUCCESS;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
/// exit_status has to be protected with a critical section due to
|
||||||
|
/// how "signal handling" is done on Windows. See signals.c for details.
|
||||||
|
static CRITICAL_SECTION exit_status_cs;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// True if --no-warn is specified. When this is true, we don't set
|
/// True if --no-warn is specified. When this is true, we don't set
|
||||||
/// the exit status to E_WARNING when something worth a warning happens.
|
/// the exit status to E_WARNING when something worth a warning happens.
|
||||||
static bool no_warn = false;
|
static bool no_warn = false;
|
||||||
|
@ -27,9 +32,17 @@ set_exit_status(enum exit_status_type new_status)
|
||||||
{
|
{
|
||||||
assert(new_status == E_WARNING || new_status == E_ERROR);
|
assert(new_status == E_WARNING || new_status == E_ERROR);
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
EnterCriticalSection(&exit_status_cs);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (exit_status != E_ERROR)
|
if (exit_status != E_ERROR)
|
||||||
exit_status = new_status;
|
exit_status = new_status;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
LeaveCriticalSection(&exit_status_cs);
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +142,10 @@ read_name(const args_info *args)
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
InitializeCriticalSection(&exit_status_cs);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set up the progname variable.
|
// Set up the progname variable.
|
||||||
tuklib_progname_init(argv);
|
tuklib_progname_init(argv);
|
||||||
|
|
||||||
|
@ -262,11 +279,24 @@ main(int argc, char **argv)
|
||||||
// of calling tuklib_exit().
|
// of calling tuklib_exit().
|
||||||
signals_exit();
|
signals_exit();
|
||||||
|
|
||||||
|
// Make a local copy of exit_status to keep the Windows code
|
||||||
|
// thread safe. At this point it is fine if we miss the user
|
||||||
|
// pressing C-c and don't set the exit_status to E_ERROR on
|
||||||
|
// Windows.
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
EnterCriticalSection(&exit_status_cs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum exit_status_type es = exit_status;
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
LeaveCriticalSection(&exit_status_cs);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Suppress the exit status indicating a warning if --no-warn
|
// Suppress the exit status indicating a warning if --no-warn
|
||||||
// was specified.
|
// was specified.
|
||||||
if (exit_status == E_WARNING && no_warn)
|
if (es == E_WARNING && no_warn)
|
||||||
exit_status = E_SUCCESS;
|
es = E_SUCCESS;
|
||||||
|
|
||||||
tuklib_exit(exit_status, E_ERROR,
|
tuklib_exit(es, E_ERROR, message_verbosity_get() != V_SILENT);
|
||||||
message_verbosity_get() != V_SILENT);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,11 @@
|
||||||
#include "tuklib_progname.h"
|
#include "tuklib_progname.h"
|
||||||
#include "tuklib_exit.h"
|
#include "tuklib_exit.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef STDIN_FILENO
|
#ifndef STDIN_FILENO
|
||||||
# define STDIN_FILENO (fileno(stdin))
|
# define STDIN_FILENO (fileno(stdin))
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -156,11 +156,14 @@ signals_exit(void)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// While Windows has some very basic signal handling functions as required
|
// While Windows has some very basic signal handling functions as required
|
||||||
// by C89, they are not really used, or so I understood. Instead, we use
|
// by C89, they are not really used, and e.g. SIGINT doesn't work exactly
|
||||||
// SetConsoleCtrlHandler() to catch user pressing C-c.
|
// the way it does on POSIX (Windows creates a new thread for the signal
|
||||||
|
// handler). Instead, we use SetConsoleCtrlHandler() to catch user
|
||||||
#include <windows.h>
|
// pressing C-c, because that seems to be the recommended way to do it.
|
||||||
|
//
|
||||||
|
// NOTE: This doesn't work under MSYS. Trying with SIGINT doesn't work
|
||||||
|
// either even if it appeared to work at first. So test using Windows
|
||||||
|
// console window.
|
||||||
|
|
||||||
static BOOL WINAPI
|
static BOOL WINAPI
|
||||||
signal_handler(DWORD type lzma_attribute((unused)))
|
signal_handler(DWORD type lzma_attribute((unused)))
|
||||||
|
@ -168,9 +171,6 @@ signal_handler(DWORD type lzma_attribute((unused)))
|
||||||
// Since we don't get a signal number which we could raise() at
|
// Since we don't get a signal number which we could raise() at
|
||||||
// signals_exit() like on POSIX, just set the exit status to
|
// signals_exit() like on POSIX, just set the exit status to
|
||||||
// indicate an error, so that we cannot return with zero exit status.
|
// indicate an error, so that we cannot return with zero exit status.
|
||||||
//
|
|
||||||
// FIXME: Since this function runs in its own thread,
|
|
||||||
// set_exit_status() should have a mutex.
|
|
||||||
set_exit_status(E_ERROR);
|
set_exit_status(E_ERROR);
|
||||||
user_abort = true;
|
user_abort = true;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in New Issue