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

Function test_subdaemons

lightningd/lightningd.c:441–504  ·  view source on GitHub ↗

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

Source from the content-addressed store, hash-verified

439
440/*~ Check we can run them, and check their versions */
441void test_subdaemons(const struct lightningd *ld)
442{
443 size_t i;
444
445 /*~ CCAN's ARRAY_SIZE() should always be used on defined arrays like
446 * the subdaemons array above. You can calculate the number of
447 * elements it has using `sizeof(subdaemons)/sizeof(subdaemons[0])`
448 * but if `subdaemons` were refactored into a pointer (eg. to make
449 * it a dynamic array) that would erroneously evaluate to `1`.
450 *
451 * ARRAY_SIZE will cause a compiler error if the argument is actually
452 * a pointer, not an array. */
453 for (i = 0; i < ARRAY_SIZE(subdaemons); i++) {
454 /*~ CCAN's path module uses tal, so wants a context to
455 * allocate from. We have a magic convenience context
456 * `tmpctx` for temporary allocations like this.
457 *
458 * Because all our daemons at their core are of form `while
459 * (!stopped) handle_events();` (an event loop pattern), we
460 * can free `tmpctx` in that top-level loop after each event
461 * is handled.
462 */
463 int outfd;
464 const char *dpath = subdaemon_path(tmpctx, ld, subdaemons[i]);
465 const char *verstring;
466 /*~ CCAN's pipecmd module is like popen for grownups: it
467 * takes pointers to fill in stdin, stdout and stderr file
468 * descriptors if desired, and the remainder of arguments
469 * are the command and its argument. */
470 pid_t pid = pipecmd(NULL, &outfd, &outfd,
471 dpath, "--version", NULL);
472
473 /*~ Our logging system: spam goes in at log_debug level, but
474 * logging is mainly added by developer necessity and removed
475 * by developer/user complaints. The only strong convention
476 * is that log_broken() is used for "should never happen".
477 *
478 * Note, however, that logging takes care to preserve the
479 * global `errno` which is set above. */
480 log_debug(ld->log, "testing %s", dpath);
481
482 /*~ ccan/err is a wrapper around BSD's err.h, which defines
483 * the convenience functions err() (error with message
484 * followed by a string based on errno) and errx() (same,x
485 * but no errno string). */
486 if (pid == -1)
487 err(EXITCODE_SUBDAEMON_FAIL, "Could not run %s", dpath);
488
489 /*~ CCAN's grab_file module contains a routine to read into a
490 * tallocated buffer until EOF (with nul appended!) */
491 verstring = grab_fd_str(tmpctx, outfd);
492 /*~ Like many CCAN modules, it set errno on failure, which
493 * err (ccan/err, but usually just the BSD <err.h>) prints */
494 if (!verstring)
495 err(1, "Could not get output from %s", dpath);
496 /*~ strstarts is from CCAN/str. */
497 if (!strstarts(verstring, version())
498 || verstring[strlen(version())] != '\n')

Callers 2

test_subdaemons_and_exitFunction · 0.85
mainFunction · 0.85

Calls 6

pipecmdFunction · 0.85
errFunction · 0.85
grab_fd_strFunction · 0.85
versionFunction · 0.85
errxFunction · 0.85
subdaemon_pathFunction · 0.70

Tested by

no test coverage detected