Subject: Re: [PATCH] Fix checkout of large files to network shares under Windows XP

From: René Scharfe <[email-masked]>
Date: Mon, 19 Apr 2010 22:43:10 +0200

Am 19.04.2010 14:45, schrieb Sebastian Schuberth:
> This fixes msysGit issue 409, see
> http://code.google.com/p/msysgit/issues/detail?id=409
> 
> Signed-off-by: Sebastian Schuberth <[email-masked]>
> ---
>  compat/mingw.c |   24 ++++++++++++++++++++++++
>  compat/mingw.h |    3 +++
>  2 files changed, 27 insertions(+), 0 deletions(-)
> 
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 7ec615c..672d074 100644
> --- a/compat/mingw.c
> +++ b/compat/mingw.c
> @@ -293,6 +293,30 @@ int mingw_open (const char *filename, int oflags, ...)
>  	return fd;
>  }
>  
> +#undef write
> +ssize_t mingw_write(int fd, const void *buf, size_t count)
> +{
> +	ssize_t written = 0;
> +	size_t total = 0, size = count;
> +
> +	while (total < count && size > 0) {
> +		written = write(fd, buf, size);
> +		if (written < 0 && errno == EINVAL) {
> +			// There seems to be a bug in the Windows XP network stack that
> +			// causes writes with sizes > 64 MB to fail, so we halve the size
> +			// until we succeed or ultimately fail.

C style comments (/*...*/) are preferred over C++ style comments (//...)
for git.

Is there a known-good size, or at least a mostly-working one?  Would it
make sense to start with that size instead of halving and trying until
that size is reached?

> +			size /= 2;
> +		} else {
> +			buf += written;
> +			total += written;

What about other errors?  You need to break out of the loop instead of
adding -1 to buf and total, right?

> +			if (total + size > count)
> +				size = count - total;
> +		}
> +	}

Shouldn't the loop be left in the successful case, too?  write(2) is
allowed to write less than requested, so the caller already needs to
deal with that case anyway.

> +
> +	return written < 0 ? written : total;
> +}
> +
>  #undef fopen
>  FILE *mingw_fopen (const char *filename, const char *otype)
>  {
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 756f3ab..751bb4c 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -178,6 +178,9 @@ int mingw_rmdir(const char *path);
>  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
>