Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-11-20 Thread Torsten Bögershausen
Hej,
I think the patch went in and out in git.git, please see below.

(I coudn't the following  in msysgit,
 but if it was there, the clipped_write() for Windows could go away.

/Torsten



commit 0b6806b9e45c659d25b87fb5713c920a3081eac8
Author: Steffen Prohaska 
Date:   Tue Aug 20 08:43:54 2013 +0200

xread, xwrite: limit size of IO to 8MB

Checking out 2GB or more through an external filter (see test) fails
on Mac OS X 10.8.4 (12E55) for a 64-bit executable with:

error: read from external filter cat failed
error: cannot feed the input to external filter cat
error: cat died of signal 13
error: external filter cat failed 141
error: external filter cat failed

The reason is that read() immediately returns with EINVAL when asked
to read more than 2GB.  According to POSIX [1], if the value of
nbyte passed to read() is greater than SSIZE_MAX, the result is
implementation-defined.  The write function has the same restriction
[2].  Since OS X still supports running 32-bit executables, the
32-bit limit (SSIZE_MAX = INT_MAX = 2GB - 1) seems to be also
imposed on 64-bit executables under certain conditions.  For write,
the problem has been addressed earlier [6c642a].

Address the problem for read() and write() differently, by limiting
size of IO chunks unconditionally on all platforms in xread() and
xwrite().  Large chunks only cause problems, like causing latencies
when killing the process, even if OS X was not buggy.  Doing IO in
reasonably sized smaller chunks should have no negative impact on
performance.

The compat wrapper clipped_write() introduced earlier [6c642a] is
not needed anymore.  It will be reverted in a separate commit.  The
new test catches read and write problems.

Note that 'git add' exits with 0 even if it prints filtering errors
to stderr.  The test, therefore, checks stderr.  'git add' should
probably be changed (sometime in another commit) to exit with
nonzero if filtering fails.  The test could then be changed to use
test_must_fail.


On 2013-11-20 11.15, Erik Faye-Lund wrote:
> I know I'm extremely late to the party, and this patch has already
> landed, but...
> 
> On Sat, May 11, 2013 at 1:05 AM, Junio C Hamano  wrote:
>> Filipe Cabecinhas  writes:
>>
>>> Due to a bug in the Darwin kernel, write() calls have a maximum size of
>>> INT_MAX bytes.
>>>
>>> This patch introduces a new compat function: clipped_write
>>> This function behaves the same as write() but will write, at most, INT_MAX
>>> characters.
>>> It may be necessary to include this function on Windows, too.
> 
> We are already doing something similar for Windows in mingw_write (see
> compat/mingw.c), but with a much smaller size.
> 
> It feels a bit pointless to duplicate this logic.
> 
>> diff --git a/compat/clipped-write.c b/compat/clipped-write.c
>> new file mode 100644
>> index 000..9183698
>> --- /dev/null
>> +++ b/compat/clipped-write.c
>> @@ -0,0 +1,13 @@
>> +#include 
>> +#include 
>> +
>> +/*
>> + * Version of write that will write at most INT_MAX bytes.
>> + * Workaround a xnu bug on Mac OS X
>> + */
>> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
>> +{
>> +   if (nbyte > INT_MAX)
>> +   nbyte = INT_MAX;
>> +   return write(fildes, buf, nbyte);
>> +}
> 
> If we were to reuse this logic with Windows, we'd need to have some
> way of overriding the max-size of the write.
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-11-20 Thread Erik Faye-Lund
I know I'm extremely late to the party, and this patch has already
landed, but...

On Sat, May 11, 2013 at 1:05 AM, Junio C Hamano  wrote:
> Filipe Cabecinhas  writes:
>
>> Due to a bug in the Darwin kernel, write() calls have a maximum size of
>> INT_MAX bytes.
>>
>> This patch introduces a new compat function: clipped_write
>> This function behaves the same as write() but will write, at most, INT_MAX
>> characters.
>> It may be necessary to include this function on Windows, too.

We are already doing something similar for Windows in mingw_write (see
compat/mingw.c), but with a much smaller size.

It feels a bit pointless to duplicate this logic.

> diff --git a/compat/clipped-write.c b/compat/clipped-write.c
> new file mode 100644
> index 000..9183698
> --- /dev/null
> +++ b/compat/clipped-write.c
> @@ -0,0 +1,13 @@
> +#include 
> +#include 
> +
> +/*
> + * Version of write that will write at most INT_MAX bytes.
> + * Workaround a xnu bug on Mac OS X
> + */
> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
> +{
> +   if (nbyte > INT_MAX)
> +   nbyte = INT_MAX;
> +   return write(fildes, buf, nbyte);
> +}

If we were to reuse this logic with Windows, we'd need to have some
way of overriding the max-size of the write.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Junio C Hamano
Filipe Cabecinhas  writes:

> It compiles cleanly and runs. I'm running the test suite anyway, but
> don't expect any change from your latest patch.

Heh, I do not think we did write(2) of that many bytes in our test
suite ;-)

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Filipe Cabecinhas
Hi Junio,

