Merge branch 'jn/thinner-wrapper'
* jn/thinner-wrapper: Remove pack file handling dependency from wrapper.o pack-objects: mark file-local variable static wrapper: give zlib wrappers their own translation unit strbuf: move strbuf_branchname to sha1_name.c path helpers: move git_mkstemp* to wrapper.c wrapper: move odb_* to environment.c wrapper: move xmmap() to sha1_file.c
This commit is contained in:
commit
39f04dbaac
1
Makefile
1
Makefile
@ -670,6 +670,7 @@ LIB_OBJS += write_or_die.o
|
|||||||
LIB_OBJS += ws.o
|
LIB_OBJS += ws.o
|
||||||
LIB_OBJS += wt-status.o
|
LIB_OBJS += wt-status.o
|
||||||
LIB_OBJS += xdiff-interface.o
|
LIB_OBJS += xdiff-interface.o
|
||||||
|
LIB_OBJS += zlib.o
|
||||||
|
|
||||||
BUILTIN_OBJS += builtin/add.o
|
BUILTIN_OBJS += builtin/add.o
|
||||||
BUILTIN_OBJS += builtin/annotate.o
|
BUILTIN_OBJS += builtin/annotate.o
|
||||||
|
@ -1543,7 +1543,7 @@ static void try_to_free_from_threads(size_t size)
|
|||||||
read_unlock();
|
read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
try_to_free_t old_try_to_free_routine;
|
static try_to_free_t old_try_to_free_routine;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The main thread waits on the condition that (at least) one of the workers
|
* The main thread waits on the condition that (at least) one of the workers
|
||||||
|
@ -172,6 +172,43 @@ char *get_object_directory(void)
|
|||||||
return git_object_dir;
|
return git_object_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int odb_mkstemp(char *template, size_t limit, const char *pattern)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
/*
|
||||||
|
* we let the umask do its job, don't try to be more
|
||||||
|
* restrictive except to remove write permission.
|
||||||
|
*/
|
||||||
|
int mode = 0444;
|
||||||
|
snprintf(template, limit, "%s/%s",
|
||||||
|
get_object_directory(), pattern);
|
||||||
|
fd = git_mkstemp_mode(template, mode);
|
||||||
|
if (0 <= fd)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
/* slow path */
|
||||||
|
/* some mkstemp implementations erase template on failure */
|
||||||
|
snprintf(template, limit, "%s/%s",
|
||||||
|
get_object_directory(), pattern);
|
||||||
|
safe_create_leading_directories(template);
|
||||||
|
return xmkstemp_mode(template, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
snprintf(name, namesz, "%s/pack/pack-%s.keep",
|
||||||
|
get_object_directory(), sha1_to_hex(sha1));
|
||||||
|
fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||||
|
if (0 <= fd)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
/* slow path */
|
||||||
|
safe_create_leading_directories(name);
|
||||||
|
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
char *get_index_file(void)
|
char *get_index_file(void)
|
||||||
{
|
{
|
||||||
if (!git_index_file)
|
if (!git_index_file)
|
||||||
|
@ -421,6 +421,7 @@ extern ssize_t xwrite(int fd, const void *buf, size_t len);
|
|||||||
extern int xdup(int fd);
|
extern int xdup(int fd);
|
||||||
extern FILE *xfdopen(int fd, const char *mode);
|
extern FILE *xfdopen(int fd, const char *mode);
|
||||||
extern int xmkstemp(char *template);
|
extern int xmkstemp(char *template);
|
||||||
|
extern int xmkstemp_mode(char *template, int mode);
|
||||||
extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
|
extern int odb_mkstemp(char *template, size_t limit, const char *pattern);
|
||||||
extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1);
|
extern int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1);
|
||||||
|
|
||||||
|
113
path.c
113
path.c
@ -161,119 +161,6 @@ char *git_path_submodule(const char *path, const char *fmt, ...)
|
|||||||
return cleanup_path(pathname);
|
return cleanup_path(pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* git_mkstemp() - create tmp file honoring TMPDIR variable */
|
|
||||||
int git_mkstemp(char *path, size_t len, const char *template)
|
|
||||||
{
|
|
||||||
const char *tmp;
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
tmp = getenv("TMPDIR");
|
|
||||||
if (!tmp)
|
|
||||||
tmp = "/tmp";
|
|
||||||
n = snprintf(path, len, "%s/%s", tmp, template);
|
|
||||||
if (len <= n) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return mkstemp(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */
|
|
||||||
int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
|
|
||||||
{
|
|
||||||
const char *tmp;
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
tmp = getenv("TMPDIR");
|
|
||||||
if (!tmp)
|
|
||||||
tmp = "/tmp";
|
|
||||||
n = snprintf(path, len, "%s/%s", tmp, template);
|
|
||||||
if (len <= n) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return mkstemps(path, suffix_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adapted from libiberty's mkstemp.c. */
|
|
||||||
|
|
||||||
#undef TMP_MAX
|
|
||||||
#define TMP_MAX 16384
|
|
||||||
|
|
||||||
int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
|
|
||||||
{
|
|
||||||
static const char letters[] =
|
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
||||||
"0123456789";
|
|
||||||
static const int num_letters = 62;
|
|
||||||
uint64_t value;
|
|
||||||
struct timeval tv;
|
|
||||||
char *template;
|
|
||||||
size_t len;
|
|
||||||
int fd, count;
|
|
||||||
|
|
||||||
len = strlen(pattern);
|
|
||||||
|
|
||||||
if (len < 6 + suffix_len) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Replace pattern's XXXXXX characters with randomness.
|
|
||||||
* Try TMP_MAX different filenames.
|
|
||||||
*/
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
|
|
||||||
template = &pattern[len - 6 - suffix_len];
|
|
||||||
for (count = 0; count < TMP_MAX; ++count) {
|
|
||||||
uint64_t v = value;
|
|
||||||
/* Fill in the random bits. */
|
|
||||||
template[0] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
template[1] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
template[2] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
template[3] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
template[4] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
template[5] = letters[v % num_letters]; v /= num_letters;
|
|
||||||
|
|
||||||
fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
|
|
||||||
if (fd > 0)
|
|
||||||
return fd;
|
|
||||||
/*
|
|
||||||
* Fatal error (EPERM, ENOSPC etc).
|
|
||||||
* It doesn't make sense to loop.
|
|
||||||
*/
|
|
||||||
if (errno != EEXIST)
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
* This is a random value. It is only necessary that
|
|
||||||
* the next TMP_MAX values generated by adding 7777 to
|
|
||||||
* VALUE are different with (module 2^32).
|
|
||||||
*/
|
|
||||||
value += 7777;
|
|
||||||
}
|
|
||||||
/* We return the null string if we can't find a unique file name. */
|
|
||||||
pattern[0] = '\0';
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int git_mkstemp_mode(char *pattern, int mode)
|
|
||||||
{
|
|
||||||
/* mkstemp is just mkstemps with no suffix */
|
|
||||||
return git_mkstemps_mode(pattern, 0, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int gitmkstemps(char *pattern, int suffix_len)
|
|
||||||
{
|
|
||||||
return git_mkstemps_mode(pattern, suffix_len, 0600);
|
|
||||||
}
|
|
||||||
|
|
||||||
int validate_headref(const char *path)
|
int validate_headref(const char *path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
26
sha1_file.c
26
sha1_file.c
@ -578,6 +578,21 @@ void release_pack_memory(size_t need, int fd)
|
|||||||
; /* nothing */
|
; /* nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *xmmap(void *start, size_t length,
|
||||||
|
int prot, int flags, int fd, off_t offset)
|
||||||
|
{
|
||||||
|
void *ret = mmap(start, length, prot, flags, fd, offset);
|
||||||
|
if (ret == MAP_FAILED) {
|
||||||
|
if (!length)
|
||||||
|
return NULL;
|
||||||
|
release_pack_memory(length, fd);
|
||||||
|
ret = mmap(start, length, prot, flags, fd, offset);
|
||||||
|
if (ret == MAP_FAILED)
|
||||||
|
die_errno("Out of memory? mmap failed");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void close_pack_windows(struct packed_git *p)
|
void close_pack_windows(struct packed_git *p)
|
||||||
{
|
{
|
||||||
while (p->windows) {
|
while (p->windows) {
|
||||||
@ -803,11 +818,22 @@ static struct packed_git *alloc_packed_git(int extra)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void try_to_free_pack_memory(size_t size)
|
||||||
|
{
|
||||||
|
release_pack_memory(size, -1);
|
||||||
|
}
|
||||||
|
|
||||||
struct packed_git *add_packed_git(const char *path, int path_len, int local)
|
struct packed_git *add_packed_git(const char *path, int path_len, int local)
|
||||||
{
|
{
|
||||||
|
static int have_set_try_to_free_routine;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct packed_git *p = alloc_packed_git(path_len + 2);
|
struct packed_git *p = alloc_packed_git(path_len + 2);
|
||||||
|
|
||||||
|
if (!have_set_try_to_free_routine) {
|
||||||
|
have_set_try_to_free_routine = 1;
|
||||||
|
set_try_to_free_routine(try_to_free_pack_memory);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure a corresponding .pack file exists and that
|
* Make sure a corresponding .pack file exists and that
|
||||||
* the index looks sane.
|
* the index looks sane.
|
||||||
|
18
sha1_name.c
18
sha1_name.c
@ -936,6 +936,24 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int strbuf_branchname(struct strbuf *sb, const char *name)
|
||||||
|
{
|
||||||
|
int len = strlen(name);
|
||||||
|
if (interpret_branch_name(name, sb) == len)
|
||||||
|
return 0;
|
||||||
|
strbuf_add(sb, name, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
|
||||||
|
{
|
||||||
|
strbuf_branchname(sb, name);
|
||||||
|
if (name[0] == '-')
|
||||||
|
return CHECK_REF_FORMAT_ERROR;
|
||||||
|
strbuf_splice(sb, 0, 0, "refs/heads/", 11);
|
||||||
|
return check_ref_format(sb->buf);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is like "get_sha1_basic()", except it allows "sha1 expressions",
|
* This is like "get_sha1_basic()", except it allows "sha1 expressions",
|
||||||
* notably "xyz^" for "parent of xyz"
|
* notably "xyz^" for "parent of xyz"
|
||||||
|
18
strbuf.c
18
strbuf.c
@ -386,21 +386,3 @@ int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint)
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int strbuf_branchname(struct strbuf *sb, const char *name)
|
|
||||||
{
|
|
||||||
int len = strlen(name);
|
|
||||||
if (interpret_branch_name(name, sb) == len)
|
|
||||||
return 0;
|
|
||||||
strbuf_add(sb, name, len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
|
|
||||||
{
|
|
||||||
strbuf_branchname(sb, name);
|
|
||||||
if (name[0] == '-')
|
|
||||||
return CHECK_REF_FORMAT_ERROR;
|
|
||||||
strbuf_splice(sb, 0, 0, "refs/heads/", 11);
|
|
||||||
return check_ref_format(sb->buf);
|
|
||||||
}
|
|
||||||
|
230
wrapper.c
230
wrapper.c
@ -3,12 +3,11 @@
|
|||||||
*/
|
*/
|
||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
|
|
||||||
static void try_to_free_builtin(size_t size)
|
static void do_nothing(size_t size)
|
||||||
{
|
{
|
||||||
release_pack_memory(size, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void (*try_to_free_routine)(size_t size) = try_to_free_builtin;
|
static void (*try_to_free_routine)(size_t size) = do_nothing;
|
||||||
|
|
||||||
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
|
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
|
||||||
{
|
{
|
||||||
@ -108,21 +107,6 @@ void *xcalloc(size_t nmemb, size_t size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *xmmap(void *start, size_t length,
|
|
||||||
int prot, int flags, int fd, off_t offset)
|
|
||||||
{
|
|
||||||
void *ret = mmap(start, length, prot, flags, fd, offset);
|
|
||||||
if (ret == MAP_FAILED) {
|
|
||||||
if (!length)
|
|
||||||
return NULL;
|
|
||||||
release_pack_memory(length, fd);
|
|
||||||
ret = mmap(start, length, prot, flags, fd, offset);
|
|
||||||
if (ret == MAP_FAILED)
|
|
||||||
die_errno("Out of memory? mmap failed");
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xread() is the same a read(), but it automatically restarts read()
|
* xread() is the same a read(), but it automatically restarts read()
|
||||||
* operations with a recoverable error (EAGAIN and EINTR). xread()
|
* operations with a recoverable error (EAGAIN and EINTR). xread()
|
||||||
@ -219,6 +203,119 @@ int xmkstemp(char *template)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* git_mkstemp() - create tmp file honoring TMPDIR variable */
|
||||||
|
int git_mkstemp(char *path, size_t len, const char *template)
|
||||||
|
{
|
||||||
|
const char *tmp;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
tmp = getenv("TMPDIR");
|
||||||
|
if (!tmp)
|
||||||
|
tmp = "/tmp";
|
||||||
|
n = snprintf(path, len, "%s/%s", tmp, template);
|
||||||
|
if (len <= n) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return mkstemp(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */
|
||||||
|
int git_mkstemps(char *path, size_t len, const char *template, int suffix_len)
|
||||||
|
{
|
||||||
|
const char *tmp;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
tmp = getenv("TMPDIR");
|
||||||
|
if (!tmp)
|
||||||
|
tmp = "/tmp";
|
||||||
|
n = snprintf(path, len, "%s/%s", tmp, template);
|
||||||
|
if (len <= n) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return mkstemps(path, suffix_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adapted from libiberty's mkstemp.c. */
|
||||||
|
|
||||||
|
#undef TMP_MAX
|
||||||
|
#define TMP_MAX 16384
|
||||||
|
|
||||||
|
int git_mkstemps_mode(char *pattern, int suffix_len, int mode)
|
||||||
|
{
|
||||||
|
static const char letters[] =
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"0123456789";
|
||||||
|
static const int num_letters = 62;
|
||||||
|
uint64_t value;
|
||||||
|
struct timeval tv;
|
||||||
|
char *template;
|
||||||
|
size_t len;
|
||||||
|
int fd, count;
|
||||||
|
|
||||||
|
len = strlen(pattern);
|
||||||
|
|
||||||
|
if (len < 6 + suffix_len) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(&pattern[len - 6 - suffix_len], "XXXXXX", 6)) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace pattern's XXXXXX characters with randomness.
|
||||||
|
* Try TMP_MAX different filenames.
|
||||||
|
*/
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
value = ((size_t)(tv.tv_usec << 16)) ^ tv.tv_sec ^ getpid();
|
||||||
|
template = &pattern[len - 6 - suffix_len];
|
||||||
|
for (count = 0; count < TMP_MAX; ++count) {
|
||||||
|
uint64_t v = value;
|
||||||
|
/* Fill in the random bits. */
|
||||||
|
template[0] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[1] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[2] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[3] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[4] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
template[5] = letters[v % num_letters]; v /= num_letters;
|
||||||
|
|
||||||
|
fd = open(pattern, O_CREAT | O_EXCL | O_RDWR, mode);
|
||||||
|
if (fd > 0)
|
||||||
|
return fd;
|
||||||
|
/*
|
||||||
|
* Fatal error (EPERM, ENOSPC etc).
|
||||||
|
* It doesn't make sense to loop.
|
||||||
|
*/
|
||||||
|
if (errno != EEXIST)
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
* This is a random value. It is only necessary that
|
||||||
|
* the next TMP_MAX values generated by adding 7777 to
|
||||||
|
* VALUE are different with (module 2^32).
|
||||||
|
*/
|
||||||
|
value += 7777;
|
||||||
|
}
|
||||||
|
/* We return the null string if we can't find a unique file name. */
|
||||||
|
pattern[0] = '\0';
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_mkstemp_mode(char *pattern, int mode)
|
||||||
|
{
|
||||||
|
/* mkstemp is just mkstemps with no suffix */
|
||||||
|
return git_mkstemps_mode(pattern, 0, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int gitmkstemps(char *pattern, int suffix_len)
|
||||||
|
{
|
||||||
|
return git_mkstemps_mode(pattern, suffix_len, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
int xmkstemp_mode(char *template, int mode)
|
int xmkstemp_mode(char *template, int mode)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@ -229,103 +326,6 @@ int xmkstemp_mode(char *template, int mode)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* zlib wrappers to make sure we don't silently miss errors
|
|
||||||
* at init time.
|
|
||||||
*/
|
|
||||||
void git_inflate_init(z_streamp strm)
|
|
||||||
{
|
|
||||||
const char *err;
|
|
||||||
|
|
||||||
switch (inflateInit(strm)) {
|
|
||||||
case Z_OK:
|
|
||||||
return;
|
|
||||||
|
|
||||||
case Z_MEM_ERROR:
|
|
||||||
err = "out of memory";
|
|
||||||
break;
|
|
||||||
case Z_VERSION_ERROR:
|
|
||||||
err = "wrong version";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
err = "error";
|
|
||||||
}
|
|
||||||
die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
|
|
||||||
}
|
|
||||||
|
|
||||||
void git_inflate_end(z_streamp strm)
|
|
||||||
{
|
|
||||||
if (inflateEnd(strm) != Z_OK)
|
|
||||||
error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
int git_inflate(z_streamp strm, int flush)
|
|
||||||
{
|
|
||||||
int ret = inflate(strm, flush);
|
|
||||||
const char *err;
|
|
||||||
|
|
||||||
switch (ret) {
|
|
||||||
/* Out of memory is fatal. */
|
|
||||||
case Z_MEM_ERROR:
|
|
||||||
die("inflate: out of memory");
|
|
||||||
|
|
||||||
/* Data corruption errors: we may want to recover from them (fsck) */
|
|
||||||
case Z_NEED_DICT:
|
|
||||||
err = "needs dictionary"; break;
|
|
||||||
case Z_DATA_ERROR:
|
|
||||||
err = "data stream error"; break;
|
|
||||||
case Z_STREAM_ERROR:
|
|
||||||
err = "stream consistency error"; break;
|
|
||||||
default:
|
|
||||||
err = "unknown error"; break;
|
|
||||||
|
|
||||||
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
|
|
||||||
case Z_BUF_ERROR:
|
|
||||||
case Z_OK:
|
|
||||||
case Z_STREAM_END:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int odb_mkstemp(char *template, size_t limit, const char *pattern)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
/*
|
|
||||||
* we let the umask do its job, don't try to be more
|
|
||||||
* restrictive except to remove write permission.
|
|
||||||
*/
|
|
||||||
int mode = 0444;
|
|
||||||
snprintf(template, limit, "%s/%s",
|
|
||||||
get_object_directory(), pattern);
|
|
||||||
fd = git_mkstemp_mode(template, mode);
|
|
||||||
if (0 <= fd)
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
/* slow path */
|
|
||||||
/* some mkstemp implementations erase template on failure */
|
|
||||||
snprintf(template, limit, "%s/%s",
|
|
||||||
get_object_directory(), pattern);
|
|
||||||
safe_create_leading_directories(template);
|
|
||||||
return xmkstemp_mode(template, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
snprintf(name, namesz, "%s/pack/pack-%s.keep",
|
|
||||||
get_object_directory(), sha1_to_hex(sha1));
|
|
||||||
fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
|
||||||
if (0 <= fd)
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
/* slow path */
|
|
||||||
safe_create_leading_directories(name);
|
|
||||||
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int warn_if_unremovable(const char *op, const char *file, int rc)
|
static int warn_if_unremovable(const char *op, const char *file, int rc)
|
||||||
{
|
{
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
61
zlib.c
Normal file
61
zlib.c
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* zlib wrappers to make sure we don't silently miss errors
|
||||||
|
* at init time.
|
||||||
|
*/
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
|
void git_inflate_init(z_streamp strm)
|
||||||
|
{
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
switch (inflateInit(strm)) {
|
||||||
|
case Z_OK:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
err = "out of memory";
|
||||||
|
break;
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
err = "wrong version";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = "error";
|
||||||
|
}
|
||||||
|
die("inflateInit: %s (%s)", err, strm->msg ? strm->msg : "no message");
|
||||||
|
}
|
||||||
|
|
||||||
|
void git_inflate_end(z_streamp strm)
|
||||||
|
{
|
||||||
|
if (inflateEnd(strm) != Z_OK)
|
||||||
|
error("inflateEnd: %s", strm->msg ? strm->msg : "failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
int git_inflate(z_streamp strm, int flush)
|
||||||
|
{
|
||||||
|
int ret = inflate(strm, flush);
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
/* Out of memory is fatal. */
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
die("inflate: out of memory");
|
||||||
|
|
||||||
|
/* Data corruption errors: we may want to recover from them (fsck) */
|
||||||
|
case Z_NEED_DICT:
|
||||||
|
err = "needs dictionary"; break;
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
err = "data stream error"; break;
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
err = "stream consistency error"; break;
|
||||||
|
default:
|
||||||
|
err = "unknown error"; break;
|
||||||
|
|
||||||
|
/* Z_BUF_ERROR: normal, needs more space in the output buffer */
|
||||||
|
case Z_BUF_ERROR:
|
||||||
|
case Z_OK:
|
||||||
|
case Z_STREAM_END:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
error("inflate: %s (%s)", err, strm->msg ? strm->msg : "no message");
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user