Browse Source

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>
maint
Erik Faye-Lund 12 years ago committed by Junio C Hamano
parent
commit
176478a8bd
  1. 76
      compat/mingw.c
  2. 6
      compat/mingw.h

76
compat/mingw.c

@ -319,6 +319,31 @@ ssize_t mingw_write(int fd, const void *buf, size_t count) @@ -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));
}

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
FILE *mingw_fopen (const char *filename, const char *otype)
{
@ -1546,7 +1571,7 @@ static HANDLE timer_event; @@ -1546,7 +1571,7 @@ static HANDLE timer_event;
static HANDLE timer_thread;
static int timer_interval;
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 thread, ticktack(), is a trivial routine that most of the time
@ -1560,13 +1585,7 @@ static sig_handler_t timer_fn = SIG_DFL; @@ -1560,13 +1585,7 @@ static sig_handler_t timer_fn = SIG_DFL;
static unsigned __stdcall ticktack(void *dummy)
{
while (WaitForSingleObject(timer_event, timer_interval) == WAIT_TIMEOUT) {
if (timer_fn == SIG_DFL) {
if (isatty(STDERR_FILENO))
fputs("Alarm clock\n", stderr);
exit(128 + SIGALRM);
}
if (timer_fn != SIG_IGN)
timer_fn(SIGALRM);
mingw_raise(SIGALRM);
if (one_shot)
break;
}
@ -1657,12 +1676,49 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out) @@ -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 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);
timer_fn = handler;
}

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 char buf[PATH_MAX + 1];

6
compat/mingw.h

@ -179,6 +179,9 @@ int mingw_open (const char *filename, int oflags, ...); @@ -179,6 +179,9 @@ int mingw_open (const char *filename, int oflags, ...);
ssize_t mingw_write(int fd, const void *buf, size_t count);
#define write mingw_write

int mingw_fgetc(FILE *stream);
#define fgetc mingw_fgetc

FILE *mingw_fopen (const char *filename, const char *otype);
#define fopen mingw_fopen

@ -290,6 +293,9 @@ static inline unsigned int git_ntohl(unsigned int x) @@ -290,6 +293,9 @@ static inline unsigned int git_ntohl(unsigned int x)
sig_handler_t mingw_signal(int sig, sig_handler_t handler);
#define signal mingw_signal

int mingw_raise(int sig);
#define raise mingw_raise

/*
* ANSI emulation wrappers
*/

Loading…
Cancel
Save