It compiles cleanly and runs. I'm running the test suite anyway, but
don't expect any change from your latest patch.

Thank you,

  Filipe
  F


On Fri, May 10, 2013 at 4:13 PM, Filipe Cabecinhas  wrote:
> Hi Junio,
>
> Thanks for helping. Your text is correct and only diffs from my patch
> in the #define write(...) part, where I suppose you stripped the
> spaced in the arglist.
>
> Thank you,
>
>   Filipe
>
>   F
>
>
> On Fri, May 10, 2013 at 4:05 PM, Junio C Hamano  wrote:
>> Filipe Cabecinhas  writes:
>>
>>> Due to a bug in the Darwin kernel, write() calls have a maximum size of
>>> INT_MAX bytes.
>>>
>>> This patch introduces a new compat function: clipped_write
>>> This function behaves the same as write() but will write, at most, INT_MAX
>>> characters.
>>> It may be necessary to include this function on Windows, too.
>>>
>>> Signed-off-by: Filipe Cabecinhas 
>>> ---
>>
>> Somehow your MUA seems to have lost _all_ tabs, not just in the new
>> lines in your patch but also in the existing context lines.
>>
>>> diff --git a/Makefile b/Makefile
>>> index 0f931a2..ccb8f3f 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -1466,6 +1466,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
>>>   MSGFMT += --check --statistics
>>>  endif
>>>
>>> +ifdef NEEDS_CLIPPED_WRITE
>>> + BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
>>> + COMPAT_OBJS += compat/clipped-write.o
>>> +endif
>>> +
>>> ...
>>
>> Here is what I resurrected and queued. I _think_ I did not make any
>> silly mistake while transcribing from your whitespace-mangled patch,
>> but please double check; I do not have any Darwin, so this hasn't
>> even been compile tested.
>>
>> Also I have a small suggestion I'd like you to try on top of it,
>> which I'll be sending in a separate message.
>>
>> Thanks.
>>
>> -- >8 --
>> From: Filipe Cabecinhas 
>> Date: Fri, 10 May 2013 15:24:57 -0700
>> Subject: [PATCH] compate/clipped-write.c: large write(2) fails on Mac OS 
>> X/XNU
>>
>> Due to a bug in the Darwin kernel, write(2) calls have a maximum size
>> of INT_MAX bytes.
>>
>> Introduce a new compat function, clipped_write(), that only writes
>> at most INT_MAX bytes and returns the number of bytes written, as
>> a substitute for write(2), and allow platforms that need this to
>> enable it from the build mechanism with NEEDS_CLIPPED_WRITE.
>>
>> Set it for Mac OS X by default.  It may be necessary to include this
>> function on Windows, too.
>>
>> Signed-off-by: Filipe Cabecinhas 
>> Signed-off-by: Junio C Hamano 
>> ---
>>  Makefile   |  5 +
>>  compat/clipped-write.c | 13 +
>>  config.mak.uname   |  1 +
>>  git-compat-util.h  |  5 +
>>  4 files changed, 24 insertions(+)
>>  create mode 100644 compat/clipped-write.c
>>
>> diff --git a/Makefile b/Makefile
>> index 26d3332..7076b15 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -1463,6 +1463,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
>> MSGFMT += --check --statistics
>>  endif
>>
>> +ifdef NEEDS_CLIPPED_WRITE
>> +   BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
>> +   COMPAT_OBJS += compat/clipped-write.o
>> +endif
>> +
>>  ifneq (,$(XDL_FAST_HASH))
>> BASIC_CFLAGS += -DXDL_FAST_HASH
>>  endif
>> diff --git a/compat/clipped-write.c b/compat/clipped-write.c
>> new file mode 100644
>> index 000..9183698
>> --- /dev/null
>> +++ b/compat/clipped-write.c
>> @@ -0,0 +1,13 @@
>> +#include 
>> +#include 
>> +
>> +/*
>> + * Version of write that will write at most INT_MAX bytes.
>> + * Workaround a xnu bug on Mac OS X
>> + */
>> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
>> +{
>> +   if (nbyte > INT_MAX)
>> +   nbyte = INT_MAX;
>> +   return write(fildes, buf, nbyte);
>> +}
>> diff --git a/config.mak.uname b/config.mak.uname
>> index e09af8f..e689a9a 100644
>> --- a/config.mak.uname
>> +++ b/config.mak.uname
>> @@ -95,6 +95,7 @@ ifeq ($(uname_S),Darwin)
>> NO_MEMMEM = YesPlease
>> USE_ST_TIMESPEC = YesPlease
>> HAVE_DEV_TTY = YesPlease
>> +   NEEDS_CLIPPED_WRITE = YesPlease
>> COMPAT_OBJS += compat/precompose_utf8.o
>> BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
>>  endif
>> diff --git a/git-compat-util.h b/git-compat-util.h
>> index b636e0d..3144b8d 100644
>> --- a/git-compat-util.h
>> +++ b/git-compat-util.h
>> @@ -181,6 +181,11 @@ typedef unsigned long uintptr_t;
>>  #define probe_utf8_pathname_composition(a,b)
>>  #endif
>>
>> +#ifdef NEEDS_CLIPPED_WRITE
>> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte);
>> +#define write(x,y,z) clipped_write((x),(y),(z))
>> +#endif
>> +
>>  #ifdef MKDIR_WO_TRAILING_SLASH
>>  #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
>>  extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
>> --
>> 1.8.3-rc1-268-g30389da
>>
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Filipe Cabecinhas
Hi Junio,

