[PATCH 02/11] Factor out and export large blob writing code to arbitrary file handle
From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:53:09
Subsystem:
the rest · Maintainer:
Linus Torvalds
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted> --- cache.h | 3 +++ entry.c | 39 ++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/cache.h b/cache.h
index e12b15f..6ce691b 100644
--- a/cache.h
+++ b/cache.h@@ -937,6 +937,9 @@ struct checkout { refresh_cache:1; }; +extern int streaming_write_sha1(int fd, int seekable, const unsigned char *sha1, + enum object_type exp_type, + struct stream_filter *filter); extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); struct cache_def {
diff --git a/entry.c b/entry.c
index 852fea1..dde0d17 100644
--- a/entry.c
+++ b/entry.c@@ -115,26 +115,20 @@ static int fstat_output(int fd, const struct checkout *state, struct stat *st) return 0; } -static int streaming_write_entry(struct cache_entry *ce, char *path, - struct stream_filter *filter, - const struct checkout *state, int to_tempfile, - int *fstat_done, struct stat *statbuf) +int streaming_write_sha1(int fd, int seekable, const unsigned char *sha1, + enum object_type exp_type, + struct stream_filter *filter) { struct git_istream *st; enum object_type type; unsigned long sz; int result = -1; ssize_t kept = 0; - int fd = -1; - st = open_istream(ce->sha1, &type, &sz, filter); + st = open_istream(sha1, &type, &sz, filter); if (!st) return -1; - if (type != OBJ_BLOB) - goto close_and_exit; - - fd = open_output_fd(path, ce, to_tempfile); - if (fd < 0) + if (exp_type != OBJ_ANY && type != exp_type) goto close_and_exit; for (;;) {
@@ -144,7 +138,7 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, if (!readlen) break; - if (sizeof(buf) == readlen) { + if (seekable && sizeof(buf) == readlen) { for (holeto = 0; holeto < readlen; holeto++) if (buf[holeto]) break;
@@ -166,10 +160,29 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, 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); + result = 0; close_and_exit: close_istream(st); + return result; +} + +static int streaming_write_entry(struct cache_entry *ce, char *path, + struct stream_filter *filter, + const struct checkout *state, int to_tempfile, + int *fstat_done, struct stat *statbuf) +{ + int result = -1; + int fd = open_output_fd(path, ce, to_tempfile); + if (fd < 0) + goto close_and_exit; + + if (streaming_write_sha1(fd, 1, ce->sha1, OBJ_BLOB, filter)) + goto close_and_exit; + + *fstat_done = fstat_output(fd, state, statbuf); + +close_and_exit: if (0 <= fd) result = close(fd); if (result && 0 <= fd)
--
1.7.3.1.256.g2539c.dirty