X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sha1_file.c;h=66a4e00fa83fd9fc853a1ba8a308b05cdc030967;hb=a41acc63badf20cbb22cca61039dca9309deaa19;hp=5801c3e71b43d80f7d65b21b100775b23455f533;hpb=000dfd3f6e3f61e15ccfd4cecb3a51624adfbf38;p=git.git diff --git a/sha1_file.c b/sha1_file.c index 5801c3e71..66a4e00fa 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -25,8 +25,10 @@ #ifdef NO_C99_FORMAT #define SZ_FMT "lu" +static unsigned long sz_fmt(size_t s) { return (unsigned long)s; } #else #define SZ_FMT "zu" +static size_t sz_fmt(size_t s) { return s; } #endif const unsigned char null_sha1[20]; @@ -86,7 +88,7 @@ int safe_create_leading_directories(char *path) char *pos = path; struct stat st; - if (*pos == '/') + if (is_absolute_path(path)) pos++; while (pos) { @@ -146,7 +148,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1) /* * NOTE! This returns a statically allocated buffer, so you have to be - * careful about using it. Do a "xstrdup()" if you need to save the + * careful about using it. Do an "xstrdup()" if you need to save the * filename. * * Also note that this returns the location for creating. Reading @@ -253,7 +255,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative int entlen = pfxlen + 43; int base_len = -1; - if (*entry != '/' && relative_base) { + if (!is_absolute_path(entry) && relative_base) { /* Relative alt-odb */ if (base_len < 0) base_len = strlen(relative_base) + 1; @@ -262,7 +264,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative } ent = xmalloc(sizeof(*ent) + entlen); - if (*entry != '/' && relative_base) { + if (!is_absolute_path(entry) && relative_base) { memcpy(ent->base, relative_base, base_len - 1); ent->base[base_len - 1] = '/'; memcpy(ent->base + base_len, entry, len); @@ -333,7 +335,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, while (cp < ep && *cp != sep) cp++; if (last != cp) { - if ((*last != '/') && depth) { + if (!is_absolute_path(last) && depth) { error("%s: ignoring relative alternate object store %s", relative_base, last); } else { @@ -423,9 +425,9 @@ void pack_report(void) "pack_report: getpagesize() = %10" SZ_FMT "\n" "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n" "pack_report: core.packedGitLimit = %10" SZ_FMT "\n", - (size_t) getpagesize(), - packed_git_window_size, - packed_git_limit); + sz_fmt(getpagesize()), + sz_fmt(packed_git_window_size), + sz_fmt(packed_git_limit)); fprintf(stderr, "pack_report: pack_used_ctr = %10u\n" "pack_report: pack_mmap_calls = %10u\n" @@ -435,7 +437,7 @@ void pack_report(void) pack_used_ctr, pack_mmap_calls, pack_open_windows, peak_pack_open_windows, - pack_mapped, peak_pack_mapped); + sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped)); } static int check_packed_git_idx(const char *path, struct packed_git *p) @@ -521,13 +523,15 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) munmap(idx_map, idx_size); return error("wrong index v2 file size in %s", path); } - if (idx_size != min_size) { - /* make sure we can deal with large pack offsets */ - off_t x = 0x7fffffffUL, y = 0xffffffffUL; - if (x > (x + 1) || y > (y + 1)) { - munmap(idx_map, idx_size); - return error("pack too large for current definition of off_t in %s", path); - } + if (idx_size != min_size && + /* + * make sure we can deal with large pack offsets. + * 31-bit signed offset won't be enough, neither + * 32-bit unsigned one will be. + */ + (sizeof(off_t) <= 4)) { + munmap(idx_map, idx_size); + return error("pack too large for current definition of off_t in %s", path); } } @@ -607,6 +611,22 @@ void release_pack_memory(size_t need, int fd) ; /* nothing */ } +void close_pack_windows(struct packed_git *p) +{ + while (p->windows) { + struct pack_window *w = p->windows; + + if (w->inuse_cnt) + die("pack '%s' still has open windows to it", + p->pack_name); + munmap(w->base, w->len); + pack_mapped -= w->len; + pack_open_windows--; + p->windows = w->next; + free(w); + } +} + void unuse_pack(struct pack_window **w_cursor) { struct pack_window *w = *w_cursor; @@ -1491,11 +1511,8 @@ found_cache_entry: ent->lru.next->prev = ent->lru.prev; ent->lru.prev->next = ent->lru.next; delta_base_cached -= ent->size; - } - else { - ret = xmalloc(ent->size + 1); - memcpy(ret, ent->data, ent->size); - ((char *)ret)[ent->size] = 0; + } else { + ret = xmemdupz(ent->data, ent->size); } *type = ent->type; *base_size = ent->size; @@ -1872,12 +1889,9 @@ void *read_sha1_file(const unsigned char *sha1, enum object_type *type, co = find_cached_object(sha1); if (co) { - buf = xmalloc(co->size + 1); - memcpy(buf, co->buf, co->size); - ((char*)buf)[co->size] = 0; *type = co->type; *size = co->size; - return buf; + return xmemdupz(co->buf, co->size); } buf = read_packed_sha1(sha1, type, size); @@ -2302,68 +2316,25 @@ int has_sha1_file(const unsigned char *sha1) return find_sha1_file(sha1, &st) ? 1 : 0; } -/* - * reads from fd as long as possible into a supplied buffer of size bytes. - * If necessary the buffer's size is increased using realloc() - * - * returns 0 if anything went fine and -1 otherwise - * - * The buffer is always NUL-terminated, not including it in returned size. - * - * NOTE: both buf and size may change, but even when -1 is returned - * you still have to free() it yourself. - */ -int read_fd(int fd, char **return_buf, unsigned long *return_size) -{ - char *buf = *return_buf; - unsigned long size = *return_size; - ssize_t iret; - unsigned long off = 0; - - if (!buf || size <= 1) { - size = 1024; - buf = xrealloc(buf, size); - } - - do { - iret = xread(fd, buf + off, (size - 1) - off); - if (iret > 0) { - off += iret; - if (off == size - 1) { - size = alloc_nr(size); - buf = xrealloc(buf, size); - } - } - } while (iret > 0); - - buf[off] = '\0'; - - *return_buf = buf; - *return_size = off; - - if (iret < 0) - return -1; - return 0; -} - int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object) { - unsigned long size = 4096; - char *buf = xmalloc(size); + struct strbuf buf; int ret; - if (read_fd(fd, &buf, &size)) { - free(buf); + strbuf_init(&buf, 0); + if (strbuf_read(&buf, fd, 4096) < 0) { + strbuf_release(&buf); return -1; } if (!type) type = blob_type; if (write_object) - ret = write_sha1_file(buf, size, type, sha1); + ret = write_sha1_file(buf.buf, buf.len, type, sha1); else - ret = hash_sha1_file(buf, size, type, sha1); - free(buf); + ret = hash_sha1_file(buf.buf, buf.len, type, sha1); + strbuf_release(&buf); + return ret; } @@ -2385,12 +2356,11 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, * Convert blobs to git internal format */ if ((type == OBJ_BLOB) && S_ISREG(st->st_mode)) { - unsigned long nsize = size; - char *nbuf = convert_to_git(path, buf, &nsize); - if (nbuf) { + struct strbuf nbuf; + strbuf_init(&nbuf, 0); + if (convert_to_git(path, buf, size, &nbuf)) { munmap(buf, size); - size = nsize; - buf = nbuf; + buf = strbuf_detach(&nbuf, &size); re_allocated = 1; } }