Thanks for helping. Your text is correct and only diffs from my patch
in the #define write(...) part, where I suppose you stripped the
spaced in the arglist.

Thank you,

  Filipe

  F


On Fri, May 10, 2013 at 4:05 PM, Junio C Hamano  wrote:
> Filipe Cabecinhas  writes:
>
>> Due to a bug in the Darwin kernel, write() calls have a maximum size of
>> INT_MAX bytes.
>>
>> This patch introduces a new compat function: clipped_write
>> This function behaves the same as write() but will write, at most, INT_MAX
>> characters.
>> It may be necessary to include this function on Windows, too.
>>
>> Signed-off-by: Filipe Cabecinhas 
>> ---
>
> Somehow your MUA seems to have lost _all_ tabs, not just in the new
> lines in your patch but also in the existing context lines.
>
>> diff --git a/Makefile b/Makefile
>> index 0f931a2..ccb8f3f 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -1466,6 +1466,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
>>   MSGFMT += --check --statistics
>>  endif
>>
>> +ifdef NEEDS_CLIPPED_WRITE
>> + BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
>> + COMPAT_OBJS += compat/clipped-write.o
>> +endif
>> +
>> ...
>
> Here is what I resurrected and queued. I _think_ I did not make any
> silly mistake while transcribing from your whitespace-mangled patch,
> but please double check; I do not have any Darwin, so this hasn't
> even been compile tested.
>
> Also I have a small suggestion I'd like you to try on top of it,
> which I'll be sending in a separate message.
>
> Thanks.
>
> -- >8 --
> From: Filipe Cabecinhas 
> Date: Fri, 10 May 2013 15:24:57 -0700
> Subject: [PATCH] compate/clipped-write.c: large write(2) fails on Mac OS X/XNU
>
> Due to a bug in the Darwin kernel, write(2) calls have a maximum size
> of INT_MAX bytes.
>
> Introduce a new compat function, clipped_write(), that only writes
> at most INT_MAX bytes and returns the number of bytes written, as
> a substitute for write(2), and allow platforms that need this to
> enable it from the build mechanism with NEEDS_CLIPPED_WRITE.
>
> Set it for Mac OS X by default.  It may be necessary to include this
> function on Windows, too.
>
> Signed-off-by: Filipe Cabecinhas 
> Signed-off-by: Junio C Hamano 
> ---
>  Makefile   |  5 +
>  compat/clipped-write.c | 13 +
>  config.mak.uname   |  1 +
>  git-compat-util.h  |  5 +
>  4 files changed, 24 insertions(+)
>  create mode 100644 compat/clipped-write.c
>
> diff --git a/Makefile b/Makefile
> index 26d3332..7076b15 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1463,6 +1463,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
> MSGFMT += --check --statistics
>  endif
>
> +ifdef NEEDS_CLIPPED_WRITE
> +   BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
> +   COMPAT_OBJS += compat/clipped-write.o
> +endif
> +
>  ifneq (,$(XDL_FAST_HASH))
> BASIC_CFLAGS += -DXDL_FAST_HASH
>  endif
> diff --git a/compat/clipped-write.c b/compat/clipped-write.c
> new file mode 100644
> index 000..9183698
> --- /dev/null
> +++ b/compat/clipped-write.c
> @@ -0,0 +1,13 @@
> +#include 
> +#include 
> +
> +/*
> + * Version of write that will write at most INT_MAX bytes.
> + * Workaround a xnu bug on Mac OS X
> + */
> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
> +{
> +   if (nbyte > INT_MAX)
> +   nbyte = INT_MAX;
> +   return write(fildes, buf, nbyte);
> +}
> diff --git a/config.mak.uname b/config.mak.uname
> index e09af8f..e689a9a 100644
> --- a/config.mak.uname
> +++ b/config.mak.uname
> @@ -95,6 +95,7 @@ ifeq ($(uname_S),Darwin)
> NO_MEMMEM = YesPlease
> USE_ST_TIMESPEC = YesPlease
> HAVE_DEV_TTY = YesPlease
> +   NEEDS_CLIPPED_WRITE = YesPlease
> COMPAT_OBJS += compat/precompose_utf8.o
> BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
>  endif
> diff --git a/git-compat-util.h b/git-compat-util.h
> index b636e0d..3144b8d 100644
> --- a/git-compat-util.h
> +++ b/git-compat-util.h
> @@ -181,6 +181,11 @@ typedef unsigned long uintptr_t;
>  #define probe_utf8_pathname_composition(a,b)
>  #endif
>
> +#ifdef NEEDS_CLIPPED_WRITE
> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte);
> +#define write(x,y,z) clipped_write((x),(y),(z))
> +#endif
> +
>  #ifdef MKDIR_WO_TRAILING_SLASH
>  #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
>  extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
> --
> 1.8.3-rc1-268-g30389da
>
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Junio C Hamano
Junio C Hamano  writes:

