Rusty Russell [Thu, 17 Mar 2011 11:42:21 +0000 (22:12 +1030)]
tdb2: make sure records with extra padding have a 0 byte.
As detailed in doc/design.lyx section 2.16 "Record Headers Are Not
Expandible", we make sure that if there is padding at the end of a record,
the first byte of padding is a zero.
Rusty Russell [Thu, 17 Mar 2011 11:42:21 +0000 (22:12 +1030)]
tdb2: feature support.
As detailed in doc/design.lyx section 2.15 "Extending The Header Is
Difficult"; we add features_used and features_offered fields to the
header, so we can identify if we add new features, and then if someone
opens it who doesn't understand that feature.
Rusty Russell [Thu, 17 Mar 2011 11:42:22 +0000 (22:12 +1030)]
ccanlint: fix gdb line in tests_pass helper.
Recent changes shifted line numbers in tap.c, so the break is now in
the wrong place. We should probably have an explicit function we can
breakpoint instead.
Rusty Russell [Thu, 17 Mar 2011 11:42:22 +0000 (22:12 +1030)]
str: provide checks for ctype.h char functions, and strstr and strchr functions.
In the former case, we were bitten by the fact that you don't pass a char
to isalpha() et al: you pass an int. This means on most platforms you want
to do:
if (isalpha((unsigned char)c)) ...
Insane? Yes, but I assure you I'm not making this up.
Similarly, I've always wanted strstr, strchr and strrchr to return
const char * when given a const char * argument to search, to avoid
constness leak.
In both cases, the actual versions from the headers may be macros, so
we need to be very careful overriding them. The result is that they
become out-of-line functions which is unacceptable for general
performance.
So we only activate these when CCAN_STR_DEBUG is defined.
Rusty Russell [Wed, 2 Mar 2011 00:15:51 +0000 (10:45 +1030)]
configurator: more robust test for HAVE_NESTED_FUNCTIONS
Thanks to Andreas Schlick, we have a nicer test for when gcc warns about
trampolines (gcc 4.6's -Wtrampolines). This works at any optimization level,
and means when that warning is enabled we recognize that we shouldn't allow
nested functions.
Rusty Russell [Tue, 1 Mar 2011 12:49:19 +0000 (23:19 +1030)]
tdb2: rework hash.c functions to return enum TDB_ERROR.
This time we have to use our tri-value "tdb_bool_err" type to indicate
true, false, or error, which now allows us to correctly handle errors
in key matching (rather than treating it as a non-match).
Rusty Russell [Tue, 1 Mar 2011 12:49:19 +0000 (23:19 +1030)]
tdb2: rework some io.c functions to encode errors in their pointer returns.
This causes a subtle enhancement in tdb_direct(): it previously
returned NULL on both "can't use direct access" or "some error
occurred", as the caller always uses read/write functions as a
fallback anyway. Now we distinguish the error case.
Rusty Russell [Tue, 1 Mar 2011 12:49:19 +0000 (23:19 +1030)]
tdb2: rework io functions to return enum TDB_ERROR.
We have a series of I/O functions which change depending on whether we're
inside a transaction or not. This makes them return enum TDB_ERROR instead
of int.
Rusty Russell [Tue, 1 Mar 2011 12:49:19 +0000 (23:19 +1030)]
tdb2: restore file filling code.
This snuck in fe55330a which added the stats attribute. Without it,
TDB works but is vulnerable to segmenation faults or write errors when
disk is exhausted.
Rusty Russell [Tue, 1 Mar 2011 12:49:19 +0000 (23:19 +1030)]
tdb2: Internal error helpers.
I use the "high pointers hold error numbers" trick, and also make
tdb_logerr return the error code, which enables the common case of
"return tdb_logerr(...)".
Rusty Russell [Tue, 1 Mar 2011 12:49:20 +0000 (23:19 +1030)]
tdb2: simplify logging levels, rename TDB_DEBUG_* to TDB_LOG_*
It was never clear to me which levels should be used for what cases.
I can only usefully distinguish three at the moment:
(1) TDB errors, which render the TDB unreliable.
(2) TDB user errors, caused by API misuse.
(3) TDB notifications of strange behaviour, from which we have recovered.
Rusty Russell [Tue, 1 Mar 2011 12:49:20 +0000 (23:19 +1030)]
tdb2: use failtest for opening and checking database.
This is a fairly sophisticated use of failtest:
1) There are a few places where we can inject failures without revealing it
at the API level, eg. opening /dev/urandom, or allocation failure in logging.
2) We want to be sure that (almost) all failures cause a message to be logged.
3) We need to exit as soon as possible when a failure is injected, to avoid
combinatorial explosion.
4) We don't want to simply exit on any log message, since we want to be sure
that cleanup happens.
This test found four different bugs failure paths. Erk!
Rusty Russell [Tue, 1 Mar 2011 07:20:32 +0000 (17:50 +1030)]
ccanlint: check for #ifdef
Old habits die hard; it's better to use #if <FEATURE> than #ifdef <FEATURE>;
they're similar, because undefined identifiers evaluate to zero, but with
GCC's -Wundef flag you can detect mis-spelled or missing features with
#if.
autoconf-style config.h leave unset features undefined, so this works for
those config.h too.
Rusty Russell [Tue, 1 Mar 2011 07:18:11 +0000 (17:48 +1030)]
ccanlint: create reduce-feature config.h
A common mistake is not to try compiling with features disabled in
config.h. The ideal case would determine how features interact and
test all combinations of them: this simply disables any features
mentioned in the code which were previously enabled.
Rusty Russell [Tue, 1 Mar 2011 05:31:20 +0000 (16:01 +1030)]
ccanlint: handle weird directories.
David Gibson reports (and I confirmed) that running ccanlint in /tmp
causes an very uninformative segv. Fix that, and add a more useful message,
as well as delaying recursing until we're confident there's code around.