From 1696d72321492c05bebd1e823de0708c13ec7d72 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Thu, 5 Apr 2012 18:48:46 +0100 Subject: compat/mingw.[ch]: Change return type of exec functions to int The POSIX standard specifies a return type of int for all six exec functions. In addition, all exec functions return -1 on error, and simply do not return on success. However, the current emulation of the exec functions on mingw are declared with a void return type. This would cause a problem should any code attempt to call the exec function in a non-void context. In particular, if an exec function were used in a conditional it would fail to compile. In order to improve the fidelity of the emulation, we change the return type of the mingw_execv[p] functions to int and return -1 on error. Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- compat/mingw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index a0ac487c0c..afc892d6b1 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1003,7 +1003,7 @@ static void mingw_execve(const char *cmd, char *const *argv, char *const *env) } } -void mingw_execvp(const char *cmd, char *const *argv) +int mingw_execvp(const char *cmd, char *const *argv) { char **path = get_path_split(); char *prog = path_lookup(cmd, path, 0); @@ -1015,11 +1015,13 @@ void mingw_execvp(const char *cmd, char *const *argv) errno = ENOENT; free_path_split(path); + return -1; } -void mingw_execv(const char *cmd, char *const *argv) +int mingw_execv(const char *cmd, char *const *argv) { mingw_execve(cmd, argv, environ); + return -1; } int mingw_kill(pid_t pid, int sig) -- cgit v1.2.1 From 84adb641545f4b58f9276adf099f840ea2928e44 Mon Sep 17 00:00:00 2001 From: Johannes Sixt Date: Wed, 17 Oct 2012 09:05:51 +0200 Subject: maybe_flush_or_die: move a too-loose Windows specific error check to compat Commit b2f5e268 (Windows: Work around an oddity when a pipe with no reader is written to) introduced a check for EINVAL after fflush() to fight spurious "Invalid argument" errors on Windows when a pipe was broken. But this check may hide real errors on systems that do not have the this odd behavior. Introduce an fflush wrapper in compat/mingw.* so that the treatment is only applied on Windows. Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index afc892d6b1..4e6383898c 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -335,6 +335,28 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) return freopen(filename, otype, stream); } +#undef fflush +int mingw_fflush(FILE *stream) +{ + int ret = fflush(stream); + + /* + * write() is used behind the scenes of stdio output functions. + * Since git code does not check for errors after each stdio write + * operation, it can happen that write() is called by a later + * stdio function even if an earlier write() call failed. In the + * case of a pipe whose readable end was closed, only the first + * call to write() reports EPIPE on Windows. Subsequent write() + * calls report EINVAL. It is impossible to notice whether this + * fflush invocation triggered such a case, therefore, we have to + * catch all EINVAL errors whole-sale. + */ + if (ret && errno == EINVAL) + errno = EPIPE; + + return ret; +} + /* * The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC. * Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch. -- cgit v1.2.1 From f4f549892ac686a9adcf3cb72bee1a11c0566c88 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 4 Dec 2012 09:10:37 +0100 Subject: mingw: correct exit-code for SIGALRM's SIG_DFL Make sure SIG_DFL for SIGALRM exits with 128 + SIGALRM so other processes can diagnose why it exits. While we're at it, make sure we only write to stderr if it's a terminal, and change the output to match that of Linux. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/mingw.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 4e6383898c..8ae4245648 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1560,8 +1560,11 @@ 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) - die("Alarm"); + 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); if (one_shot) -- cgit v1.2.1 From 176478a8bd028a3877d2be49a1e7a49386c095ce Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 4 Dec 2012 09:10:38 +0100 Subject: 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 Signed-off-by: Junio C Hamano --- compat/mingw.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 10 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 8ae4245648..c749a0259d 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -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; 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; 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) 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]; -- cgit v1.2.1 From f7a4cea25e3ee1c8f27777bc4293dca0210fa573 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 4 Dec 2012 09:10:42 +0100 Subject: mingw: get rid of getpass implementation There's no remaining call-sites, and as pointed out in the previous commit message, it's not quite ideal. So let's just lose it. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/mingw.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index c749a0259d..34724c2781 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1780,21 +1780,6 @@ int link(const char *oldpath, const char *newpath) return 0; } -char *getpass(const char *prompt) -{ - struct strbuf buf = STRBUF_INIT; - - fputs(prompt, stderr); - for (;;) { - char c = _getch(); - if (c == '\r' || c == '\n') - break; - strbuf_addch(&buf, c); - } - fputs("\n", stderr); - return strbuf_detach(&buf, NULL); -} - pid_t waitpid(pid_t pid, int *status, int options) { HANDLE h = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, -- cgit v1.2.1 From a83b2b578c04a2abe33a586ec9c64e75ef5bc819 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Mon, 10 Dec 2012 15:42:27 +0100 Subject: mingw_rmdir: do not prompt for retry when non-empty in ab1a11be ("mingw_rmdir: set errno=ENOTEMPTY when appropriate"), a check was added to prevent us from retrying to delete a directory that is both in use and non-empty. However, this logic was slightly flawed; since we didn't return immediately, we end up falling out of the retry-loop, but right into the prompting-loop. Fix this by setting errno, and guarding the prompting-loop with an errno-check. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/mingw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index 4e6383898c..28527abe22 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -256,6 +256,8 @@ int mingw_rmdir(const char *pathname) while ((ret = rmdir(pathname)) == -1 && tries < ARRAY_SIZE(delay)) { if (!is_file_in_use_error(GetLastError())) + errno = err_win_to_posix(GetLastError()); + if (errno != EACCES) break; if (!is_dir_empty(pathname)) { errno = ENOTEMPTY; @@ -271,7 +273,7 @@ int mingw_rmdir(const char *pathname) Sleep(delay[tries]); tries++; } - while (ret == -1 && is_file_in_use_error(GetLastError()) && + while (ret == -1 && errno == EACCES && is_file_in_use_error(GetLastError()) && ask_yes_no_if_possible("Deletion of directory '%s' failed. " "Should I try again?", pathname)) ret = rmdir(pathname); -- cgit v1.2.1 From 657b35f4bef7d25831607882ed7f1f2ced378eb7 Mon Sep 17 00:00:00 2001 From: Ramsay Jones Date: Sat, 27 Apr 2013 20:18:55 +0100 Subject: compat/mingw.c: Fix some sparse warnings Sparse issues the following warnings: SP compat/mingw.c compat/mingw.c:795:3: warning: symbol 'pinfo_t' was not declared. \ Should it be static? compat/mingw.c:796:16: warning: symbol 'pinfo' was not declared. \ Should it be static? compat/mingw.c:797:18: warning: symbol 'pinfo_cs' was not declared. \ Should it be static? compat/mingw.c:1207:23: warning: Using plain integer as NULL pointer In 'pinfo_t' variable, defined on line 795, seems to have been a mistake (a missing typedef keyword?), so we simply remove it. The 'pinfo' variable does not require more than file scope, so we simply add the static modifier to the declaration. The 'pinfo_cs' variable, in contrast, requires initialisation in the mingw replacement main() function, so we add an extern declaration to the compat/mingw.h header file. The remaining warning is suppressed by replacing the rhs of the pointer assignment with the NULL pointer literal. Signed-off-by: Ramsay Jones Signed-off-by: Junio C Hamano --- compat/mingw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index b673625580..b295e2f6a9 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -841,8 +841,8 @@ struct pinfo_t { struct pinfo_t *next; pid_t pid; HANDLE proc; -} pinfo_t; -struct pinfo_t *pinfo = NULL; +}; +static struct pinfo_t *pinfo = NULL; CRITICAL_SECTION pinfo_cs; static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, @@ -1253,7 +1253,7 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service, else sin->sin_addr.s_addr = INADDR_LOOPBACK; ai->ai_addr = (struct sockaddr *)sin; - ai->ai_next = 0; + ai->ai_next = NULL; return 0; } -- cgit v1.2.1 From a45406585b0a42e38e580baf47b0daf631c5e454 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Mon, 10 Jun 2013 07:48:17 +0200 Subject: mingw: make mingw_signal return the correct handler Returning the SIGALRM handler for SIGINT is not very useful. Signed-off-by: Erik Faye-Lund Signed-off-by: Johannes Sixt Signed-off-by: Junio C Hamano --- compat/mingw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'compat/mingw.c') diff --git a/compat/mingw.c b/compat/mingw.c index b673625580..dae30a081c 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1677,14 +1677,16 @@ int sigaction(int sig, struct sigaction *in, struct sigaction *out) #undef signal sig_handler_t mingw_signal(int sig, sig_handler_t handler) { - sig_handler_t old = timer_fn; + sig_handler_t old; switch (sig) { case SIGALRM: + old = timer_fn; timer_fn = handler; break; case SIGINT: + old = sigint_fn; sigint_fn = handler; break; -- cgit v1.2.1