> Also I have a small suggestion I'd like you to try on top of it,
> which I'll be sending in a separate message.

The first hunk is to match other Makefile knobs the builders can
tweak with minimum documentation.

As you hinted that there may be other platforms that may want to use
the clipped-write, I would prefer to see this file _not_ directly
include any system headers, but let git-compat-util.h to absorb
platform differences instead.

Of course, inside this file, we do need to use the underlying
write(2), so immediately after including the header, we #undef write
so that this compilation unit will make a call to the platform
implementation of the function.

I do not expect the follow-up patch to Makefile to cause any
problem, but I'd like to see the change to compat/clipped-write.c
double checked on a real Mac OS X system, so that we can squash this
patch into your original.

Thanks.

 Makefile   | 3 +++
 compat/clipped-write.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 7076b15..0434715 100644
--- a/Makefile
+++ b/Makefile
@@ -69,6 +69,9 @@ all::
 # Define NO_MSGFMT_EXTENDED_OPTIONS if your implementation of msgfmt
 # doesn't support GNU extensions like --check and --statistics
 #
+# Define NEEDS_CLIPPED_WRITE if your write(2) cannot write more than
+# INT_MAX bytes at once (e.g. MacOS X).
+#
 # Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
 # it specifies.
 #
diff --git a/compat/clipped-write.c b/compat/clipped-write.c
index 9183698..b8f98ff 100644
--- a/compat/clipped-write.c
+++ b/compat/clipped-write.c
@@ -1,5 +1,5 @@
-#include 
-#include 
+#include "../git-compat-util.h"
+#undef write
 
 /*
  * Version of write that will write at most INT_MAX bytes.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Junio C Hamano
Filipe Cabecinhas  writes:

> Due to a bug in the Darwin kernel, write() calls have a maximum size of
> INT_MAX bytes.
>
> This patch introduces a new compat function: clipped_write
> This function behaves the same as write() but will write, at most, INT_MAX
> characters.
> It may be necessary to include this function on Windows, too.
>
> Signed-off-by: Filipe Cabecinhas 
> ---

Somehow your MUA seems to have lost _all_ tabs, not just in the new
lines in your patch but also in the existing context lines.

> diff --git a/Makefile b/Makefile
> index 0f931a2..ccb8f3f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1466,6 +1466,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
>   MSGFMT += --check --statistics
>  endif
>
> +ifdef NEEDS_CLIPPED_WRITE
> + BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
> + COMPAT_OBJS += compat/clipped-write.o
> +endif
> +
> ...

Here is what I resurrected and queued. I _think_ I did not make any
silly mistake while transcribing from your whitespace-mangled patch,
but please double check; I do not have any Darwin, so this hasn't
even been compile tested.

Also I have a small suggestion I'd like you to try on top of it,
which I'll be sending in a separate message.

Thanks.

-- >8 --
From: Filipe Cabecinhas 
Date: Fri, 10 May 2013 15:24:57 -0700
Subject: [PATCH] compate/clipped-write.c: large write(2) fails on Mac OS X/XNU

Due to a bug in the Darwin kernel, write(2) calls have a maximum size
of INT_MAX bytes.

Introduce a new compat function, clipped_write(), that only writes
at most INT_MAX bytes and returns the number of bytes written, as
a substitute for write(2), and allow platforms that need this to
enable it from the build mechanism with NEEDS_CLIPPED_WRITE.

Set it for Mac OS X by default.  It may be necessary to include this
function on Windows, too.

Signed-off-by: Filipe Cabecinhas 
Signed-off-by: Junio C Hamano 
---
 Makefile   |  5 +
 compat/clipped-write.c | 13 +
 config.mak.uname   |  1 +
 git-compat-util.h  |  5 +
 4 files changed, 24 insertions(+)
 create mode 100644 compat/clipped-write.c

diff --git a/Makefile b/Makefile
index 26d3332..7076b15 100644
--- a/Makefile
+++ b/Makefile
@@ -1463,6 +1463,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
MSGFMT += --check --statistics
 endif
 
+ifdef NEEDS_CLIPPED_WRITE
+   BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
+   COMPAT_OBJS += compat/clipped-write.o
+endif
+
 ifneq (,$(XDL_FAST_HASH))
BASIC_CFLAGS += -DXDL_FAST_HASH
 endif
diff --git a/compat/clipped-write.c b/compat/clipped-write.c
new file mode 100644
index 000..9183698
--- /dev/null
+++ b/compat/clipped-write.c
@@ -0,0 +1,13 @@
+#include 
+#include 
+
+/*
+ * Version of write that will write at most INT_MAX bytes.
+ * Workaround a xnu bug on Mac OS X
+ */
+ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
+{
+   if (nbyte > INT_MAX)
+   nbyte = INT_MAX;
+   return write(fildes, buf, nbyte);
+}
diff --git a/config.mak.uname b/config.mak.uname
index e09af8f..e689a9a 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -95,6 +95,7 @@ ifeq ($(uname_S),Darwin)
NO_MEMMEM = YesPlease
USE_ST_TIMESPEC = YesPlease
HAVE_DEV_TTY = YesPlease
+   NEEDS_CLIPPED_WRITE = YesPlease
COMPAT_OBJS += compat/precompose_utf8.o
BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
 endif
