threads / patch / 41019

patchmingw: emulate write(2) that fails with a EPIPE

Subject: [PATCH] mingw: emulate write(2) that fails with a EPIPE

## tl;dr

13 messages between Dec 16, 2015 and Dec 21, 2015. Diffs are folded; open one to read it.

replies: 12people: 4as markdown or json

Johannes Schindelin· Dec 16, 2015, 12:14 UTC · lore

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.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
Show changes to compat/mingw.h +18 −0
diff --git a/compat/mingw.h b/compat/mingw.h
index 738865c..2aca347 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -210,6 +210,24 @@ 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;
+}
+
+#define write mingw_write
+
 int mingw_access(const char *filename, int mode);
 #undef access
 #define access mingw_access
-- 
2.6.3.windows.1.300.g1c25e49
Junio C Hamano· Dec 16, 2015, 18:35 UTC · re: Johannes Schindelin · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Johannes Schindelin <johannes.schindelin@gmx.de> writes:
Show 9 quoted lines
> 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.
Makes sense.
Show 21 quoted lines
>  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;
> +}
> +
> +#define write mingw_write
> +

It strikes me a bit strange to see this inlined compared to what appears in the context. Shouldn't the implementation be done in compat/mingw.c like all others?

>  int mingw_access(const char *filename, int mode);
>  #undef access
>  #define access mingw_access
Johannes Schindelin· Dec 17, 2015, 09:39 UTC · re: Junio C Hamano · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Hi Junio,
On Wed, 16 Dec 2015, Junio C Hamano wrote:
Show 27 quoted lines
> Johannes Schindelin <johannes.schindelin@gmx.de> writes:
> 
> >  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;
> > +}
> > +
> > +#define write mingw_write
> > +
> 
> It strikes me a bit strange to see this inlined compared to what
> appears in the context.  Shouldn't the implementation be done in
> compat/mingw.c like all others?

My intuition (which I honestly did not verify using performance tests) was that write() is called *much* more often than, say, open(), and therefore I wanted to interfere as little as possible with the performance penalty. Hence the choice of an inlined function as opposed to a non-optimizable increment of the call chain.

If it bothers you a lot I will set aside time to perform performance tests.

Ciao, Dscho

Junio C Hamano· Dec 17, 2015, 16:40 UTC · re: Johannes Schindelin · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> My intuition (which I honestly did not verify using performance tests) was
> that write() is called *much* more often than, say, open(),...

My gut feeling agrees with yours, but I do not think the frequency at which write() is called should be the primary factor when you decide to make its wrapper inlined. Once you call write(2), you will hit either the disk or the network doing I/O, and at that point I'd expect that the cost of making an extra layer of wrapper call would be lost in the noise. I'd worry a lot more about from how many callsites write() is called---by inlining the extra code that is run only when the underlying write(2) returns an error to many callsites, we would make the program as a whole bigger, and as the result other code needs to be evicted out of the instruction cache, which also would hurt performance.

Johannes Schindelin· Dec 17, 2015, 17:08 UTC · re: Junio C Hamano · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Hi Junio,
On Thu, 17 Dec 2015, Junio C Hamano wrote:
Show 16 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> > My intuition (which I honestly did not verify using performance tests) was
> > that write() is called *much* more often than, say, open(),...
> 
> My gut feeling agrees with yours, but I do not think the frequency
> at which write() is called should be the primary factor when you
> decide to make its wrapper inlined.  Once you call write(2), you
> will hit either the disk or the network doing I/O, and at that point
> I'd expect that the cost of making an extra layer of wrapper call
> would be lost in the noise.  I'd worry a lot more about from how
> many callsites write() is called---by inlining the extra code that
> is run only when the underlying write(2) returns an error to many
> callsites, we would make the program as a whole bigger, and as the
> result other code needs to be evicted out of the instruction cache,
> which also would hurt performance.
That argument convinced me. v2 coming shortly.

Ciao, Dscho

Eric Sunshine· Dec 16, 2015, 19:47 UTC · re: Johannes Schindelin · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

On Wednesday, December 16, 2015, Johannes Schindelin <johannes.schindelin@gmx.de> wrote:

