@ -57,6 +57,7 @@
/*~ This is common code: routines shared by one or more executables
* ( separate daemons , or the lightning - cli program ) . */
# include <common/daemon.h>
# include <common/memleak.h>
# include <common/timeout.h>
# include <common/utils.h>
# include <common/version.h>
@ -72,6 +73,7 @@
# include <lightningd/io_loop_with_timers.h>
# include <lightningd/jsonrpc.h>
# include <lightningd/log.h>
# include <lightningd/memdump.h>
# include <lightningd/onchain_control.h>
# include <lightningd/options.h>
# include <onchaind/onchain_wire.h>
@ -81,6 +83,12 @@
# include <sys/types.h>
# include <unistd.h>
static void destroy_alt_subdaemons ( struct lightningd * ld ) ;
# if DEVELOPER
static void memleak_help_alt_subdaemons ( struct htable * memtable ,
struct lightningd * ld ) ;
# endif /* DEVELOPER */
/*~ The core lightning object: it's passed everywhere, and is basically a
* global variable . This new_xxx pattern is something we ' ll see often :
* it allocates and initializes a new structure , using * tal * , the hierarchical
@ -248,6 +256,11 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
*/
ld - > encrypted_hsm = false ;
/* This is used to override subdaemons */
strmap_init ( & ld - > alt_subdaemons ) ;
tal_add_destructor ( ld , destroy_alt_subdaemons ) ;
memleak_add_helper ( ld , memleak_help_alt_subdaemons ) ;
/*~ We change umask if we daemonize, but not if we don't. Initialize the
* initial_umask anyway as we might rely on it later ( ` plugin start ` ) . */
ld - > initial_umask = umask ( 0 ) ;
@ -278,6 +291,50 @@ static const char *subdaemons[] = {
" lightning_openingd "
} ;
/* Return true if called with a recognized subdaemon e.g. "hsmd" */
bool is_subdaemon ( const char * sdname )
{
for ( size_t i = 0 ; i < ARRAY_SIZE ( subdaemons ) ; i + + )
/* Skip the "lightning_" prefix in the table */
if ( streq ( sdname , subdaemons [ i ] + strlen ( " lightning_ " ) ) )
return true ;
return false ;
}
static void destroy_alt_subdaemons ( struct lightningd * ld )
{
strmap_clear ( & ld - > alt_subdaemons ) ;
}
# if DEVELOPER
static void memleak_help_alt_subdaemons ( struct htable * memtable ,
struct lightningd * ld )
{
memleak_remove_strmap ( memtable , & ld - > alt_subdaemons ) ;
}
# endif /* DEVELOPER */
const char * subdaemon_path ( const tal_t * ctx , const struct lightningd * ld , const char * name )
{
/* Strip the leading "lightning_" before looking in alt_subdaemons.
*/
size_t pfxlen = strlen ( " lightning_ " ) ;
assert ( strlen ( name ) > pfxlen ) ;
const char * short_name = tal_strdup ( ctx , name + pfxlen ) ;
/* Is there an alternate path for this subdaemon? */
const char * dpath ;
const char * alt = strmap_get ( & ld - > alt_subdaemons , short_name ) ;
if ( alt ) {
/* path_join will honor absolute paths as well. */
dpath = path_join ( ctx , ld - > daemon_dir , alt ) ;
} else {
/* This subdaemon is found in the standard place. */
dpath = path_join ( ctx , ld - > daemon_dir , name ) ;
}
return dpath ;
}
/*~ Check we can run them, and check their versions */
void test_subdaemons ( const struct lightningd * ld )
{
@ -292,7 +349,6 @@ void test_subdaemons(const struct lightningd *ld)
* ARRAY_SIZE will cause a compiler error if the argument is actually
* a pointer , not an array . */
for ( i = 0 ; i < ARRAY_SIZE ( subdaemons ) ; i + + ) {
int outfd ;
/*~ CCAN's path module uses tal, so wants a context to
* allocate from . We have a magic convenience context
* ` tmpctx ` for temporary allocations like this .
@ -302,7 +358,8 @@ void test_subdaemons(const struct lightningd *ld)
* can free ` tmpctx ` in that top - level loop after each event
* is handled .
*/
const char * dpath = path_join ( tmpctx , ld - > daemon_dir , subdaemons [ i ] ) ;
int outfd ;
const char * dpath = subdaemon_path ( tmpctx , ld , subdaemons [ i ] ) ;
const char * verstring ;
/*~ CCAN's pipecmd module is like popen for grownups: it
* takes pointers to fill in stdin , stdout and stderr file