diff --git a/git-compat-util.h b/git-compat-util.h
index b636e0d..3144b8d 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -181,6 +181,11 @@ typedef unsigned long uintptr_t;
 #define probe_utf8_pathname_composition(a,b)
 #endif
 
+#ifdef NEEDS_CLIPPED_WRITE
+ssize_t clipped_write(int fildes, const void *buf, size_t nbyte);
+#define write(x,y,z) clipped_write((x),(y),(z))
+#endif
+
 #ifdef MKDIR_WO_TRAILING_SLASH
 #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
 extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
-- 
1.8.3-rc1-268-g30389da

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-10 Thread Filipe Cabecinhas
Due to a bug in the Darwin kernel, write() calls have a maximum size of
INT_MAX bytes.

This patch introduces a new compat function: clipped_write
This function behaves the same as write() but will write, at most, INT_MAX
characters.
It may be necessary to include this function on Windows, too.

Signed-off-by: Filipe Cabecinhas 
---
 Makefile   |  5 +
 compat/clipped-write.c | 13 +
 config.mak.uname   |  1 +
 git-compat-util.h  |  5 +
 4 files changed, 24 insertions(+)
 create mode 100644 compat/clipped-write.c

diff --git a/Makefile b/Makefile
index 0f931a2..ccb8f3f 100644
--- a/Makefile
+++ b/Makefile
@@ -1466,6 +1466,11 @@ ifndef NO_MSGFMT_EXTENDED_OPTIONS
  MSGFMT += --check --statistics
 endif

+ifdef NEEDS_CLIPPED_WRITE
+ BASIC_CFLAGS += -DNEEDS_CLIPPED_WRITE
+ COMPAT_OBJS += compat/clipped-write.o
+endif
+
 ifneq (,$(XDL_FAST_HASH))
  BASIC_CFLAGS += -DXDL_FAST_HASH
 endif
diff --git a/compat/clipped-write.c b/compat/clipped-write.c
new file mode 100644
index 000..9183698
--- /dev/null
+++ b/compat/clipped-write.c
@@ -0,0 +1,13 @@
+#include 
+#include 
+
+/*
+ * Version of write that will write at most INT_MAX bytes.
+ * Workaround a xnu bug on Mac OS X
+ */
+ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
+{
+ if (nbyte > INT_MAX)
+ nbyte = INT_MAX;
+ return write(fildes, buf, nbyte);
+}
diff --git a/config.mak.uname b/config.mak.uname
index d78fd3d..174703b 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -95,6 +95,7 @@ ifeq ($(uname_S),Darwin)
  NO_MEMMEM = YesPlease
  USE_ST_TIMESPEC = YesPlease
  HAVE_DEV_TTY = YesPlease
+ NEEDS_CLIPPED_WRITE = YesPlease
  COMPAT_OBJS += compat/precompose_utf8.o
  BASIC_CFLAGS += -DPRECOMPOSE_UNICODE
 endif
diff --git a/git-compat-util.h b/git-compat-util.h
index e955bb5..a96db23 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -185,6 +185,11 @@ int get_st_mode_bits(const char *path, int *mode);
 #define probe_utf8_pathname_composition(a,b)
 #endif

+#ifdef NEEDS_CLIPPED_WRITE
+ssize_t clipped_write(int fildes, const void *buf, size_t nbyte);
+#define write(x, y, z) clipped_write((x), (y), (z))
+#endif
+
 #ifdef MKDIR_WO_TRAILING_SLASH
 #define mkdir(a,b) compat_mkdir_wo_trailing_slash((a),(b))
 extern int compat_mkdir_wo_trailing_slash(const char*, mode_t);
--
1.8.2.1.343.g13c32df
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-09 Thread Junio C Hamano
Filipe Cabecinhas  writes:

> Sorry for the delay. I've updated the patch to work as you suggested (I 
> think).
> It's attached.

A few comments.

