mingw: make fgetc raise SIGINT if apropriate
Set a control-handler to prevent the process from terminating, and simulate SIGINT so it can be handled by a signal-handler as usual. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
f4f549892a
commit
176478a8bd
@ -319,6 +319,31 @@ ssize_t mingw_write(int fd, const void *buf, size_t count)
|
|||||||
return write(fd, buf, min(count, 31 * 1024 * 1024));
|
return write(fd, buf, min(count, 31 * 1024 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL WINAPI ctrl_ignore(DWORD type)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef fgetc
|
||||||
|
int mingw_fgetc(FILE *stream)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
if (!isatty(_fileno(stream)))
|
||||||
|
return fgetc(stream);
|
||||||
|
|
||||||
|
SetConsoleCtrlHandler(ctrl_ignore, TRUE);
|
||||||
|
while (1) {
|
||||||
|
ch = fgetc(stream);
|
||||||
|
if (ch != EOF || GetLastError() != ERROR_OPERATION_ABORTED)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Ctrl+C was pressed, simulate SIGINT and retry */
|
||||||
|
mingw_raise(SIGINT);
|
||||||
|
}
|
||||||
|
SetConsoleCtrlHandler(ctrl_ignore, FALSE);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
#undef fopen
|
#undef fopen
|
||||||
FILE *mingw_fopen (const char *filename, const char *otype)
|
FILE *mingw_fopen (const char *filename, const char *otype)
|
||||||
{
|
{
|
||||||
@ -1546,7 +1571,7 @@ static HANDLE timer_event;
|
|||||||
static HANDLE timer_thread;
|
static HANDLE timer_thread;
|
||||||
static int timer_interval;
|
static int timer_interval;
|
||||||
static int one_shot;
|
static int one_shot;
|
||||||
static sig_handler_t timer_fn = SIG_DFL;
|
static sig_handler_t timer_fn = SIG_DFL, sigint_fn = SIG_DFL;
|
||||||
|
|
||||||
/* The timer works like this:
|
/* The timer works like this:
|
||||||
* The thread, ticktack(), is a trivial routine that most of the time
|
* The thread, ticktack(), is a trivial routine that most of the time
|
||||||
@ -1560,13 +1585,7 @@ static sig_handler_t timer_fn = SIG_DFL;
|
|||||||
static unsigned __stdcall ticktack(void *dummy)
|
static unsigned __stdcall ticktack(void *dummy)
|
||||||
{
|
{
|
||||||
while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
|
while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
|
||||||
if (timer_fn == SIG_DFL) {
|
mingw_raise(SIGALRM);
|
||||||
if (isatty(STDERR_FILENO))
|
|
||||||
fputs("Alarm clock\n", stderr);
|
|
||||||
exit(128 + SIGALRM);
|
|
||||||
}
|
|
||||||
if (timer_fn != SIG_IGN)
|
|
||||||
timer_fn(SIGALRM);
|
|
||||||
if (one_shot)
|
if (one_shot)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1657,12 +1676,49 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out)
|
|||||||
sig_handler_t mingw_signal(int sig, sig_handler_t handler)
|
sig_handler_t mingw_signal(int sig, sig_handler_t handler)
|
||||||
{
|
{
|
||||||
sig_handler_t old = timer_fn;
|
sig_handler_t old = timer_fn;
|
||||||
if (sig != SIGALRM)
|
|
||||||
|
switch (sig) {
|
||||||
|
case SIGALRM:
|
||||||
|
timer_fn = handler;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGINT:
|
||||||
|
sigint_fn = handler;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
return signal(sig, handler);
|
return signal(sig, handler);
|
||||||
timer_fn = handler;
|
}
|
||||||
|
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef raise
|
||||||
|
int mingw_raise(int sig)
|
||||||
|
{
|
||||||
|
switch (sig) {
|
||||||
|
case SIGALRM:
|
||||||
|
if (timer_fn == SIG_DFL) {
|
||||||
|
if (isatty(STDERR_FILENO))
|
||||||
|
fputs("Alarm clock\n", stderr);
|
||||||
|
exit(128 + SIGALRM);
|
||||||
|
} else if (timer_fn != SIG_IGN)
|
||||||
|
timer_fn(SIGALRM);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case SIGINT:
|
||||||
|
if (sigint_fn == SIG_DFL)
|
||||||
|
exit(128 + SIGINT);
|
||||||
|
else if (sigint_fn != SIG_IGN)
|
||||||
|
sigint_fn(SIGINT);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return raise(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *make_backslash_path(const char *path)
|
static const char *make_backslash_path(const char *path)
|
||||||
{
|
{
|
||||||
static char buf[PATH_MAX + 1];
|
static char buf[PATH_MAX + 1];
|
||||||
|
@ -179,6 +179,9 @@ int mingw_open (const char *filename, int oflags, ...);
|
|||||||
ssize_t mingw_write(int fd, const void *buf, size_t count);
|
ssize_t mingw_write(int fd, const void *buf, size_t count);
|
||||||
#define write mingw_write
|
#define write mingw_write
|
||||||
|
|
||||||
|
int mingw_fgetc(FILE *stream);
|
||||||
|
#define fgetc mingw_fgetc
|
||||||
|
|
||||||
FILE *mingw_fopen (const char *filename, const char *otype);
|
FILE *mingw_fopen (const char *filename, const char *otype);
|
||||||
#define fopen mingw_fopen
|
#define fopen mingw_fopen
|
||||||
|
|
||||||
@ -290,6 +293,9 @@ static inline unsigned int git_ntohl(unsigned int x)
|
|||||||
sig_handler_t mingw_signal(int sig, sig_handler_t handler);
|
sig_handler_t mingw_signal(int sig, sig_handler_t handler);
|
||||||
#define signal mingw_signal
|
#define signal mingw_signal
|
||||||
|
|
||||||
|
int mingw_raise(int sig);
|
||||||
|
#define raise mingw_raise
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ANSI emulation wrappers
|
* ANSI emulation wrappers
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user