X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=index-pack.c;h=72e0962415d74c856917f6bb56e6fa2fea950c25;hb=10e8d68820db9c7b6412d5a553a93fd200388f30;hp=b37dd787296e908b843049a660e3e0f5cd80e01e;hpb=b8077709243138c3d8cc1c096c06a95b250a9001;p=git.git diff --git a/index-pack.c b/index-pack.c index b37dd7872..72e096241 100644 --- a/index-pack.c +++ b/index-pack.c @@ -6,8 +6,6 @@ #include "commit.h" #include "tag.h" #include "tree.h" -#include -#include static const char index_pack_usage[] = "git-index-pack [-v] [-o ] [{ ---keep | --keep= }] { | --stdin [--fix-thin] [] }"; @@ -87,16 +85,16 @@ static unsigned display_progress(unsigned n, unsigned total, unsigned last_pc) static unsigned char input_buffer[4096]; static unsigned long input_offset, input_len, consumed_bytes; static SHA_CTX input_ctx; -static int input_fd, output_fd, mmap_fd; +static int input_fd, output_fd, pack_fd; /* Discard current buffer used content. */ -static void flush() +static void flush(void) { if (input_offset) { if (output_fd >= 0) write_or_die(output_fd, input_buffer, input_offset); SHA1_Update(&input_ctx, input_buffer, input_offset); - memcpy(input_buffer, input_buffer + input_offset, input_len); + memmove(input_buffer, input_buffer + input_offset, input_len); input_offset = 0; } } @@ -148,14 +146,14 @@ static const char *open_pack_file(const char *pack_name) output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd < 0) die("unable to create %s: %s\n", pack_name, strerror(errno)); - mmap_fd = output_fd; + pack_fd = output_fd; } else { input_fd = open(pack_name, O_RDONLY); if (input_fd < 0) die("cannot open packfile '%s': %s", pack_name, strerror(errno)); output_fd = -1; - mmap_fd = input_fd; + pack_fd = input_fd; } SHA1_Init(&input_ctx); return pack_name; @@ -268,7 +266,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_ case OBJ_TAG: break; default: - bad_object(obj->offset, "bad object type %d", obj->type); + bad_object(obj->offset, "unknown object type %d", obj->type); } obj->hdr_size = consumed_bytes - obj->offset; @@ -279,27 +277,25 @@ static void *get_data_from_pack(struct object_entry *obj) { unsigned long from = obj[0].offset + obj[0].hdr_size; unsigned long len = obj[1].offset - from; - unsigned pg_offset = from % getpagesize(); - unsigned char *map, *data; + unsigned char *src, *data; z_stream stream; int st; - map = mmap(NULL, len + pg_offset, PROT_READ, MAP_PRIVATE, - mmap_fd, from - pg_offset); - if (map == MAP_FAILED) - die("cannot mmap pack file: %s", strerror(errno)); + src = xmalloc(len); + if (pread(pack_fd, src, len, from) != len) + die("cannot pread pack file: %s", strerror(errno)); data = xmalloc(obj->size); memset(&stream, 0, sizeof(stream)); stream.next_out = data; stream.avail_out = obj->size; - stream.next_in = map + pg_offset; + stream.next_in = src; stream.avail_in = len; inflateInit(&stream); while ((st = inflate(&stream, Z_FINISH)) == Z_OK); inflateEnd(&stream); if (st != Z_STREAM_END || stream.total_out != obj->size) die("serious inflate inconsistency"); - munmap(map, len + pg_offset); + free(src); return data; } @@ -642,7 +638,7 @@ static void readjust_pack_header_and_sha1(unsigned char *sha1) /* Rewrite pack header with updated object number */ if (lseek(output_fd, 0, SEEK_SET) != 0) die("cannot seek back: %s", strerror(errno)); - if (xread(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) + if (read_in_full(output_fd, &hdr, sizeof(hdr)) != sizeof(hdr)) die("cannot read pack header back: %s", strerror(errno)); hdr.hdr_entries = htonl(nr_objects); if (lseek(output_fd, 0, SEEK_SET) != 0) @@ -757,6 +753,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name, const char *keep_name, const char *keep_msg, unsigned char *sha1) { + char *report = "pack"; char name[PATH_MAX]; int err; @@ -767,18 +764,6 @@ static void final(const char *final_pack_name, const char *curr_pack_name, if (err) die("error while closing pack file: %s", strerror(errno)); chmod(curr_pack_name, 0444); - - /* - * Let's just mimic git-unpack-objects here and write - * the last part of the buffer to stdout. - */ - while (input_len) { - err = xwrite(1, input_buffer + input_offset, input_len); - if (err <= 0) - break; - input_len -= err; - input_offset += err; - } } if (keep_msg) { @@ -788,14 +773,18 @@ static void final(const char *final_pack_name, const char *curr_pack_name, get_object_directory(), sha1_to_hex(sha1)); keep_name = name; } - keep_fd = open(keep_name, O_RDWR | O_CREAT, 0600); - if (keep_fd < 0) - die("cannot write keep file"); - if (keep_msg_len > 0) { - write_or_die(keep_fd, keep_msg, keep_msg_len); - write_or_die(keep_fd, "\n", 1); + keep_fd = open(keep_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (keep_fd < 0) { + if (errno != EEXIST) + die("cannot write keep file"); + } else { + if (keep_msg_len > 0) { + write_or_die(keep_fd, keep_msg, keep_msg_len); + write_or_die(keep_fd, "\n", 1); + } + close(keep_fd); + report = "keep"; } - close(keep_fd); } if (final_pack_name != curr_pack_name) { @@ -818,6 +807,27 @@ static void final(const char *final_pack_name, const char *curr_pack_name, if (move_temp_to_file(curr_index_name, final_index_name)) die("cannot store index file"); } + + if (!from_stdin) { + printf("%s\n", sha1_to_hex(sha1)); + } else { + char buf[48]; + int len = snprintf(buf, sizeof(buf), "%s\t%s\n", + report, sha1_to_hex(sha1)); + write_or_die(1, buf, len); + + /* + * Let's just mimic git-unpack-objects here and write + * the last part of the input buffer to stdout. + */ + while (input_len) { + err = xwrite(1, input_buffer + input_offset, input_len); + if (err <= 0) + break; + input_len -= err; + input_offset += err; + } + } } int main(int argc, char **argv) @@ -841,6 +851,19 @@ int main(int argc, char **argv) keep_msg = ""; } else if (!strncmp(arg, "--keep=", 7)) { keep_msg = arg + 7; + } else if (!strncmp(arg, "--pack_header=", 14)) { + struct pack_header *hdr; + char *c; + + hdr = (struct pack_header *)input_buffer; + hdr->hdr_signature = htonl(PACK_SIGNATURE); + hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); + if (*c != ',') + die("bad %s", arg); + hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); + if (*c) + die("bad %s", arg); + input_len = sizeof(*hdr); } else if (!strcmp(arg, "-v")) { verbose = 1; } else if (!strcmp(arg, "-o")) { @@ -921,8 +944,5 @@ int main(int argc, char **argv) free(index_name_buf); free(keep_name_buf); - if (!from_stdin) - printf("%s\n", sha1_to_hex(sha1)); - return 0; }