Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
/*
|
|
|
|
* Various trivial helper wrappers around standard functions
|
|
|
|
*/
|
|
|
|
#include "cache.h"
|
|
|
|
|
2010-11-06 22:00:38 +03:00
|
|
|
static void do_nothing(size_t size)
|
2010-03-24 23:22:34 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-11-06 22:00:38 +03:00
|
|
|
static void (*try_to_free_routine)(size_t size) = do_nothing;
|
2010-03-24 23:22:34 +03:00
|
|
|
|
2012-03-07 14:54:16 +04:00
|
|
|
static void memory_limit_check(size_t size)
|
|
|
|
{
|
|
|
|
static int limit = -1;
|
|
|
|
if (limit == -1) {
|
|
|
|
const char *env = getenv("GIT_ALLOC_LIMIT");
|
|
|
|
limit = env ? atoi(env) * 1024 : 0;
|
|
|
|
}
|
|
|
|
if (limit && size > limit)
|
|
|
|
die("attempting to allocate %"PRIuMAX" over limit %d",
|
|
|
|
(intmax_t)size, limit);
|
|
|
|
}
|
|
|
|
|
2010-05-08 19:13:49 +04:00
|
|
|
try_to_free_t set_try_to_free_routine(try_to_free_t routine)
|
2010-03-24 23:22:34 +03:00
|
|
|
{
|
2010-05-08 19:13:49 +04:00
|
|
|
try_to_free_t old = try_to_free_routine;
|
2010-12-21 20:24:18 +03:00
|
|
|
if (!routine)
|
|
|
|
routine = do_nothing;
|
2010-05-08 19:13:49 +04:00
|
|
|
try_to_free_routine = routine;
|
|
|
|
return old;
|
2010-03-24 23:22:34 +03:00
|
|
|
}
|
|
|
|
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
char *xstrdup(const char *str)
|
|
|
|
{
|
|
|
|
char *ret = strdup(str);
|
|
|
|
if (!ret) {
|
2010-03-24 23:22:34 +03:00
|
|
|
try_to_free_routine(strlen(str) + 1);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
ret = strdup(str);
|
|
|
|
if (!ret)
|
|
|
|
die("Out of memory, strdup failed");
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *xmalloc(size_t size)
|
|
|
|
{
|
2012-03-07 14:54:16 +04:00
|
|
|
void *ret;
|
|
|
|
|
|
|
|
memory_limit_check(size);
|
|
|
|
ret = malloc(size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
if (!ret && !size)
|
|
|
|
ret = malloc(1);
|
|
|
|
if (!ret) {
|
2010-03-24 23:22:34 +03:00
|
|
|
try_to_free_routine(size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
ret = malloc(size);
|
|
|
|
if (!ret && !size)
|
|
|
|
ret = malloc(1);
|
|
|
|
if (!ret)
|
2010-08-20 19:09:51 +04:00
|
|
|
die("Out of memory, malloc failed (tried to allocate %lu bytes)",
|
|
|
|
(unsigned long)size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
}
|
|
|
|
#ifdef XMALLOC_POISON
|
|
|
|
memset(ret, 0xA5, size);
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-01-26 21:24:12 +03:00
|
|
|
void *xmallocz(size_t size)
|
|
|
|
{
|
|
|
|
void *ret;
|
2010-10-11 06:59:26 +04:00
|
|
|
if (unsigned_add_overflows(size, 1))
|
2010-01-26 21:24:12 +03:00
|
|
|
die("Data too large to fit into virtual memory space.");
|
|
|
|
ret = xmalloc(size + 1);
|
|
|
|
((char*)ret)[size] = 0;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
/*
|
|
|
|
* xmemdupz() allocates (len + 1) bytes of memory, duplicates "len" bytes of
|
|
|
|
* "data" to the allocated memory, zero terminates the allocated memory,
|
|
|
|
* and returns a pointer to the allocated memory. If the allocation fails,
|
|
|
|
* the program dies.
|
|
|
|
*/
|
|
|
|
void *xmemdupz(const void *data, size_t len)
|
|
|
|
{
|
2010-01-26 21:24:12 +03:00
|
|
|
return memcpy(xmallocz(len), data, len);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
char *xstrndup(const char *str, size_t len)
|
|
|
|
{
|
|
|
|
char *p = memchr(str, '\0', len);
|
|
|
|
return xmemdupz(str, p ? p - str : len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *xrealloc(void *ptr, size_t size)
|
|
|
|
{
|
2012-03-07 14:54:16 +04:00
|
|
|
void *ret;
|
|
|
|
|
|
|
|
memory_limit_check(size);
|
|
|
|
ret = realloc(ptr, size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
if (!ret && !size)
|
|
|
|
ret = realloc(ptr, 1);
|
|
|
|
if (!ret) {
|
2010-03-24 23:22:34 +03:00
|
|
|
try_to_free_routine(size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
ret = realloc(ptr, size);
|
|
|
|
if (!ret && !size)
|
|
|
|
ret = realloc(ptr, 1);
|
|
|
|
if (!ret)
|
|
|
|
die("Out of memory, realloc failed");
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *xcalloc(size_t nmemb, size_t size)
|
|
|
|
{
|
2012-03-07 14:54:16 +04:00
|
|
|
void *ret;
|
|
|
|
|
|
|
|
memory_limit_check(size * nmemb);
|
|
|
|
ret = calloc(nmemb, size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
if (!ret && (!nmemb || !size))
|
|
|
|
ret = calloc(1, 1);
|
|
|
|
if (!ret) {
|
2010-03-24 23:22:34 +03:00
|
|
|
try_to_free_routine(nmemb * size);
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
ret = calloc(nmemb, size);
|
|
|
|
if (!ret && (!nmemb || !size))
|
|
|
|
ret = calloc(1, 1);
|
|
|
|
if (!ret)
|
|
|
|
die("Out of memory, calloc failed");
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* xread() is the same a read(), but it automatically restarts read()
|
|
|
|
* operations with a recoverable error (EAGAIN and EINTR). xread()
|
|
|
|
* DOES NOT GUARANTEE that "len" bytes is read even if the data is available.
|
|
|
|
*/
|
|
|
|
ssize_t xread(int fd, void *buf, size_t len)
|
|
|
|
{
|
|
|
|
ssize_t nr;
|
|
|
|
while (1) {
|
|
|
|
nr = read(fd, buf, len);
|
|
|
|
if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
|
|
|
|
continue;
|
|
|
|
return nr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* xwrite() is the same a write(), but it automatically restarts write()
|
|
|
|
* operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT
|
|
|
|
* GUARANTEE that "len" bytes is written even if the operation is successful.
|
|
|
|
*/
|
|
|
|
ssize_t xwrite(int fd, const void *buf, size_t len)
|
|
|
|
{
|
|
|
|
ssize_t nr;
|
|
|
|
while (1) {
|
|
|
|
nr = write(fd, buf, len);
|
|
|
|
if ((nr < 0) && (errno == EAGAIN || errno == EINTR))
|
|
|
|
continue;
|
|
|
|
return nr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-21 03:13:05 +04:00
|
|
|
ssize_t read_in_full(int fd, void *buf, size_t count)
|
|
|
|
{
|
|
|
|
char *p = buf;
|
|
|
|
ssize_t total = 0;
|
|
|
|
|
|
|
|
while (count > 0) {
|
|
|
|
ssize_t loaded = xread(fd, p, count);
|
read_in_full: always report errors
The read_in_full function repeatedly calls read() to fill a
buffer. If the first read() returns an error, we notify the
caller by returning the error. However, if we read some data
and then get an error on a subsequent read, we simply return
the amount of data that we did read, and the caller is
unaware of the error.
This makes the tradeoff that seeing the partial data is more
important than the fact that an error occurred. In practice,
this is generally not the case; we care more if an error
occurred, and should throw away any partial data.
I audited the current callers. In most cases, this will make
no difference at all, as they do:
if (read_in_full(fd, buf, size) != size)
error("short read");
However, it will help in a few cases:
1. In sha1_file.c:index_stream, we would fail to notice
errors in the incoming stream.
2. When reading symbolic refs in resolve_ref, we would
fail to notice errors and potentially use a truncated
ref name.
3. In various places, we will get much better error
messages. For example, callers of safe_read would
erroneously print "the remote end hung up unexpectedly"
instead of showing the read error.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-05-26 20:30:27 +04:00
|
|
|
if (loaded < 0)
|
|
|
|
return -1;
|
|
|
|
if (loaded == 0)
|
|
|
|
return total;
|
2008-07-21 03:13:05 +04:00
|
|
|
count -= loaded;
|
|
|
|
p += loaded;
|
|
|
|
total += loaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
ssize_t write_in_full(int fd, const void *buf, size_t count)
|
|
|
|
{
|
|
|
|
const char *p = buf;
|
|
|
|
ssize_t total = 0;
|
|
|
|
|
|
|
|
while (count > 0) {
|
|
|
|
ssize_t written = xwrite(fd, p, count);
|
|
|
|
if (written < 0)
|
|
|
|
return -1;
|
|
|
|
if (!written) {
|
|
|
|
errno = ENOSPC;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
count -= written;
|
|
|
|
p += written;
|
|
|
|
total += written;
|
|
|
|
}
|
|
|
|
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
int xdup(int fd)
|
|
|
|
{
|
|
|
|
int ret = dup(fd);
|
|
|
|
if (ret < 0)
|
2009-06-27 19:58:46 +04:00
|
|
|
die_errno("dup failed");
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
FILE *xfdopen(int fd, const char *mode)
|
|
|
|
{
|
|
|
|
FILE *stream = fdopen(fd, mode);
|
|
|
|
if (stream == NULL)
|
2009-06-27 19:58:46 +04:00
|
|
|
die_errno("Out of memory? fdopen failed");
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
|
|
|
int xmkstemp(char *template)
|
|
|
|
{
|
|
|
|
int fd;
|
2010-12-19 00:28:00 +03:00
|
|
|
char origtemplate[PATH_MAX];
|
|
|
|
strlcpy(origtemplate, template, sizeof(origtemplate));
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
|
|
|
|
fd = mkstemp(template);
|
2010-12-19 00:28:00 +03:00
|
|
|
if (fd < 0) {
|
|
|
|
int saved_errno = errno;
|
|
|
|
const char *nonrelative_template;
|
|
|
|
|
2012-12-19 00:51:35 +04:00
|
|
|
if (strlen(template) != strlen(origtemplate))
|
2010-12-19 00:28:00 +03:00
|
|
|
template = origtemplate;
|
|
|
|
|
2011-03-17 14:26:46 +03:00
|
|
|
nonrelative_template = absolute_path(template);
|
2010-12-19 00:28:00 +03:00
|
|
|
errno = saved_errno;
|
|
|
|
die_errno("Unable to create temporary file '%s'",
|
|
|
|
nonrelative_template);
|
|
|
|
}
|
Shrink the git binary a bit by avoiding unnecessary inline functions
So I was looking at the disgusting size of the git binary, and even with
the debugging removed, and using -Os instead of -O2, the size of the text
section was pretty high. In this day and age I guess almost a megabyte of
text isn't really all that surprising, but it still doesn't exactly make
me think "lean and mean".
With -Os, a surprising amount of text space is wasted on inline functions
that end up just being replicated multiple times, and where performance
really isn't a valid reason to inline them. In particular, the trivial
wrapper functions like "xmalloc()" are used _everywhere_, and making them
inline just duplicates the text (and the string we use to 'die()' on
failure) unnecessarily.
So this just moves them into a "wrapper.c" file, getting rid of a tiny bit
of unnecessary bloat. The following numbers are both with "CFLAGS=-Os":
Before:
[torvalds@woody git]$ size git
text data bss dec hex filename
700460 15160 292184 1007804 f60bc git
After:
[torvalds@woody git]$ size git
text data bss dec hex filename
670540 15160 292184 977884 eebdc git
so it saves almost 30k of text-space (it actually saves more than that
with the default -O2, but I don't think that's necessarily a very relevant
number from a "try to shrink git" standpoint).
It might conceivably have a performance impact, but none of this should be
_that_ performance critical. The real cost is not generally in the wrapper
anyway, but in the code it wraps (ie the cost of "xread()" is all in the
read itself, not in the trivial wrapping of it).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-06-22 23:19:25 +04:00
|
|
|
return fd;
|
|
|
|
}
|
2009-01-08 06:54:47 +03:00
|
|
|
|
2010-11-06 14:46:31 +03:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2010-02-23 01:32:13 +03:00
|
|
|
int xmkstemp_mode(char *template, int mode)
|
|
|
|
{
|
|
|
|
int fd;
|
2010-12-19 00:28:00 +03:00
|
|
|
char origtemplate[PATH_MAX];
|
|
|
|
strlcpy(origtemplate, template, sizeof(origtemplate));
|
2010-02-23 01:32:13 +03:00
|
|
|
|
|
|
|
fd = git_mkstemp_mode(template, mode);
|
2010-12-19 00:28:00 +03:00
|
|
|
if (fd < 0) {
|
|
|
|
int saved_errno = errno;
|
|
|
|
const char *nonrelative_template;
|
|
|
|
|
|
|
|
if (!template[0])
|
|
|
|
template = origtemplate;
|
|
|
|
|
2011-03-17 14:26:46 +03:00
|
|
|
nonrelative_template = absolute_path(template);
|
2010-12-19 00:28:00 +03:00
|
|
|
errno = saved_errno;
|
|
|
|
die_errno("Unable to create temporary file '%s'",
|
|
|
|
nonrelative_template);
|
|
|
|
}
|
2010-02-23 01:32:13 +03:00
|
|
|
return fd;
|
|
|
|
}
|
|
|
|
|
2010-03-26 18:25:32 +03:00
|
|
|
static int warn_if_unremovable(const char *op, const char *file, int rc)
|
2009-04-30 01:21:46 +04:00
|
|
|
{
|
|
|
|
if (rc < 0) {
|
|
|
|
int err = errno;
|
|
|
|
if (ENOENT != err) {
|
2010-03-26 18:25:32 +03:00
|
|
|
warning("unable to %s %s: %s",
|
|
|
|
op, file, strerror(errno));
|
2009-04-30 01:21:46 +04:00
|
|
|
errno = err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2010-03-26 18:25:32 +03:00
|
|
|
int unlink_or_warn(const char *file)
|
|
|
|
{
|
|
|
|
return warn_if_unremovable("unlink", file, unlink(file));
|
|
|
|
}
|
2010-03-26 18:25:33 +03:00
|
|
|
|
|
|
|
int rmdir_or_warn(const char *file)
|
|
|
|
{
|
|
|
|
return warn_if_unremovable("rmdir", file, rmdir(file));
|
|
|
|
}
|
2010-03-26 18:25:34 +03:00
|
|
|
|
|
|
|
int remove_or_warn(unsigned int mode, const char *file)
|
|
|
|
{
|
|
|
|
return S_ISGITLINK(mode) ? rmdir_or_warn(file) : unlink_or_warn(file);
|
|
|
|
}
|
2012-05-22 03:10:20 +04:00
|
|
|
|
2012-08-22 01:52:07 +04:00
|
|
|
void warn_on_inaccessible(const char *path)
|
|
|
|
{
|
|
|
|
warning(_("unable to access '%s': %s"), path, strerror(errno));
|
|
|
|
}
|
|
|
|
|
2012-08-21 10:10:59 +04:00
|
|
|
int access_or_warn(const char *path, int mode)
|
|
|
|
{
|
|
|
|
int ret = access(path, mode);
|
2012-10-14 04:03:07 +04:00
|
|
|
if (ret && errno != ENOENT && errno != ENOTDIR)
|
2012-08-22 01:52:07 +04:00
|
|
|
warn_on_inaccessible(path);
|
2012-08-21 10:10:59 +04:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-10-14 04:04:02 +04:00
|
|
|
int access_or_die(const char *path, int mode)
|
|
|
|
{
|
|
|
|
int ret = access(path, mode);
|
|
|
|
if (ret && errno != ENOENT && errno != ENOTDIR)
|
|
|
|
die_errno(_("unable to access '%s'"), path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2012-05-22 03:10:20 +04:00
|
|
|
struct passwd *xgetpwuid_self(void)
|
|
|
|
{
|
|
|
|
struct passwd *pw;
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
pw = getpwuid(getuid());
|
|
|
|
if (!pw)
|
|
|
|
die(_("unable to look up current user in the passwd file: %s"),
|
|
|
|
errno ? strerror(errno) : _("no such user"));
|
|
|
|
return pw;
|
|
|
|
}
|