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 gits...@pobox.com wrote:
 Filipe Cabecinhas fil...@gmail.com 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 limits.h
 +#include unistd.h
 +
 +/*
 + * 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-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 proha...@zib.de
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 gits...@pobox.com wrote:
 Filipe Cabecinhas fil...@gmail.com 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 limits.h
 +#include unistd.h
 +
 +/*
 + * 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-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 filcab+...@gmail.com
---
 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 limits.h
+#include unistd.h
+
+/*
+ * 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-10 Thread Junio C Hamano
Filipe Cabecinhas fil...@gmail.com 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 filcab+...@gmail.com
 ---

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 fil...@gmail.com
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 filcab+...@gmail.com
Signed-off-by: Junio C Hamano gits...@pobox.com
---
 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 limits.h
+#include unistd.h
+
+/*
+ * 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 gits...@pobox.com 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 limits.h
-#include unistd.h
+#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 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 gits...@pobox.com wrote:
 Filipe Cabecinhas fil...@gmail.com 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 filcab+...@gmail.com
 ---

 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 fil...@gmail.com
 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 filcab+...@gmail.com
 Signed-off-by: Junio C Hamano gits...@pobox.com
 ---
  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 limits.h
 +#include unistd.h
 +
 +/*
 + * 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,

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 fil...@gmail.com 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 gits...@pobox.com wrote:
 Filipe Cabecinhas fil...@gmail.com 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 filcab+...@gmail.com
 ---

 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 fil...@gmail.com
 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 filcab+...@gmail.com
 Signed-off-by: Junio C Hamano gits...@pobox.com
 ---
  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 limits.h
 +#include unistd.h
 +
 +/*
 + * 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
Filipe Cabecinhas fil...@gmail.com 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-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 gits...@pobox.com wrote:
 Filipe Cabecinhas fil...@gmail.com 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-05-09 Thread Junio C Hamano
Filipe Cabecinhas fil...@gmail.com 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 limits.h
 +#include unistd.h
 +
 +/* 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


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


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

2013-04-09 Thread Junio C Hamano
Filipe Cabecinhas fil...@gmail.com 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