diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/apple-common-crypto.h | 4 | ||||
-rw-r--r-- | compat/basename.c | 66 | ||||
-rw-r--r-- | compat/bswap.h | 5 | ||||
-rw-r--r-- | compat/hstrerror.c | 2 | ||||
-rw-r--r-- | compat/inet_ntop.c | 6 | ||||
-rw-r--r-- | compat/mingw.c | 63 | ||||
-rw-r--r-- | compat/mingw.h | 25 | ||||
-rw-r--r-- | compat/nedmalloc/nedmalloc.c | 5 | ||||
-rw-r--r-- | compat/poll/poll.c | 16 | ||||
-rw-r--r-- | compat/precompose_utf8.c | 24 | ||||
-rw-r--r-- | compat/precompose_utf8.h | 2 | ||||
-rw-r--r-- | compat/qsort.c | 2 | ||||
-rw-r--r-- | compat/regex/regcomp.c | 6 | ||||
-rw-r--r-- | compat/setenv.c | 2 | ||||
-rw-r--r-- | compat/sha1-chunked.c | 19 | ||||
-rw-r--r-- | compat/sha1-chunked.h | 2 | ||||
-rw-r--r-- | compat/win32/syslog.c | 4 | ||||
-rw-r--r-- | compat/winansi.c | 2 |
18 files changed, 203 insertions, 52 deletions
diff --git a/compat/apple-common-crypto.h b/compat/apple-common-crypto.h index c8b9b0e1a6..d3fb264181 100644 --- a/compat/apple-common-crypto.h +++ b/compat/apple-common-crypto.h @@ -16,6 +16,10 @@ #undef TYPE_BOOL #endif +#ifndef SHA1_MAX_BLOCK_SIZE +#error Using Apple Common Crypto library requires setting SHA1_MAX_BLOCK_SIZE +#endif + #ifdef APPLE_LION_OR_NEWER #define git_CC_error_check(pattern, err) \ do { \ diff --git a/compat/basename.c b/compat/basename.c index d8f8a3c6dc..96bd9533b4 100644 --- a/compat/basename.c +++ b/compat/basename.c @@ -1,15 +1,71 @@ #include "../git-compat-util.h" +#include "../strbuf.h" /* Adapted from libiberty's basename.c. */ char *gitbasename (char *path) { const char *base; - /* Skip over the disk name in MSDOS pathnames. */ - if (has_dos_drive_prefix(path)) - path += 2; + + if (path) + skip_dos_drive_prefix(&path); + + if (!path || !*path) + return "."; + for (base = path; *path; path++) { - if (is_dir_sep(*path)) - base = path + 1; + if (!is_dir_sep(*path)) + continue; + do { + path++; + } while (is_dir_sep(*path)); + if (*path) + base = path; + else + while (--path != base && is_dir_sep(*path)) + *path = '\0'; } return (char *)base; } + +char *gitdirname(char *path) +{ + static struct strbuf buf = STRBUF_INIT; + char *p = path, *slash = NULL, c; + int dos_drive_prefix; + + if (!p) + return "."; + + if ((dos_drive_prefix = skip_dos_drive_prefix(&p)) && !*p) + goto dot; + + /* + * POSIX.1-2001 says dirname("/") should return "/", and dirname("//") + * should return "//", but dirname("///") should return "/" again. + */ + if (is_dir_sep(*p)) { + if (!p[1] || (is_dir_sep(p[1]) && !p[2])) + return path; + slash = ++p; + } + while ((c = *(p++))) + if (is_dir_sep(c)) { + char *tentative = p - 1; + + /* POSIX.1-2001 says to ignore trailing slashes */ + while (is_dir_sep(*p)) + p++; + if (*p) + slash = tentative; + } + + if (slash) { + *slash = '\0'; + return path; + } + +dot: + strbuf_reset(&buf); + strbuf_addf(&buf, "%.*s.", dos_drive_prefix, path); + return buf.buf; +} diff --git a/compat/bswap.h b/compat/bswap.h index 7fed637ed0..d47c003544 100644 --- a/compat/bswap.h +++ b/compat/bswap.h @@ -149,11 +149,12 @@ static inline uint64_t git_bswap64(uint64_t x) * and is faster on architectures with memory alignment issues. */ -#if defined(__i386__) || defined(__x86_64__) || \ +#if !defined(NO_UNALIGNED_LOADS) && ( \ + defined(__i386__) || defined(__x86_64__) || \ defined(_M_IX86) || defined(_M_X64) || \ defined(__ppc__) || defined(__ppc64__) || \ defined(__powerpc__) || defined(__powerpc64__) || \ - defined(__s390__) || defined(__s390x__) + defined(__s390__) || defined(__s390x__)) #define get_be16(p) ntohs(*(unsigned short *)(p)) #define get_be32(p) ntohl(*(unsigned int *)(p)) diff --git a/compat/hstrerror.c b/compat/hstrerror.c index 069c555da4..b85a2fa956 100644 --- a/compat/hstrerror.c +++ b/compat/hstrerror.c @@ -16,6 +16,6 @@ const char *githstrerror(int err) case TRY_AGAIN: return "Non-authoritative \"host not found\", or SERVERFAIL"; } - sprintf(buffer, "Name resolution error %d", err); + snprintf(buffer, sizeof(buffer), "Name resolution error %d", err); return buffer; } diff --git a/compat/inet_ntop.c b/compat/inet_ntop.c index 90b7cc45f3..68307262be 100644 --- a/compat/inet_ntop.c +++ b/compat/inet_ntop.c @@ -53,11 +53,11 @@ inet_ntop4(const u_char *src, char *dst, size_t size) nprinted = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); if (nprinted < 0) return (NULL); /* we assume "errno" was set by "snprintf()" */ - if ((size_t)nprinted > size) { + if ((size_t)nprinted >= size) { errno = ENOSPC; return (NULL); } - strcpy(dst, tmp); + strlcpy(dst, tmp, size); return (dst); } @@ -154,7 +154,7 @@ inet_ntop6(const u_char *src, char *dst, size_t size) errno = ENOSPC; return (NULL); } - strcpy(dst, tmp); + strlcpy(dst, tmp, size); return (dst); } #endif diff --git a/compat/mingw.c b/compat/mingw.c index 70f3191a4f..af56c1fe61 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream) return ret; } +#undef write +ssize_t mingw_write(int fd, const void *buf, size_t len) +{ + ssize_t result = write(fd, buf, len); + + if (result < 0 && errno == EINVAL && buf) { + /* check if fd is a pipe */ + HANDLE h = (HANDLE) _get_osfhandle(fd); + if (GetFileType(h) == FILE_TYPE_PIPE) + errno = EPIPE; + else + errno = EINVAL; + } + + return result; +} + int mingw_access(const char *filename, int mode) { wchar_t wfilename[MAX_PATH]; @@ -681,7 +698,7 @@ int pipe(int filedes[2]) return -1; } filedes[1] = _open_osfhandle((int)h[1], O_NOINHERIT); - if (filedes[0] < 0) { + if (filedes[1] < 0) { close(filedes[0]); CloseHandle(h[1]); return -1; @@ -752,7 +769,7 @@ static const char *quote_arg(const char *arg) return arg; /* insert \ where necessary */ - d = q = xmalloc(len+n+3); + d = q = xmalloc(st_add3(len, n, 3)); *d++ = '"'; while (*arg) { if (*arg == '"') @@ -835,7 +852,7 @@ static char **get_path_split(void) if (!n) return NULL; - path = xmalloc((n+1)*sizeof(char *)); + ALLOC_ARRAY(path, n + 1); p = envpath; i = 0; do { @@ -920,7 +937,7 @@ static wchar_t *make_environment_block(char **deltaenv) i++; /* copy the environment, leaving space for changes */ - tmpenv = xmalloc((size + i) * sizeof(char*)); + ALLOC_ARRAY(tmpenv, size + i); memcpy(tmpenv, environ, size * sizeof(char*)); /* merge supplied environment changes into the temporary environment */ @@ -1011,7 +1028,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen free(quoted); } - wargs = xmalloc((2 * args.len + 1) * sizeof(wchar_t)); + ALLOC_ARRAY(wargs, st_add(st_mult(2, args.len), 1)); xutftowcs(wargs, args.buf, 2 * args.len + 1); strbuf_release(&args); @@ -1110,7 +1127,7 @@ static int try_shell_exec(const char *cmd, char *const *argv) int argc = 0; const char **argv2; while (argv[argc]) argc++; - argv2 = xmalloc(sizeof(*argv) * (argc+1)); + ALLOC_ARRAY(argv2, argc + 1); argv2[0] = (char *)cmd; /* full path to the script file */ memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc); pid = mingw_spawnv(prog, argv2, 1); @@ -1915,28 +1932,31 @@ pid_t waitpid(pid_t pid, int *status, int options) return -1; } +int mingw_skip_dos_drive_prefix(char **path) +{ + int ret = has_dos_drive_prefix(*path); + *path += ret; + return ret; +} + int mingw_offset_1st_component(const char *path) { - int offset = 0; - if (has_dos_drive_prefix(path)) - offset = 2; + char *pos = (char *)path; /* unc paths */ - else if (is_dir_sep(path[0]) && is_dir_sep(path[1])) { - + if (!skip_dos_drive_prefix(&pos) && + is_dir_sep(pos[0]) && is_dir_sep(pos[1])) { /* skip server name */ - char *pos = strpbrk(path + 2, "\\/"); + pos = strpbrk(pos + 2, "\\/"); if (!pos) return 0; /* Error: malformed unc path */ do { pos++; } while (*pos && !is_dir_sep(*pos)); - - offset = pos - path; } - return offset + is_dir_sep(path[offset]); + return pos + is_dir_sep(*pos) - path; } int xutftowcsn(wchar_t *wcs, const char *utfs, size_t wcslen, int utflen) @@ -2128,3 +2148,16 @@ void mingw_startup() /* initialize Unicode console */ winansi_init(); } + +int uname(struct utsname *buf) +{ + unsigned v = (unsigned)GetVersion(); + memset(buf, 0, sizeof(*buf)); + xsnprintf(buf->sysname, sizeof(buf->sysname), "Windows"); + xsnprintf(buf->release, sizeof(buf->release), + "%u.%u", v & 0xff, (v >> 8) & 0xff); + /* assuming NT variants only.. */ + xsnprintf(buf->version, sizeof(buf->version), + "%u", (v >> 16) & 0x7fff); + return 0; +} diff --git a/compat/mingw.h b/compat/mingw.h index 5e499cfb71..a5fb52f977 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -76,6 +76,14 @@ struct itimerval { }; #define ITIMER_REAL 0 +struct utsname { + char sysname[16]; + char nodename[1]; + char release[16]; + char version[16]; + char machine[1]; +}; + /* * sanitize preprocessor namespace polluted by Windows headers defining * macros which collide with git local versions @@ -98,8 +106,6 @@ static inline unsigned int alarm(unsigned int seconds) { return 0; } static inline int fsync(int fd) { return _commit(fd); } -static inline pid_t getppid(void) -{ return 1; } static inline void sync(void) {} static inline uid_t getuid(void) @@ -121,6 +127,12 @@ static inline int sigaddset(sigset_t *set, int signum) #define SIG_UNBLOCK 0 static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { return 0; } +static inline pid_t getppid(void) +{ return 1; } +static inline pid_t getpgid(pid_t pid) +{ return pid == 0 ? getpid() : pid; } +static inline pid_t tcgetpgrp(int fd) +{ return getpid(); } /* * simple adaptors @@ -171,6 +183,7 @@ struct passwd *getpwuid(uid_t uid); int setitimer(int type, struct itimerval *in, struct itimerval *out); int sigaction(int sig, struct sigaction *in, struct sigaction *out); int link(const char *oldpath, const char *newpath); +int uname(struct utsname *buf); /* * replacements of existing functions @@ -197,6 +210,9 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream); int mingw_fflush(FILE *stream); #define fflush mingw_fflush +ssize_t mingw_write(int fd, const void *buf, size_t len); +#define write mingw_write + int mingw_access(const char *filename, int mode); #undef access #define access mingw_access @@ -345,7 +361,10 @@ HANDLE winansi_get_osfhandle(int fd); * git specific compatibility */ -#define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') +#define has_dos_drive_prefix(path) \ + (isalpha(*(path)) && (path)[1] == ':' ? 2 : 0) +int mingw_skip_dos_drive_prefix(char **path); +#define skip_dos_drive_prefix mingw_skip_dos_drive_prefix #define is_dir_sep(c) ((c) == '/' || (c) == '\\') static inline char *mingw_find_last_dir_sep(const char *path) { diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index 609ebba125..a0a16eb1bb 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -957,8 +957,9 @@ char *strdup(const char *s1) { char *s2 = 0; if (s1) { - s2 = malloc(strlen(s1) + 1); - strcpy(s2, s1); + size_t len = strlen(s1) + 1; + s2 = malloc(len); + memcpy(s2, s1, len); } return s2; } diff --git a/compat/poll/poll.c b/compat/poll/poll.c index a9b41d89f4..db4e03ed79 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -446,7 +446,7 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) static HANDLE hEvent; WSANETWORKEVENTS ev; HANDLE h, handle_array[FD_SETSIZE + 2]; - DWORD ret, wait_timeout, nhandles; + DWORD ret, wait_timeout, nhandles, start = 0, elapsed, orig_timeout = 0; fd_set rfds, wfds, xfds; BOOL poll_again; MSG msg; @@ -459,6 +459,12 @@ poll (struct pollfd *pfd, nfds_t nfd, int timeout) return -1; } + if (timeout != INFTIM) + { + orig_timeout = timeout; + start = GetTickCount(); + } + if (!hEvent) hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); @@ -603,7 +609,13 @@ restart: rc++; } - if (!rc && timeout == INFTIM) + if (!rc && orig_timeout && timeout != INFTIM) + { + elapsed = GetTickCount() - start; + timeout = elapsed >= orig_timeout ? 0 : orig_timeout - elapsed; + } + + if (!rc && timeout) { SleepEx (1, TRUE); goto restart; diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 95fe849e42..dfbe6d8408 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -36,24 +36,27 @@ static size_t has_non_ascii(const char *s, size_t maxlen, size_t *strlen_c) } -void probe_utf8_pathname_composition(char *path, int len) +void probe_utf8_pathname_composition(void) { + struct strbuf path = STRBUF_INIT; static const char *auml_nfc = "\xc3\xa4"; static const char *auml_nfd = "\x61\xcc\x88"; int output_fd; if (precomposed_unicode != -1) return; /* We found it defined in the global config, respect it */ - strcpy(path + len, auml_nfc); - output_fd = open(path, O_CREAT|O_EXCL|O_RDWR, 0600); + git_path_buf(&path, "%s", auml_nfc); + output_fd = open(path.buf, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd >= 0) { close(output_fd); - strcpy(path + len, auml_nfd); - precomposed_unicode = access(path, R_OK) ? 0 : 1; - git_config_set("core.precomposeunicode", precomposed_unicode ? "true" : "false"); - strcpy(path + len, auml_nfc); - if (unlink(path)) - die_errno(_("failed to unlink '%s'"), path); + git_path_buf(&path, "%s", auml_nfd); + precomposed_unicode = access(path.buf, R_OK) ? 0 : 1; + git_config_set("core.precomposeunicode", + precomposed_unicode ? "true" : "false"); + git_path_buf(&path, "%s", auml_nfc); + if (unlink(path.buf)) + die_errno(_("failed to unlink '%s'"), path.buf); } + strbuf_release(&path); } @@ -139,9 +142,8 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir) size_t inleft = namelenz; char *outpos = &prec_dir->dirent_nfc->d_name[0]; size_t outsz = prec_dir->dirent_nfc->max_name_len; - size_t cnt; errno = 0; - cnt = iconv(prec_dir->ic_precompose, &cp, &inleft, &outpos, &outsz); + iconv(prec_dir->ic_precompose, &cp, &inleft, &outpos, &outsz); if (errno || inleft) { /* * iconv() failed and errno could be E2BIG, EILSEQ, EINVAL, EBADF diff --git a/compat/precompose_utf8.h b/compat/precompose_utf8.h index 3b73585fc5..a94e7c4342 100644 --- a/compat/precompose_utf8.h +++ b/compat/precompose_utf8.h @@ -27,7 +27,7 @@ typedef struct { } PREC_DIR; void precompose_argv(int argc, const char **argv); -void probe_utf8_pathname_composition(char *, int); +void probe_utf8_pathname_composition(void); PREC_DIR *precompose_utf8_opendir(const char *dirname); struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *dirp); diff --git a/compat/qsort.c b/compat/qsort.c index 9574d537bd..7d071afb70 100644 --- a/compat/qsort.c +++ b/compat/qsort.c @@ -47,7 +47,7 @@ static void msort_with_tmp(void *b, size_t n, size_t s, void git_qsort(void *b, size_t n, size_t s, int (*cmp)(const void *, const void *)) { - const size_t size = n * s; + const size_t size = st_mult(n, s); char buf[1024]; if (size < sizeof(buf)) { diff --git a/compat/regex/regcomp.c b/compat/regex/regcomp.c index 06f3088708..fba5986399 100644 --- a/compat/regex/regcomp.c +++ b/compat/regex/regcomp.c @@ -18,6 +18,8 @@ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <stdint.h> + static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, size_t length, reg_syntax_t syntax); static void re_compile_fastmap_iter (regex_t *bufp, @@ -2577,7 +2579,7 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, old_tree = NULL; if (elem->token.type == SUBEXP) - postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); + postorder (elem, mark_opt_subexp, (void *) (intptr_t) elem->token.opr.idx); tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); if (BE (tree == NULL, 0)) @@ -3806,7 +3808,7 @@ create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node) { - int idx = (int) (long) extra; + int idx = (int) (intptr_t) extra; if (node->token.type == SUBEXP && node->token.opr.idx == idx) node->token.opt_subexp = 1; diff --git a/compat/setenv.c b/compat/setenv.c index fc1439a643..7849f258d2 100644 --- a/compat/setenv.c +++ b/compat/setenv.c @@ -18,7 +18,7 @@ int gitsetenv(const char *name, const char *value, int replace) namelen = strlen(name); valuelen = strlen(value); - envstr = malloc((namelen + valuelen + 2)); + envstr = malloc(st_add3(namelen, valuelen, 2)); if (!envstr) { errno = ENOMEM; return -1; diff --git a/compat/sha1-chunked.c b/compat/sha1-chunked.c new file mode 100644 index 0000000000..6adfcfd540 --- /dev/null +++ b/compat/sha1-chunked.c @@ -0,0 +1,19 @@ +#include "cache.h" + +int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len) +{ + size_t nr; + size_t total = 0; + const char *cdata = (const char*)data; + + while (len) { + nr = len; + if (nr > SHA1_MAX_BLOCK_SIZE) + nr = SHA1_MAX_BLOCK_SIZE; + platform_SHA1_Update(c, cdata, nr); + total += nr; + cdata += nr; + len -= nr; + } + return total; +} diff --git a/compat/sha1-chunked.h b/compat/sha1-chunked.h new file mode 100644 index 0000000000..7b2df28eec --- /dev/null +++ b/compat/sha1-chunked.h @@ -0,0 +1,2 @@ + +int git_SHA1_Update_Chunked(platform_SHA_CTX *c, const void *data, size_t len); diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c index d015e436d5..b905aea31b 100644 --- a/compat/win32/syslog.c +++ b/compat/win32/syslog.c @@ -32,7 +32,7 @@ void syslog(int priority, const char *fmt, ...) return; } - str = malloc(str_len + 1); + str = malloc(st_add(str_len, 1)); if (!str) { warning("malloc failed: '%s'", strerror(errno)); return; @@ -43,7 +43,7 @@ void syslog(int priority, const char *fmt, ...) va_end(ap); while ((pos = strstr(str, "%1")) != NULL) { - str = realloc(str, ++str_len + 1); + str = realloc(str, st_add(++str_len, 1)); if (!str) { warning("realloc failed: '%s'", strerror(errno)); return; diff --git a/compat/winansi.c b/compat/winansi.c index efc5bb3a4b..ceff55bd67 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -539,7 +539,7 @@ void winansi_init(void) return; /* create a named pipe to communicate with the console thread */ - sprintf(name, "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId()); + xsnprintf(name, sizeof(name), "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId()); hwrite = CreateNamedPipe(name, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 1, BUFFER_SIZE, 0, 0, NULL); if (hwrite == INVALID_HANDLE_VALUE) |