From: Junio C Hamano Date: Fri, 13 May 2011 22:55:00 +0000 (-0700) Subject: streaming_write_entry(): support files with holes X-Git-Tag: v1.7.7-rc0~60^2~13 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=de6182db67d0f53fdc13256042014f2ddf5f8df3;p=git.git streaming_write_entry(): support files with holes One typical use of a large binary file is to hold a sparse on-disk hash table with a lot of holes. Help preserving the holes with lseek(). Signed-off-by: Junio C Hamano --- diff --git a/entry.c b/entry.c index da37d0151..e2dc16c13 100644 --- a/entry.c +++ b/entry.c @@ -123,6 +123,7 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, enum object_type type; unsigned long sz; int result = -1; + ssize_t kept = 0; int fd = -1; st = open_istream(ce->sha1, &type, &sz); @@ -136,18 +137,34 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, goto close_and_exit; for (;;) { - char buf[10240]; - ssize_t wrote; + char buf[1024 * 16]; + ssize_t wrote, holeto; ssize_t readlen = read_istream(st, buf, sizeof(buf)); if (!readlen) break; + if (sizeof(buf) == readlen) { + for (holeto = 0; holeto < readlen; holeto++) + if (buf[holeto]) + break; + if (readlen == holeto) { + kept += holeto; + continue; + } + } + if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1) + goto close_and_exit; + else + kept = 0; wrote = write_in_full(fd, buf, readlen); if (wrote != readlen) goto close_and_exit; } + if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 || + write(fd, "", 1) != 1)) + goto close_and_exit; *fstat_done = fstat_output(fd, state, statbuf); close_and_exit: