*/
#include "cache.h"
+static void try_to_free_builtin(size_t size)
+{
+ release_pack_memory(size, -1);
+}
+
+static void (*try_to_free_routine)(size_t size) = try_to_free_builtin;
+
+try_to_free_t set_try_to_free_routine(try_to_free_t routine)
+{
+ try_to_free_t old = try_to_free_routine;
+ try_to_free_routine = routine;
+ return old;
+}
+
char *xstrdup(const char *str)
{
char *ret = strdup(str);
if (!ret) {
- release_pack_memory(strlen(str) + 1, -1);
+ try_to_free_routine(strlen(str) + 1);
ret = strdup(str);
if (!ret)
die("Out of memory, strdup failed");
if (!ret && !size)
ret = malloc(1);
if (!ret) {
- release_pack_memory(size, -1);
+ try_to_free_routine(size);
ret = malloc(size);
if (!ret && !size)
ret = malloc(1);
if (!ret)
- die("Out of memory, malloc failed");
+ die("Out of memory, malloc failed (tried to allocate %lu bytes)",
+ (unsigned long)size);
}
#ifdef XMALLOC_POISON
memset(ret, 0xA5, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret) {
- release_pack_memory(size, -1);
+ try_to_free_routine(size);
ret = realloc(ptr, size);
if (!ret && !size)
ret = realloc(ptr, 1);
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
if (!ret) {
- release_pack_memory(nmemb * size, -1);
+ try_to_free_routine(nmemb * size);
ret = calloc(nmemb, size);
if (!ret && (!nmemb || !size))
ret = calloc(1, 1);
return fd;
}
+int xmkstemp_mode(char *template, int mode)
+{
+ int fd;
+
+ fd = git_mkstemp_mode(template, mode);
+ if (fd < 0)
+ die_errno("Unable to create temporary file");
+ return fd;
+}
+
/*
* zlib wrappers to make sure we don't silently miss errors
* at init time.
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 = mkstemp(template);
+ fd = git_mkstemp_mode(template, mode);
if (0 <= fd)
return fd;
snprintf(template, limit, "%s/%s",
get_object_directory(), pattern);
safe_create_leading_directories(template);
- return xmkstemp(template);
+ return xmkstemp_mode(template, mode);
}
int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)
return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
}
-int unlink_or_warn(const char *file)
+static int warn_if_unremovable(const char *op, const char *file, int rc)
{
- int rc = unlink(file);
-
if (rc < 0) {
int err = errno;
if (ENOENT != err) {
- warning("unable to unlink %s: %s",
- file, strerror(errno));
+ warning("unable to %s %s: %s",
+ op, file, strerror(errno));
errno = err;
}
}
return rc;
}
+int unlink_or_warn(const char *file)
+{
+ return warn_if_unremovable("unlink", file, unlink(file));
+}
+
+int rmdir_or_warn(const char *file)
+{
+ return warn_if_unremovable("rmdir", file, rmdir(file));
+}
+
+int remove_or_warn(unsigned int mode, const char *file)
+{
+ return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);
+}