Show 24 quoted lines
> 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>
> ---
> diff --git a/compat/mingw.h b/compat/mingw.h
> @@ -210,6 +210,24 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
> +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) {
Here, errno is EINVAL...
Show 6 quoted lines
> +               /* check if fd is a pipe */
> +               HANDLE h = (HANDLE) _get_osfhandle(fd);
> +               if (GetFileType(h) == FILE_TYPE_PIPE)
> +                       errno = EPIPE;
> +               else
> +                       errno = EINVAL;

Does any of the code between the outer 'if' and this point clobber errno, or are you merely assigning EINVAL for robustness against future changes?

Show 9 quoted lines
> +       }
> +
> +       return result;
> +}
> +
> +#define write mingw_write
> +
> --
> 2.6.3.windows.1.300.g1c25e49
Junio C Hamano· Dec 16, 2015, 20:36 UTC · re: Eric Sunshine · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Eric Sunshine <sunshine@sunshineco.com> writes:
Show 14 quoted lines
>> +       if (result < 0 && errno == EINVAL && buf) {
>
> Here, errno is EINVAL...
>
>> +               /* check if fd is a pipe */
>> +               HANDLE h = (HANDLE) _get_osfhandle(fd);
>> +               if (GetFileType(h) == FILE_TYPE_PIPE)
>> +                       errno = EPIPE;
>> +               else
>> +                       errno = EINVAL;
>
> Does any of the code between the outer 'if' and this point clobber
> errno, or are you merely assigning EINVAL for robustness against
> future changes?

I do think it is a good idea to reassign 'errno' here to stress on the fact that we return EPIPE only when we positively know that we were reading from a pipe, and otherwise we won't change the original errno at all.

But at the same time, if other things that are called before we figure out if we were reading from a pipe could affect errno, I wonder if that is an indication of a bug--an error return from system functions that the code is not responding to. For example, can _get_osfhandle() fail and when it does what would we see? Perhaps NULL in h?

Johannes Schindelin· Dec 17, 2015, 09:37 UTC · re: Eric Sunshine · lore

Re: [PATCH] mingw: emulate write(2) that fails with a EPIPE

Hi Eric,
On Wed, 16 Dec 2015, Eric Sunshine wrote:
Show 22 quoted lines
> On Wednesday, December 16, 2015, Johannes Schindelin
> <johannes.schindelin@gmx.de> wrote:
> > diff --git a/compat/mingw.h b/compat/mingw.h
> > @@ -210,6 +210,24 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
> > +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) {
> 
> Here, errno is EINVAL...
> 
> > +               /* check if fd is a pipe */
> > +               HANDLE h = (HANDLE) _get_osfhandle(fd);
> > +               if (GetFileType(h) == FILE_TYPE_PIPE)
> > +                       errno = EPIPE;
> > +               else
> > +                       errno = EINVAL;
> 
> Does any of the code between the outer 'if' and this point clobber
> errno, or are you merely assigning EINVAL for robustness against
> future changes?

Yes, it is proofing the code against future changes. And TBH I did not even bother to check whether _get_osfhandle() or GetFileType() can modify the errno value, since I *really* wanted to make sure that errno is either EPIPE or EINVAL in this execution path.

Ciao, Dscho

Johannes Schindelin· Dec 17, 2015, 17:08 UTC · re: Johannes Schindelin · lore

[PATCH v2] mingw: emulate write(2) that fails with a EPIPE

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(+)
Show changes to 2 files +38 −16

compat/mingw.c, compat/mingw.h

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
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);
-- 
2.6.3.windows.1.300.g1c25e49
Junio C Hamano· Dec 17, 2015, 19:22 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2] mingw: emulate write(2) that fails with a EPIPE

Johannes Schindelin <johannes.schindelin@gmx.de> writes:
Show 63 quoted lines
> 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.

Show 58 quoted lines
> 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);
Johannes Schindelin· Dec 18, 2015, 16:10 UTC · re: Junio C Hamano · lore

Re: [PATCH v2] mingw: emulate write(2) that fails with a EPIPE

Hi Junio,
On Thu, 17 Dec 2015, Junio C Hamano wrote:
Show 7 quoted lines
> 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.
> 
> Johannes Schindelin <johannes.schindelin@gmx.de> writes:
> 
> > Interdiff vs v1:

Whoops. This is an obvious bug in my patch series submission script. Will fix.

Sorry, Dscho

Johannes Sixt· Dec 18, 2015, 20:57 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2] mingw: emulate write(2) that fails with a EPIPE

Am 17.12.2015 um 18:08 schrieb Johannes Schindelin:
Show 49 quoted lines
> 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];

Looks good. I tested the patch, and it fixes the failure exposed by t5571.11.

Acked-by: Johannes Sixt <j6t@kdbg.org>
Thanks!
-- Hannes
Junio C Hamano· Dec 21, 2015, 16:59 UTC · re: Johannes Sixt · lore

Re: [PATCH v2] mingw: emulate write(2) that fails with a EPIPE

Johannes Sixt <j6t@kdbg.org> writes:
Show 27 quoted lines
>> +#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];
>
> Looks good. I tested the patch, and it fixes the failure exposed by
> t5571.11.
>
> Acked-by: Johannes Sixt <j6t@kdbg.org>
>
> Thanks!
Thanks, both.

← back to recent threads