diff options
Diffstat (limited to 'compat')
-rw-r--r-- | compat/bswap.h | 2 | ||||
-rw-r--r-- | compat/mingw.c | 47 | ||||
-rw-r--r-- | compat/mingw.h | 4 | ||||
-rw-r--r-- | compat/vcbuild/include/termios.h | 1 | ||||
-rw-r--r-- | compat/win32mmap.c | 6 |
5 files changed, 51 insertions, 9 deletions
diff --git a/compat/bswap.h b/compat/bswap.h index f3b8c44181..54756dbb05 100644 --- a/compat/bswap.h +++ b/compat/bswap.h @@ -17,6 +17,8 @@ static inline uint32_t default_swab32(uint32_t val) ((val & 0x000000ff) << 24)); } +#undef bswap32 + #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) #define bswap32(x) ({ \ diff --git a/compat/mingw.c b/compat/mingw.c index c5bfb39b39..9a8e336582 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -140,6 +140,23 @@ int mingw_open (const char *filename, int oflags, ...) return fd; } +#undef write +ssize_t mingw_write(int fd, const void *buf, size_t count) +{ + /* + * While write() calls to a file on a local disk are translated + * into WriteFile() calls with a maximum size of 64KB on Windows + * XP and 256KB on Vista, no such cap is placed on writes to + * files over the network on Windows XP. Unfortunately, there + * seems to be a limit of 32MB-28KB on X64 and 64MB-32KB on x86; + * bigger writes fail on Windows XP. + * So we cap to a nice 31MB here to avoid write failures over + * the net without changing the number of WriteFile() calls in + * the local case. + */ + return write(fd, buf, min(count, 31 * 1024 * 1024)); +} + #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { @@ -275,8 +292,17 @@ int mingw_utime (const char *file_name, const struct utimbuf *times) int fh, rc; /* must have write permission */ - if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) - return -1; + DWORD attrs = GetFileAttributes(file_name); + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_READONLY)) { + /* ignore errors here; open() will report them */ + SetFileAttributes(file_name, attrs & ~FILE_ATTRIBUTE_READONLY); + } + + if ((fh = open(file_name, O_RDWR | O_BINARY)) < 0) { + rc = -1; + goto revert_attrs; + } time_t_to_filetime(times->modtime, &mft); time_t_to_filetime(times->actime, &aft); @@ -286,6 +312,13 @@ int mingw_utime (const char *file_name, const struct utimbuf *times) } else rc = 0; close(fh); + +revert_attrs: + if (attrs != INVALID_FILE_ATTRIBUTES && + (attrs & FILE_ATTRIBUTE_READONLY)) { + /* ignore errors again */ + SetFileAttributes(file_name, attrs); + } return rc; } @@ -634,6 +667,7 @@ static int env_compare(const void *a, const void *b) } static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, + const char *dir, int prepend_cmd, int fhin, int fhout, int fherr) { STARTUPINFO si; @@ -713,7 +747,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, memset(&pi, 0, sizeof(pi)); ret = CreateProcess(cmd, args.buf, NULL, NULL, TRUE, flags, - env ? envblk.buf : NULL, NULL, &si, &pi); + env ? envblk.buf : NULL, dir, &si, &pi); if (env) strbuf_release(&envblk); @@ -730,10 +764,11 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, int prepend_cmd) { - return mingw_spawnve_fd(cmd, argv, env, prepend_cmd, 0, 1, 2); + return mingw_spawnve_fd(cmd, argv, env, NULL, prepend_cmd, 0, 1, 2); } pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, + const char *dir, int fhin, int fhout, int fherr) { pid_t pid; @@ -756,14 +791,14 @@ pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, pid = -1; } else { - pid = mingw_spawnve_fd(iprog, argv, env, 1, + pid = mingw_spawnve_fd(iprog, argv, env, dir, 1, fhin, fhout, fherr); free(iprog); } argv[0] = argv0; } else - pid = mingw_spawnve_fd(prog, argv, env, 0, + pid = mingw_spawnve_fd(prog, argv, env, dir, 0, fhin, fhout, fherr); free(prog); } diff --git a/compat/mingw.h b/compat/mingw.h index e81e752ed2..0e3e743041 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -170,6 +170,9 @@ int link(const char *oldpath, const char *newpath); int mingw_open (const char *filename, int oflags, ...); #define open mingw_open +ssize_t mingw_write(int fd, const void *buf, size_t count); +#define write mingw_write + FILE *mingw_fopen (const char *filename, const char *otype); #define fopen mingw_fopen @@ -229,6 +232,7 @@ int mingw_utime(const char *file_name, const struct utimbuf *times); #define utime mingw_utime pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env, + const char *dir, int fhin, int fhout, int fherr); void mingw_execvp(const char *cmd, char *const *argv); #define execvp mingw_execvp diff --git a/compat/vcbuild/include/termios.h b/compat/vcbuild/include/termios.h new file mode 100644 index 0000000000..0d8552a2c6 --- /dev/null +++ b/compat/vcbuild/include/termios.h @@ -0,0 +1 @@ +/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/win32mmap.c b/compat/win32mmap.c index 1c5a14922f..b58aa69fa0 100644 --- a/compat/win32mmap.c +++ b/compat/win32mmap.c @@ -4,19 +4,19 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of { HANDLE hmap; void *temp; - size_t len; + off_t len; struct stat st; uint64_t o = offset; uint32_t l = o & 0xFFFFFFFF; uint32_t h = (o >> 32) & 0xFFFFFFFF; if (!fstat(fd, &st)) - len = xsize_t(st.st_size); + len = st.st_size; else die("mmap: could not determine filesize"); if ((length + offset) > len) - length = len - offset; + length = xsize_t(len - offset); if (!(flags & MAP_PRIVATE)) die("Invalid usage of mmap when built with USE_WIN32_MMAP"); |