First, the formalities.  Please see Documentation/SubmittingPatches,
notably:

   - Please do not send a patch as an attachment.

   - The attached patch does not seem to have any proposed commit
 log message. For this particular change, I expect it would not
 be more than a paragraph of several lines. Please have one.

   - Please sign-off your patch.

Look at patches from other high-value contributors to learn the
style and the tone of log message.  For instance,

http://article.gmane.org/gmane.comp.version-control.git/223406

is a good example (taken at random).

> diff --git a/compat/write.c b/compat/write.c
> new file mode 100644
> index 000..1e890aa
> --- /dev/null
> +++ b/compat/write.c
> @@ -0,0 +1,11 @@
> +#include 
> +#include 
> +
> +/* Version of write that will write at most INT_MAX bytes.
> + * Workaround a xnu bug on Mac OS X */

/*
 * We format our multi-line comments like this.
 *
 * Nothing other than slash-asterisk/asterisk-slash
 * on the first and the last line of the comment block.
 */

> +ssize_t clipped_write(int fildes, const void *buf, size_t nbyte) {
> +  if (nbyte > INT_MAX)
> +return write(fildes, buf, INT_MAX);
> +  else
> +return write(fildes, buf, nbyte);
> +}

Style:

 - opening and closing parentheses of the function body sit on
   lines on their own.

 - one level of indent is 8 places, using a tab.

Perhaps it would look more like this (my MUA may clobber the tabs,
though, before it gets to you):

ssize_t clipped_write(int fildes, const void *buf, size_t nbyte)
{
if (nbyte > INT_MAX)
nbyte = INT_MAX;
return write(fildes, buf, nbyte);
}

I do not want to see this ffile called "write.c"; we will encounter
a platform whose write(2) behaves a way that we do not expect but is
different from this "clipped to INT_MAX" in the future.  The way we
will deal with such a platform is to add a workaround similar to
this patch somewhere in the compat/ directory, but if you squat on
"compat/write.c", it would be a problem for that platform, as it
cannot call its version "compat/write.c".

Perhaps call it "compat/clipped-write.c" or something.

By the way, does your underlying write(2) correctly write INT_MAX
bytes, or did you mean to clip at (INT_MAX-1)? Just double-checking.

Other than that, the patch looks sensible to me.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-05-09 Thread Filipe Cabecinhas
Hi Junio,

Sorry for the delay. I've updated the patch to work as you suggested (I think).
It's attached.

Thank you,

  Filipe
  F


