diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/cygwin.c | 7 | ||||
-rw-r--r-- | compat/fnmatch/fnmatch.c | 27 | ||||
-rw-r--r-- | compat/mingw.c | 114 | ||||
-rw-r--r-- | compat/mingw.h | 11 | ||||
-rw-r--r-- | compat/nedmalloc/malloc.c.h | 6 | ||||
-rw-r--r-- | compat/nedmalloc/nedmalloc.c | 5 | ||||
-rw-r--r-- | compat/obstack.h | 2 | ||||
-rw-r--r-- | compat/precompose_utf8.c | 2 | ||||
-rw-r--r-- | compat/regex/regcomp.c | 4 | ||||
-rw-r--r-- | compat/regex/regex.c | 2 | ||||
-rw-r--r-- | compat/regex/regex_internal.c | 6 | ||||
-rw-r--r-- | compat/strtok_r.c | 61 | ||||
-rw-r--r-- | compat/terminal.c | 129 |
13 files changed, 233 insertions, 143 deletions
diff --git a/compat/cygwin.c b/compat/cygwin.c index dfe9b3084f..5428858875 100644 --- a/compat/cygwin.c +++ b/compat/cygwin.c @@ -1,6 +1,13 @@ #define WIN32_LEAN_AND_MEAN +#ifdef CYGWIN_V15_WIN32API #include "../git-compat-util.h" #include "win32.h" +#else +#include <sys/stat.h> +#include <sys/errno.h> +#include "win32.h" +#include "../git-compat-util.h" +#endif #include "../cache.h" /* to read configuration */ static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts) diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c index 0ff1d273a5..5ef0685135 100644 --- a/compat/fnmatch/fnmatch.c +++ b/compat/fnmatch/fnmatch.c @@ -55,7 +55,8 @@ program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ -#if defined _LIBC || !defined __GNU_LIBRARY__ +#if defined NO_FNMATCH || defined NO_FNMATCH_CASEFOLD || \ + defined _LIBC || !defined __GNU_LIBRARY__ # if defined STDC_HEADERS || !defined isascii @@ -135,9 +136,9 @@ extern int errno; # if !defined HAVE___STRCHRNUL && !defined _LIBC static char * -__strchrnul (s, c) - const char *s; - int c; +__strchrnul (const char *s, int c) + + { char *result = strchr (s, c); if (result == NULL) @@ -159,11 +160,11 @@ static int internal_fnmatch __P ((const char *pattern, const char *string, internal_function; static int internal_function -internal_fnmatch (pattern, string, no_leading_period, flags) - const char *pattern; - const char *string; - int no_leading_period; - int flags; +internal_fnmatch (const char *pattern, const char *string, int no_leading_period, int flags) + + + + { register const char *p = pattern, *n = string; register unsigned char c; @@ -481,10 +482,10 @@ internal_fnmatch (pattern, string, no_leading_period, flags) int -fnmatch (pattern, string, flags) - const char *pattern; - const char *string; - int flags; +fnmatch (const char *pattern, const char *string, int flags) + + + { return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags); } diff --git a/compat/mingw.c b/compat/mingw.c index afc892d6b1..b673625580 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); @@ -319,6 +321,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) { @@ -335,6 +362,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. @@ -1524,7 +1573,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 @@ -1538,10 +1587,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) - die("Alarm"); - if (timer_fn != SIG_IGN) - timer_fn(SIGALRM); + mingw_raise(SIGALRM); if (one_shot) break; } @@ -1632,12 +1678,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]; @@ -1699,21 +1782,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, diff --git a/compat/mingw.h b/compat/mingw.h index 61a652138a..685cd2c3d4 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -55,8 +55,6 @@ struct passwd { char *pw_dir; }; -extern char *getpass(const char *prompt); - typedef void (__cdecl *sig_handler_t)(int); struct sigaction { sig_handler_t sa_handler; @@ -179,12 +177,18 @@ 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 FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream); #define freopen mingw_freopen +int mingw_fflush(FILE *stream); +#define fflush mingw_fflush + char *mingw_getcwd(char *pointer, int len); #define getcwd mingw_getcwd @@ -287,6 +291,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 */ diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h index ff7c2c4fd8..1401a67274 100644 --- a/compat/nedmalloc/malloc.c.h +++ b/compat/nedmalloc/malloc.c.h @@ -4778,7 +4778,7 @@ void* dlmalloc(size_t bytes) { void dlfree(void* mem) { /* - Consolidate freed chunks with preceeding or succeeding bordering + Consolidate freed chunks with preceding or succeeding bordering free chunks, if they exist, and then place in a bin. Intermixed with special cases for top, dv, mmapped chunks, and usage errors. */ @@ -5680,10 +5680,10 @@ History: Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold + * Use ordered bins instead of best-fit threshold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. + * Fix error occurring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index d9a17a8057..91c4e7f27b 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -603,7 +603,10 @@ static NOINLINE mstate FindMSpace(nedpool *p, threadcache *tc, int *lastUsed, si } /* We really want to make sure this goes into memory now but we have to be careful of breaking aliasing rules, so write it twice */ - *((volatile struct malloc_state **) &p->m[end])=p->m[end]=temp; + { + volatile struct malloc_state **_m=(volatile struct malloc_state **) &p->m[end]; + *_m=(p->m[end]=temp); + } ACQUIRE_LOCK(&p->m[end]->mutex); /*printf("Created mspace idx %d\n", end);*/ RELEASE_LOCK(&p->mutex); diff --git a/compat/obstack.h b/compat/obstack.h index d178bd6716..ceb4bdbcdd 100644 --- a/compat/obstack.h +++ b/compat/obstack.h @@ -128,7 +128,7 @@ extern "C" { #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) -/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case +/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case where pointers can be converted to integers, aligned as integers, and converted back again. If PTR_INT_TYPE is narrower than a pointer (e.g., the AS/400), play it safe and compute the alignment diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 8cf59558e1..030174db51 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -134,7 +134,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir) if (prec_dir->ic_precompose == (iconv_t)-1) { die("iconv_open(%s,%s) failed, but needed:\n" " precomposed unicode is not supported.\n" - " If you wnat to use decomposed unicode, run\n" + " If you want to use decomposed unicode, run\n" " \"git config core.precomposeunicode false\"\n", repo_encoding, path_encoding); } else { diff --git a/compat/regex/regcomp.c b/compat/regex/regcomp.c index 8c96ed942c..d0025bd58d 100644 --- a/compat/regex/regcomp.c +++ b/compat/regex/regcomp.c @@ -2095,7 +2095,7 @@ peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) /* Entry point of the parser. Parse the regular expression REGEXP and return the structure tree. - If an error is occured, ERR is set by error code, and return NULL. + If an error has occurred, ERR is set by error code, and return NULL. This function build the following tree, from regular expression <reg_exp>: CAT / \ @@ -3715,7 +3715,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, /* This is intended for the expressions like "a{1,3}". Fetch a number from `input', and return the number. Return -1, if the number field is empty like "{,1}". - Return -2, If an error is occured. */ + Return -2, if an error has occurred. */ static int fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) diff --git a/compat/regex/regex.c b/compat/regex/regex.c index 3dd8dfa01f..6aaae00327 100644 --- a/compat/regex/regex.c +++ b/compat/regex/regex.c @@ -22,7 +22,7 @@ #include "config.h" #endif -/* Make sure noone compiles this code with a C++ compiler. */ +/* Make sure no one compiles this code with a C++ compiler. */ #ifdef __cplusplus # error "This is C code, use a C compiler" #endif diff --git a/compat/regex/regex_internal.c b/compat/regex/regex_internal.c index 193854cf5b..d4121f2f4f 100644 --- a/compat/regex/regex_internal.c +++ b/compat/regex/regex_internal.c @@ -1284,7 +1284,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) /* Insert the new element ELEM to the re_node_set* SET. SET should not already have ELEM. - return -1 if an error is occured, return 1 otherwise. */ + return -1 if an error has occurred, return 1 otherwise. */ static int internal_function @@ -1341,7 +1341,7 @@ re_node_set_insert (re_node_set *set, int elem) /* Insert the new element ELEM to the re_node_set* SET. SET should not already have any element greater than or equal to ELEM. - Return -1 if an error is occured, return 1 otherwise. */ + Return -1 if an error has occurred, return 1 otherwise. */ static int internal_function @@ -1416,7 +1416,7 @@ re_node_set_remove_at (re_node_set *set, int idx) /* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return -1, if an error will be occured. */ + Or return -1, if an error has occurred. */ static int internal_function diff --git a/compat/strtok_r.c b/compat/strtok_r.c deleted file mode 100644 index 7b5d568a96..0000000000 --- a/compat/strtok_r.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Reentrant string tokenizer. Generic version. - Copyright (C) 1991,1996-1999,2001,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include "../git-compat-util.h" - -/* Parse S into tokens separated by characters in DELIM. - If S is NULL, the saved pointer in SAVE_PTR is used as - the next starting point. For example: - char s[] = "-abc-=-def"; - char *sp; - x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" - x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL - x = strtok_r(NULL, "=", &sp); // x = NULL - // s = "abc\0-def\0" -*/ -char * -gitstrtok_r (char *s, const char *delim, char **save_ptr) -{ - char *token; - - if (s == NULL) - s = *save_ptr; - - /* Scan leading delimiters. */ - s += strspn (s, delim); - if (*s == '\0') - { - *save_ptr = s; - return NULL; - } - - /* Find the end of the token. */ - token = s; - s = strpbrk (token, delim); - if (s == NULL) - /* This token finishes the string. */ - *save_ptr = token + strlen (token); - else - { - /* Terminate the token and make *SAVE_PTR point past it. */ - *s = '\0'; - *save_ptr = s + 1; - } - return token; -} diff --git a/compat/terminal.c b/compat/terminal.c index bbb038dd01..9b5e3d1bb8 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -3,8 +3,22 @@ #include "sigchain.h" #include "strbuf.h" +#if defined(HAVE_DEV_TTY) || defined(WIN32) + +static void restore_term(void); + +static void restore_term_on_signal(int sig) +{ + restore_term(); + sigchain_pop(sig); + raise(sig); +} + #ifdef HAVE_DEV_TTY +#define INPUT_PATH "/dev/tty" +#define OUTPUT_PATH "/dev/tty" + static int term_fd = -1; static struct termios old_term; @@ -14,58 +28,109 @@ static void restore_term(void) return; tcsetattr(term_fd, TCSAFLUSH, &old_term); + close(term_fd); term_fd = -1; } -static void restore_term_on_signal(int sig) +static int disable_echo(void) { - restore_term(); - sigchain_pop(sig); - raise(sig); + struct termios t; + + term_fd = open("/dev/tty", O_RDWR); + if (tcgetattr(term_fd, &t) < 0) + goto error; + + old_term = t; + sigchain_push_common(restore_term_on_signal); + + t.c_lflag &= ~ECHO; + if (!tcsetattr(term_fd, TCSAFLUSH, &t)) + return 0; + +error: + close(term_fd); + term_fd = -1; + return -1; +} + +#elif defined(WIN32) + +#define INPUT_PATH "CONIN$" +#define OUTPUT_PATH "CONOUT$" +#define FORCE_TEXT "t" + +static HANDLE hconin = INVALID_HANDLE_VALUE; +static DWORD cmode; + +static void restore_term(void) +{ + if (hconin == INVALID_HANDLE_VALUE) + return; + + SetConsoleMode(hconin, cmode); + CloseHandle(hconin); + hconin = INVALID_HANDLE_VALUE; } +static int disable_echo(void) +{ + hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hconin == INVALID_HANDLE_VALUE) + return -1; + + GetConsoleMode(hconin, &cmode); + sigchain_push_common(restore_term_on_signal); + if (!SetConsoleMode(hconin, cmode & (~ENABLE_ECHO_INPUT))) { + CloseHandle(hconin); + hconin = INVALID_HANDLE_VALUE; + return -1; + } + + return 0; +} + +#endif + +#ifndef FORCE_TEXT +#define FORCE_TEXT +#endif + char *git_terminal_prompt(const char *prompt, int echo) { static struct strbuf buf = STRBUF_INIT; int r; - FILE *fh; + FILE *input_fh, *output_fh; - fh = fopen("/dev/tty", "w+"); - if (!fh) + input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT); + if (!input_fh) return NULL; - if (!echo) { - struct termios t; - - if (tcgetattr(fileno(fh), &t) < 0) { - fclose(fh); - return NULL; - } - - old_term = t; - term_fd = fileno(fh); - sigchain_push_common(restore_term_on_signal); - - t.c_lflag &= ~ECHO; - if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) { - term_fd = -1; - fclose(fh); - return NULL; - } + output_fh = fopen(OUTPUT_PATH, "w" FORCE_TEXT); + if (!output_fh) { + fclose(input_fh); + return NULL; + } + + if (!echo && disable_echo()) { + fclose(input_fh); + fclose(output_fh); + return NULL; } - fputs(prompt, fh); - fflush(fh); + fputs(prompt, output_fh); + fflush(output_fh); - r = strbuf_getline(&buf, fh, '\n'); + r = strbuf_getline(&buf, input_fh, '\n'); if (!echo) { - fseek(fh, SEEK_CUR, 0); - putc('\n', fh); - fflush(fh); + putc('\n', output_fh); + fflush(output_fh); } restore_term(); - fclose(fh); + fclose(input_fh); + fclose(output_fh); if (r == EOF) return NULL; |