From: Junio C Hamano <gitster@pobox.com>
To: Johannes Schindelin <johannes.schindelin@gmx.de>
Cc: git@vger.kernel.org, Johannes Sixt <j6t@kdbg.org>
Subject: Re: [PATCH v2] mingw: emulate write(2) that fails with a EPIPE
Date: Thu, 17 Dec 2015 11:22:49 -0800 [thread overview]
Message-ID: <xmqqwpscc22e.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <ca357ac83a9990d6c88b637b76c6cc7f30d3f7be.1450372051.git.johannes.schindelin@gmx.de> (Johannes Schindelin's message of "Thu, 17 Dec 2015 18:08:15 +0100 (CET)")
Johannes Schindelin <johannes.schindelin@gmx.de> writes:
> On Windows, when writing to a pipe fails, errno is always
> EINVAL. However, Git expects it to be EPIPE.
>
> According to the documentation, there are two cases in which write()
> triggers EINVAL: the buffer is NULL, or the length is odd but the mode
> is 16-bit Unicode (the broken pipe is not mentioned as possible cause).
> Git never sets the file mode to anything but binary, therefore we know
> that errno should actually be EPIPE if it is EINVAL and the buffer is
> not NULL.
>
> See https://msdn.microsoft.com/en-us/library/1570wh78.aspx for more
> details.
>
> This works around t5571.11 failing with v2.6.4 on Windows.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> compat/mingw.c | 17 +++++++++++++++++
> compat/mingw.h | 3 +++
> 2 files changed, 20 insertions(+)
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 90bdb1e..5edea29 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];
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 738865c..57ca477 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -210,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
PLEASE DON'T DO THE BELOW TO THE SAME MESSAGE AS THE PATCH ITSELF.
"git apply" would not read and understand the next line as a natural
language sentence for obvious reasons.
> Interdiff vs v1:
>
> diff --git a/compat/mingw.c b/compat/mingw.c
> index 90bdb1e..5edea29 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];
> diff --git a/compat/mingw.h b/compat/mingw.h
> index 2aca347..57ca477 100644
> --- a/compat/mingw.h
> +++ b/compat/mingw.h
> @@ -210,22 +210,7 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
> int mingw_fflush(FILE *stream);
> #define fflush mingw_fflush
>
> -static inline 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;
> -}
> -
> +ssize_t mingw_write(int fd, const void *buf, size_t len);
> #define write mingw_write
>
> int mingw_access(const char *filename, int mode);
next prev parent reply other threads:[~2015-12-17 19:22 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-16 12:14 [PATCH] mingw: emulate write(2) that fails with a EPIPE Johannes Schindelin
2015-12-16 18:35 ` Junio C Hamano
2015-12-17 9:39 ` Johannes Schindelin
2015-12-17 16:40 ` Junio C Hamano
2015-12-17 17:08 ` Johannes Schindelin
2015-12-16 19:47 ` Eric Sunshine
2015-12-16 20:36 ` Junio C Hamano
2015-12-17 9:37 ` Johannes Schindelin
2015-12-17 17:08 ` [PATCH v2] " Johannes Schindelin
2015-12-17 19:22 ` Junio C Hamano [this message]
2015-12-18 16:10 ` Johannes Schindelin
2015-12-18 20:57 ` Johannes Sixt
2015-12-21 16:59 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqwpscc22e.fsf@gitster.mtv.corp.google.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=j6t@kdbg.org \
--cc=johannes.schindelin@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.