On Tue, Apr 9, 2013 at 3:50 PM, Junio C Hamano  wrote:
> Filipe Cabecinhas  writes:
>
>>
>> Testing with dd bs=INT_MAX+1 count=1 also gets me an “Invalid
>> argument” error, while bs=INT_MAX will do what's expected.
>>
>> I have a preliminary patch that fixes it, but it may not be the
>> preferred way. The code is not ifdef'ed out and I'm doing the fix in
>> write_in_full(), while it may be preferred to do the fix in xwrite().
>>
>> A radar bug has been submitted to Apple about this, but I think git
>> could tolerate the bug while it isn't fixed, by working around it.
>>
>> Thank you,
>>
>>   Filipe
>>
>> diff --git a/wrapper.c b/wrapper.c
>> index bac59d2..474d760 100644
>> --- a/wrapper.c
>> +++ b/wrapper.c
>> @@ -187,7 +187,12 @@ ssize_t write_in_full(int fd, const void *buf, size_t 
>> count)
>>   ssize_t total = 0;
>>
>>   while (count > 0) {
>> - ssize_t written = xwrite(fd, p, count);
>> + ssize_t written = 0;
>> +if (count >= INT_MAX)
>> + written = xwrite(fd, p, INT_MAX-1);
>> +else
>> + written = xwrite(fd, p, count);
>
> I think it is better to fix it in much lower level of the stack, as
> other codepaths would call write(2), either thru xwrite() or
> directly.
>
> Ideally the fix should go to the lowest level, i.e. the write(2).  I
> do not care if it is done in the kernel or in the libc wrapping
> code; the above does not belong to our code (in an ideal world, that
> is).
>
> Otherwise you would have to patch everything in /usr/bin, no?
>
> But you do not live in an ideal world and neither do we.  I think
> the least ugly way may be to add compat/clipped-write.c that
> implements a loop like the above in a helper function:
>
> ssize_t clipped_write(int, const void *, size_t);
>
> and have a
>
> #ifdef NEED_CLIPPED_WRITE
> #define write(x,y,z) clipped_write((x),(y),(z))
> #endif
>
> in git-compat-util.h, or something.  Makefile needs to get adjusted
> to link with compat/clipped-write.o when NEED_CLIPPED_WRITE is
> defined as well.


git-big-write-darwin.patch
Description: Binary data


Re: write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-04-09 Thread Junio C Hamano
Filipe Cabecinhas  writes:

>
> Testing with dd bs=INT_MAX+1 count=1 also gets me an “Invalid
> argument” error, while bs=INT_MAX will do what's expected.
>
> I have a preliminary patch that fixes it, but it may not be the
> preferred way. The code is not ifdef'ed out and I'm doing the fix in
> write_in_full(), while it may be preferred to do the fix in xwrite().
>
> A radar bug has been submitted to Apple about this, but I think git
> could tolerate the bug while it isn't fixed, by working around it.
>
> Thank you,
>
>   Filipe
>
> diff --git a/wrapper.c b/wrapper.c
> index bac59d2..474d760 100644
> --- a/wrapper.c
> +++ b/wrapper.c
> @@ -187,7 +187,12 @@ ssize_t write_in_full(int fd, const void *buf, size_t 
> count)
>   ssize_t total = 0;
>  
>   while (count > 0) {
> - ssize_t written = xwrite(fd, p, count);
> + ssize_t written = 0;
> +if (count >= INT_MAX)
> + written = xwrite(fd, p, INT_MAX-1);
> +else
> + written = xwrite(fd, p, count);

I think it is better to fix it in much lower level of the stack, as
other codepaths would call write(2), either thru xwrite() or
directly.

Ideally the fix should go to the lowest level, i.e. the write(2).  I
do not care if it is done in the kernel or in the libc wrapping
code; the above does not belong to our code (in an ideal world, that
is).

Otherwise you would have to patch everything in /usr/bin, no?

But you do not live in an ideal world and neither do we.  I think
the least ugly way may be to add compat/clipped-write.c that
implements a loop like the above in a helper function:

ssize_t clipped_write(int, const void *, size_t);

and have a

#ifdef NEED_CLIPPED_WRITE
#define write(x,y,z) clipped_write((x),(y),(z))
#endif

in git-compat-util.h, or something.  Makefile needs to get adjusted
to link with compat/clipped-write.o when NEED_CLIPPED_WRITE is
defined as well.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

2013-04-09 Thread Filipe Cabecinhas
Hi all,


While “git svn fetch”ing a subversion repository (private, sorry),
I've encoutered a bug that appears in several git versions (always
with the same symptoms):

git from master (from 2013-04-08)
git version 1.8.2.1 (compiled from homebrew)
git version 1.7.12.4 (Apple Git-37)

The only symptom is git blowing up with the error:
fatal: write error: Invalid argument

Problems showed up when this happened (in the SVN repo):
rev A: File F with 110K is replaced with a 9G file (don't ask…)
intermediate revs: files got added and changed, not touching file F
rev B: File F finally got reverted to the state before rev A

I can git svn fetch up to rev B-1, but svn fetching rev B will throw
the previously mentioned error.

I traced it down to write() returning <0 and setting errno to EINVAL
if nbytes > INT_MAX:
http://fxr.watson.org/fxr/source/bsd/kern/sys_generic.c?v=xnu-2050.18.24#L573
(the write() will eventually call dofilewrite, which has that check).

Testing with dd bs=INT_MAX+1 count=1 also gets me an “Invalid
argument” error, while bs=INT_MAX will do what's expected.

I have a preliminary patch that fixes it, but it may not be the
preferred way. The code is not ifdef'ed out and I'm doing the fix in
write_in_full(), while it may be preferred to do the fix in xwrite().

A radar bug has been submitted to Apple about this, but I think git
could tolerate the bug while it isn't fixed, by working around it.

Thank you,

  Filipe


git-darwin-bigwrites.patch
Description: Binary data