MCPcopy Create free account
hub / github.com/ElementsProject/lightning / test_subdaemons

Function test_subdaemons

lightningd/lightningd.c:363–426  ·  view source on GitHub ↗

~ Check we can run them, and check their versions */

Source from the content-addressed store, hash-verified

361
362/*~ Check we can run them, and check their versions */
363void test_subdaemons(const struct lightningd *ld)
364{
365 size_t i;
366
367 /*~ CCAN's ARRAY_SIZE() should always be used on defined arrays like
368 * the subdaemons array above. You can calculate the number of
369 * elements it has using `sizeof(subdaemons)/sizeof(subdaemons[0])`
370 * but if `subdaemons` were refactored into a pointer (eg. to make
371 * it a dynamic array) that would erroneously evaluate to `1`.
372 *
373 * ARRAY_SIZE will cause a compiler error if the argument is actually
374 * a pointer, not an array. */
375 for (i = 0; i < ARRAY_SIZE(subdaemons); i++) {
376 /*~ CCAN's path module uses tal, so wants a context to
377 * allocate from. We have a magic convenience context
378 * `tmpctx` for temporary allocations like this.
379 *
380 * Because all our daemons at their core are of form `while
381 * (!stopped) handle_events();` (an event loop pattern), we
382 * can free `tmpctx` in that top-level loop after each event
383 * is handled.
384 */
385 int outfd;
386 const char *dpath = subdaemon_path(tmpctx, ld, subdaemons[i]);
387 const char *verstring;
388 /*~ CCAN's pipecmd module is like popen for grownups: it
389 * takes pointers to fill in stdin, stdout and stderr file
390 * descriptors if desired, and the remainder of arguments
391 * are the command and its argument. */
392 pid_t pid = pipecmd(NULL, &outfd, &outfd,
393 dpath, "--version", NULL);
394
395 /*~ Our logging system: spam goes in at log_debug level, but
396 * logging is mainly added by developer necessity and removed
397 * by developer/user complaints. The only strong convention
398 * is that log_broken() is used for "should never happen".
399 *
400 * Note, however, that logging takes care to preserve the
401 * global `errno` which is set above. */
402 log_debug(ld->log, "testing %s", dpath);
403
404 /*~ ccan/err is a wrapper around BSD's err.h, which defines
405 * the convenience functions err() (error with message
406 * followed by a string based on errno) and errx() (same,x
407 * but no errno string). */
408 if (pid == -1)
409 err(EXITCODE_SUBDAEMON_FAIL, "Could not run %s", dpath);
410
411 /*~ CCAN's grab_file module contains a routine to read into a
412 * tallocated buffer until EOF */
413 verstring = grab_fd(tmpctx, outfd);
414 /*~ Like many CCAN modules, it set errno on failure, which
415 * err (ccan/err, but usually just the BSD <err.h>) prints */
416 if (!verstring)
417 err(1, "Could not get output from %s", dpath);
418 /*~ strstarts is from CCAN/str. */
419 if (!strstarts(verstring, version())
420 || verstring[strlen(version())] != '\n')

Callers 2

test_subdaemons_and_exitFunction · 0.85
mainFunction · 0.85

Calls 6

pipecmdFunction · 0.85
errFunction · 0.85
grab_fdFunction · 0.85
errxFunction · 0.85
subdaemon_pathFunction · 0.70
versionFunction · 0.50

Tested by

no test coverage detected