Rusty Russell [Mon, 13 Oct 2025 03:38:56 +0000 (14:08 +1030)]
global: avoid using sprintf.
snprintf has different footguns, but MacOS started complaining, a-la:
Core Lightning fails to compile on macOS with the latest Command Line Tools (macOS 15 SDK) due to sprintf being marked as deprecated and -Werror treating the deprecation as a compilation error.
```
ccan/ccan/closefrom/closefrom.c:83:2: error: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Werror,-Wdeprecated-declarations]
83 | sprintf(dnam, "/proc/%ld/fd", (long) getpid());
| ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:278:1: note: 'sprintf' has been explicitly marked deprecated here
278 | deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
| ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:218:48: note: expanded from macro 'deprecated_msg'
218 | #define deprecated_msg(_msg) attribute((deprecated(_msg)))
| ^
ccan/ccan/closefrom/closefrom.c:162:2: error: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Werror,-Wdeprecated-declarations]
162 | sprintf(dnam, "/proc/%ld/fd", (long) getpid());
| ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/_stdio.h:278:1: note: 'sprintf' has been explicitly marked deprecated here
278 | deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
| ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:218:48: note: expanded from macro 'deprecated_msg'
218 | #define deprecated_msg(_msg) attribute((deprecated(_msg)))
| ^
2 errors generated.
make: *** [ccan-closefrom.o] Error 1
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 29 Sep 2025 01:37:01 +0000 (11:07 +0930)]
ccan/io: fix occasional immediate close after io_shutdown()
If we're doing a duplex connection, we could be still trying to write:
that will fail (since we called shutdown on the write side), and we'll
respond by closing the socket.
The reason we're doing shutdown() is to ensure the final bytes are
written: doing a close() breaks this, and so the result is lost final
bytes.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Matt Whitlock [Mon, 14 Jul 2025 10:02:58 +0000 (06:02 -0400)]
json_escape: add json_escape_unescape_len()
Lacking a variant of json_escape_unescape() that takes a sized span,
the common case of unescaping a JSON string that is embedded inside a
larger buffer is forced to make a copy of the escaped string so as to
terminate it with a NUL character. This extra copy can be avoided if
we can pass an explicit length to the unescaping function.
Also, a drive-by fix: shrink the returned unescaped string to fit its
contents, which can save the caller a subsequent call to strlen().
David Gibson [Sat, 14 Jun 2025 05:44:43 +0000 (15:44 +1000)]
Remove ccodearchive.net references
Our former website ccodearchive.net has been taken over by domain
squatters, who've put up a near-duplicate of the former site with sneeaky
advertising links inserted. No idea if they've also subverted the actual
code, but it's possible.
There is, alas, not much we can do about that. We can, at least, stop
linking to it in the repository though. So, remove all references to the
now untrustworthy website.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Rusty Russell [Fri, 13 Jun 2025 02:13:20 +0000 (11:43 +0930)]
fdpass: fix complilation on FreeBSD.
```
cc ccan/ccan/fdpass/fdpass.c
ccan/ccan/fdpass/fdpass.c:16:12: error: use of undeclared identifier 'u_long'; did you mean 'long'?
char buf[CMSG_SPACE(sizeof(fd))];
^
/usr/include/sys/socket.h:577:25: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:16:12: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:577:25: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:16:12: error: use of undeclared identifier 'u_long'; did you mean 'long'?
/usr/include/sys/socket.h:577:58: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:16:12: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:577:58: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:26:19: error: use of undeclared identifier 'u_long'; did you mean 'long'?
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
^
/usr/include/sys/socket.h:578:23: note: expanded from macro 'CMSG_LEN'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:26:19: error: use of undeclared identifier 'u_long'
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
^
/usr/include/sys/socket.h:578:23: note: expanded from macro 'CMSG_LEN'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:26:19: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:578:23: note: expanded from macro 'CMSG_LEN'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:27:9: error: use of undeclared identifier 'u_long'; did you mean 'long'?
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
^
/usr/include/sys/socket.h:554:6: note: expanded from macro 'CMSG_DATA'
_ALIGN(sizeof(struct cmsghdr)))
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:27:9: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:554:6: note: expanded from macro 'CMSG_DATA'
_ALIGN(sizeof(struct cmsghdr)))
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:53:12: error: use of undeclared identifier 'u_long'; did you mean 'long'?
char buf[CMSG_SPACE(sizeof(fd))];
^
/usr/include/sys/socket.h:577:25: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:53:12: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:577:25: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:53:12: error: use of undeclared identifier 'u_long'; did you mean 'long'?
/usr/include/sys/socket.h:577:58: note: expanded from macro 'CMSG_SPACE'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:74:27: error: use of undeclared identifier 'u_long'; did you mean 'long'?
|| cmsg->cmsg_len != CMSG_LEN(sizeof(fd))
^
/usr/include/sys/socket.h:578:23: note: expanded from macro 'CMSG_LEN'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:74:27: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:578:23: note: expanded from macro 'CMSG_LEN'
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:81:14: error: use of undeclared identifier 'u_long'; did you mean 'long'?
memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
^
/usr/include/sys/socket.h:554:6: note: expanded from macro 'CMSG_DATA'
_ALIGN(sizeof(struct cmsghdr)))
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
ccan/ccan/fdpass/fdpass.c:81:14: error: use of undeclared identifier 'u_long'
/usr/include/sys/socket.h:554:6: note: expanded from macro 'CMSG_DATA'
_ALIGN(sizeof(struct cmsghdr)))
^
/usr/include/machine/_align.h:45:22: note: expanded from macro '_ALIGN'
^
16 errors generated.
gmake: *** [Makefile:994: ccan-fdpass.o] Error 1
```
Reported-by: https://github.com/21M4TW Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 12 Aug 2024 05:34:00 +0000 (15:04 +0930)]
htable: separate htable_type constructors to clarify duplicate keys.
Most hash tables do not want duplicates, so specify this
at declaration time. This way you crash should such a thing
be inserted, not have some subtle behavior you didn't expect!
Also disable the functions depending on the type.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 24 Jun 2024 02:45:02 +0000 (12:15 +0930)]
io: add benchmark for large poll.
This simulates a performance issue reported in `connectd` for
lightningd with 900 fds: it's consuming 70% of a CPU, and strace shows
it getting a single fd (or two) from poll, doing a write (gossip store
streaming), then going back into poll.
I tested using 1000 x netcat from a machine on the same LAN:
```
remote$ for i in `seq 1000`; do sleep 0.1; nc 10.88.9.17 8888 </dev/null > /dev/null & done
```
Rusty Russell [Sun, 3 Mar 2024 22:33:11 +0000 (09:03 +1030)]
rune: make error message better when integer parameter is missing.
We say "is not an integer field" when a field is missing entirely,
which is technically true but confusing. Say "not present" like
every other condition does.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
David Gibson [Sat, 1 Jun 2024 09:03:27 +0000 (19:03 +1000)]
bitmap: Avoid shadowing type name with parameter name
'bitmap' is a typedef name in this module, and we also use it as a
parameter name in a bunch of places. Although that's possible, because
types and variables live in different namespaces, it's probably not that
wise. It also appears to trip warnings with at least some options and
compiler versions.
Reported-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Rusty Russell [Tue, 1 Aug 2023 01:43:53 +0000 (11:13 +0930)]
base64: fix for unsigned chars (e.g. ARM).
```
ccan/ccan/base64/base64.c:34:10: error: result of comparison of constant 255 with expression of type 'int8_t' (aka 'signed char') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
if (ret == (char)0xff) {
~~~ ^ ~~~~~~~~~~
ccan/ccan/base64/base64.c:44:57: error: result of comparison of constant 255 with expression of type 'const signed char' is always true [-Werror,-Wtautological-constant-out-of-range-compare]
return (maps->decode_map[(const unsigned char)b64char] != (char)0xff);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~
```
Reported-by: Christian Decker Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 9 Jan 2023 02:06:22 +0000 (12:36 +1030)]
tcon: fix warning when it's used with NULL on some gcc versions.
Seems to be happening with gcc 12.2.0-3ubuntu1:
```
lightningd/jsonrpc.c: In function ‘destroy_json_command’:
lightningd/jsonrpc.c:1180:63: error: the comparison will always evaluate as ‘false’ for the address of ‘canary’ will never be NULL [-Werror=address]
lightningd/jsonrpc.c:108:53: note: ‘canary’ declared here
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 9 Jan 2023 02:16:22 +0000 (12:46 +1030)]
idtree: make sanitizer happier about shifts.
```
/home/rusty/devel/cvs/ccan/ccan/idtree/test/run-wrap.c:/home/rusty/devel/cvs/ccan/ccan/idtree/idtree.c:76:21: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Mon, 9 Jan 2023 02:15:22 +0000 (12:45 +1030)]
version: fix version() function.
```
/home/rusty/devel/cvs/ccan/ccan/version/test/run.c:/home/rusty/devel/cvs/ccan/ccan/version/version.h:58:35: runtime error: left shift of 65535 by 16 places cannot be represented in type 'int'
```
Rusty Russell [Mon, 9 Jan 2023 02:09:22 +0000 (12:39 +1030)]
tcon: fix overzealous gcc 12.2.0 warning.
At least with -fsanitize=address -fno-sanitize-recover=address -fsanitize=undefined -fno-sanitize-recover=undefined:
```
/home/rusty/devel/cvs/ccan/ccan/tcon/test/compile_fail-container1.c:Compile gave warnings without -DFAIL:
In file included from /home/rusty/devel/cvs/ccan/ccan/tcon/test/compile_fail-container1.c:3:
/home/rusty/devel/cvs/ccan/ccan/tcon/tcon.h: In function ‘main’:
/home/rusty/devel/cvs/ccan/ccan/tcon/tcon.h:332:25: warning: ‘innerp’ may be used uninitialized [-Wmaybe-uninitialized]
332 | canary, tcon_container_of_((member_ptr), \
| ^~~~~~~~~~~~~~~~~~
/home/rusty/devel/cvs/ccan/ccan/tcon/tcon.h:335:21: note: by argument 1 of type ‘const void *’ to ‘tcon_container_of_’ declared here
335 | static inline void *tcon_container_of_(const void *member_ptr, size_t offset)
| ^~~~~~~~~~~~~~~~~~
/home/rusty/devel/cvs/ccan/ccan/tcon/test/compile_fail-container1.c:28:22: note: ‘ovar’ declared here
28 | struct outer ovar;
| ^~~~
Rusty Russell [Mon, 4 Jul 2022 00:11:57 +0000 (09:41 +0930)]
ccan/rune: compile without warnings on -O3.
```
ccan/ccan/rune/rune.c: In function ‘rune_alt_single_int’:
ccan/ccan/rune/rune.c:257:5: error: ‘runeval_int’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
257 | if (cond)
| ^
ccan/ccan/rune/rune.c:305:6: note: ‘runeval_int’ was declared here
305 | s64 runeval_int;
| ^~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [Makefile:919: ccan-rune-rune.o] Error 1
```
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Fri, 17 Jun 2022 04:34:14 +0000 (14:04 +0930)]
htable: opportunistically avoid delete marker.
Fairly cheap test, we can see a drop in initial re-inserting, probably
because it has just been cleaned at this point with the old code, but
generally we do better with churn.
I also tried a variant which only checked if next bucket was on same
cacheline, but no significant difference.
Rusty Russell [Mon, 13 Jun 2022 12:18:19 +0000 (21:48 +0930)]
htable: fix vanishing entries properly.
A hash table entry consists of the pointer, but we mask out bits which
are common to all pointers, and replace them with hash bits.
The entry values 0 and 1 are special, meaning "empty" and "deleted"
respectively.
However, if a hash has mainly zero bits, and an pointer's non-shared
bits are all zero, we can create an entry which looks empty or
deleted.
The solution in this case is to share another bit (there must be some
bit which is not zero, since we don't allow 0 and 1 as pointers in the
hash table).
It's unusual, so I put this in a cold function: it shares code with
the existing "oh, we need to reduce the common bits, since this new
pointer doesn't look like the previous ones" case.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Except for:
- Leaves the test behind though (which fail!
- Leaves the reversion of 0b93bd102aad6b61f1e569fb12aabc6352a1d7cd, since
we're about to fix it, and properly!
Rusty Russell [Thu, 9 Jun 2022 03:12:31 +0000 (12:42 +0930)]
htable: handle v. unlikely case where entries look deleted/empty.
If the hash function doesn't set any bits we use, and the common
bits are all zero the slot will look empty (or, just the lower bit is
set: the slow looks deleted).
However, each bucket is distinct since there are no duplicates, so
at worse there can be two "looks invalid but actually is valid"
buckets. Keep them at the end.
Lookup suffers in raw tools/speed though:
-Lookup after half-change (match): 53-61(54.8+/-2.3) ns
+Lookup after half-change (match): 61-113(83.3+/-17) ns
-Lookup after churn & spread (match): 54-90(59.9+/-11) ns
+Lookup after churn & spread (match): 70-108(85.2+/-14) ns
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell [Fri, 17 Jul 2020 01:56:51 +0000 (11:26 +0930)]
tools/configurator: fix compile error with -O2
In file included from /usr/include/string.h:495,
from configuratortest.c:2:
In function ‘strncpy’,
inlined from ‘main’ at configuratortest.c:6:2:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:106:10: warning: ‘__builtin_strncpy’ specified bound 8 equals destination size [-Wstringop-truncation]
106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>