libplugin: make set callback for options take plugin ptr, check correct type.

I added a plugin arg and was surprised that compile didn't break.
This is because typesafe_cb et al are conditional casts: if the type
isn't as expected it has no effect, but we're passing plugin_option() through
varargs, so everything is accepted!

Add a noop inline to check type, and fix up the two cases where we
used `const char *` instead of `char *`.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-06-06 10:08:53 +09:30
parent 630dba8840
commit aa5c7e763f
7 changed files with 47 additions and 34 deletions

View File

@ -1202,7 +1202,7 @@ param_funder_opt(struct command *cmd, const char *name,
opt_str = tal_strndup(cmd, buffer + tok->start,
tok->end - tok->start);
err = funding_option(opt_str, *opt);
err = funding_option(cmd->plugin, opt_str, *opt);
if (err)
return command_fail_badparam(cmd, name, buffer, tok, err);
@ -1222,7 +1222,7 @@ param_policy_mod(struct command *cmd, const char *name,
arg_str = tal_strndup(cmd, buffer + tok->start,
tok->end - tok->start);
err = u64_option(arg_str, *mod);
err = u64_option(cmd->plugin, arg_str, *mod);
if (err) {
tal_free(err);
if (!parse_amount_sat(&sats, arg_str, strlen(arg_str)))
@ -1518,7 +1518,7 @@ const struct plugin_notification notifs[] = {
},
};
static char *option_channel_base(const char *arg, struct funder_policy *policy)
static char *option_channel_base(struct plugin *plugin, const char *arg, struct funder_policy *policy)
{
struct amount_msat amt;
@ -1536,15 +1536,16 @@ static char *option_channel_base(const char *arg, struct funder_policy *policy)
}
static char *
option_channel_fee_proportional_thousandths_max(const char *arg,
option_channel_fee_proportional_thousandths_max(struct plugin *plugin,
const char *arg,
struct funder_policy *policy)
{
if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(arg, &policy->rates->channel_fee_max_proportional_thousandths);
return u16_option(plugin, arg, &policy->rates->channel_fee_max_proportional_thousandths);
}
static char *amount_option(const char *arg, struct amount_sat *amt)
static char *amount_option(struct plugin *plugin, const char *arg, struct amount_sat *amt)
{
if (!parse_amount_sat(amt, arg, strlen(arg)))
return tal_fmt(tmpctx, "Unable to parse amount '%s'", arg);
@ -1552,7 +1553,7 @@ static char *amount_option(const char *arg, struct amount_sat *amt)
return NULL;
}
static char *option_lease_fee_base(const char *arg,
static char *option_lease_fee_base(struct plugin *plugin, const char *arg,
struct funder_policy *policy)
{
struct amount_sat amt;
@ -1560,7 +1561,7 @@ static char *option_lease_fee_base(const char *arg,
if (!policy->rates)
policy->rates = default_lease_rates(policy);
err = amount_option(arg, &amt);
err = amount_option(plugin, arg, &amt);
if (err)
return err;
@ -1571,28 +1572,29 @@ static char *option_lease_fee_base(const char *arg,
return NULL;
}
static char *option_lease_fee_basis(const char *arg,
static char *option_lease_fee_basis(struct plugin *plugin, const char *arg,
struct funder_policy *policy)
{
if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(arg, &policy->rates->lease_fee_basis);
return u16_option(plugin, arg, &policy->rates->lease_fee_basis);
}
static char *option_lease_weight_max(const char *arg,
static char *option_lease_weight_max(struct plugin *plugin, const char *arg,
struct funder_policy *policy)
{
if (!policy->rates)
policy->rates = default_lease_rates(policy);
return u16_option(arg, &policy->rates->funding_weight);
return u16_option(plugin, arg, &policy->rates->funding_weight);
}
static char *amount_sat_or_u64_option(const char *arg, u64 *amt)
static char *amount_sat_or_u64_option(struct plugin *plugin,
const char *arg, u64 *amt)
{
struct amount_sat sats;
char *err;
err = u64_option(arg, amt);
err = u64_option(plugin, arg, amt);
if (err) {
tal_free(err);
if (!parse_amount_sat(&sats, arg, strlen(arg)))

View File

@ -21,7 +21,7 @@ const char *funder_opt_name(enum funder_opt opt)
abort();
}
char *funding_option(const char *arg, enum funder_opt *opt)
char *funding_option(struct plugin *plugin, const char *arg, enum funder_opt *opt)
{
if (streq(arg, "match"))
*opt = MATCH;

View File

@ -3,6 +3,7 @@
#include "config.h"
#include <common/amount.h>
struct plugin;
struct lease_rates;
struct node_id;
@ -93,7 +94,7 @@ const char *funder_policy_desc(const tal_t *ctx,
const struct funder_policy *policy);
/* Convert a cmdline option to a funding_opt */
char *funding_option(const char *arg, enum funder_opt *opt);
char *funding_option(struct plugin *plugin, const char *arg, enum funder_opt *opt);
/* Check policy settings, return error if fails */
char *funder_check_policy(const struct funder_policy *policy);

View File

@ -1202,7 +1202,7 @@ static struct command_result *handle_init(struct command *cmd,
char *problem;
if (!streq(p->opts[optnum].name, opt))
continue;
problem = p->opts[optnum].handle(json_strdup(opt, buf, t+1),
problem = p->opts[optnum].handle(p, json_strdup(opt, buf, t+1),
p->opts[optnum].arg);
if (problem)
plugin_err(p, "option '%s': %s",
@ -1225,7 +1225,7 @@ static struct command_result *handle_init(struct command *cmd,
return command_success(cmd, json_out_obj(cmd, NULL, NULL));
}
char *u64_option(const char *arg, u64 *i)
char *u64_option(struct plugin *plugin, const char *arg, u64 *i)
{
char *endp;
@ -1239,7 +1239,7 @@ char *u64_option(const char *arg, u64 *i)
return NULL;
}
char *u32_option(const char *arg, u32 *i)
char *u32_option(struct plugin *plugin, const char *arg, u32 *i)
{
char *endp;
u64 n;
@ -1258,7 +1258,7 @@ char *u32_option(const char *arg, u32 *i)
return NULL;
}
char *u16_option(const char *arg, u16 *i)
char *u16_option(struct plugin *plugin, const char *arg, u16 *i)
{
char *endp;
u64 n;
@ -1277,7 +1277,7 @@ char *u16_option(const char *arg, u16 *i)
return NULL;
}
char *bool_option(const char *arg, bool *i)
char *bool_option(struct plugin *plugin, const char *arg, bool *i)
{
if (!streq(arg, "true") && !streq(arg, "false"))
return tal_fmt(tmpctx, "'%s' is not a bool, must be \"true\" or \"false\"", arg);
@ -1286,7 +1286,7 @@ char *bool_option(const char *arg, bool *i)
return NULL;
}
char *flag_option(const char *arg, bool *i)
char *flag_option(struct plugin *plugin, const char *arg, bool *i)
{
/* We only get called if the flag was provided, so *i should be false
* by default */
@ -1298,7 +1298,7 @@ char *flag_option(const char *arg, bool *i)
return NULL;
}
char *charp_option(const char *arg, char **p)
char *charp_option(struct plugin *plugin, const char *arg, char **p)
{
*p = tal_strdup(NULL, arg);
return NULL;
@ -1839,7 +1839,7 @@ static struct plugin *new_plugin(const tal_t *ctx,
o.name = optname;
o.type = va_arg(ap, const char *);
o.description = va_arg(ap, const char *);
o.handle = va_arg(ap, char *(*)(const char *str, void *arg));
o.handle = va_arg(ap, char *(*)(struct plugin *, const char *str, void *arg));
o.arg = va_arg(ap, void *);
o.deprecated = va_arg(ap, int); /* bool gets promoted! */
tal_arr_expand(&p->opts, o);

View File

@ -77,7 +77,7 @@ struct plugin_option {
const char *name;
const char *type;
const char *description;
char *(*handle)(const char *str, void *arg);
char *(*handle)(struct plugin *plugin, const char *str, void *arg);
void *arg;
/* If true, this options *disabled* if allow-deprecated-apis = false */
bool deprecated;
@ -393,12 +393,22 @@ void plugin_notify_progress(struct command *cmd,
u32 num_stages, u32 stage,
u32 num_progress, u32 progress);
/* Simply exists to check that `set` to plugin_option* is correct type */
static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin,
const char *arg, void *))
{
return set;
}
/* Macro to define arguments */
#define plugin_option_(name, type, description, set, arg, deprecated) \
(name), \
(type), \
(description), \
typesafe_cb_preargs(char *, void *, (set), (arg), const char *), \
plugin_option_cb_check(typesafe_cb_preargs(char *, void *, \
(set), (arg), \
struct plugin *, \
const char *)), \
(arg), \
(deprecated)
@ -409,12 +419,12 @@ void plugin_notify_progress(struct command *cmd,
plugin_option_((name), (type), (description), (set), (arg), true)
/* Standard helpers */
char *u64_option(const char *arg, u64 *i);
char *u32_option(const char *arg, u32 *i);
char *u16_option(const char *arg, u16 *i);
char *bool_option(const char *arg, bool *i);
char *charp_option(const char *arg, char **p);
char *flag_option(const char *arg, bool *i);
char *u64_option(struct plugin *plugin, const char *arg, u64 *i);
char *u32_option(struct plugin *plugin, const char *arg, u32 *i);
char *u16_option(struct plugin *plugin, const char *arg, u16 *i);
char *bool_option(struct plugin *plugin, const char *arg, bool *i);
char *charp_option(struct plugin *plugin, const char *arg, char **p);
char *flag_option(struct plugin *plugin, const char *arg, bool *i);
/* The main plugin runner: append with 0 or more plugin_option(), then NULL. */
void NORETURN LAST_ARG_NULL plugin_main(char *argv[],

View File

@ -114,7 +114,7 @@ struct table_desc {
static STRMAP(struct table_desc *) tablemap;
static size_t max_dbmem = 500000000;
static struct sqlite3 *db;
static const char *dbfilename;
static char *dbfilename;
static int gosstore_fd = -1;
static size_t gosstore_nodes_off = 0, gosstore_channels_off = 0;
static u64 next_rowid = 1;

View File

@ -6,7 +6,7 @@
#include <common/memleak.h>
#include <plugins/libplugin.h>
static const char *somearg;
static char *somearg;
static bool self_disable = false;
static bool dont_shutdown = false;