More patches on the way for improving .list_exports signature and adding .export_description, but this is the promised code showing why nbdkit_string_intern is useful. Patch 4 is somewhat RFC: we could either add new API to take the boilerplate from: foo_config(const char *key, const char *value) { if (strcmp (key, "file") == 0) { CLEANUP_FREE char *tmp = nbdkit_realpath (value); filename = nbdkit_string_intern (tmp); if (!filename) return -1; } ... to the shorter: foo_config(const char *key, const char *value) { if (strcmp (key, "file") == 0) { if ((filename = nbdkit_realpath_intern (value)) == NULL) return -1; } by adding 'const char *nbdkit_realpath_intern(const char *name)', or maybe we instead add a 'bool malloced' knob to nbdkit_string_intern, passing true transfers ownership of an existing string, and passing false forces nbdkit to copy (but exposes a bit more of a malloc/free coupling between plugin and nbdkit): foo_config(const char *key, const char *value) { if (strcmp (key, "file") == 0) { if ((filename = nbdkit_string_intern (nbdkit_realpath (value), true)) == NULL) return -1; } Also, more than just the file plugin shares the pattern of copying off a config name where we could simplify or eliminate .unload by interning the string. Eric Blake (5): api: Add .default_export server: Respond to NBD_INFO_NAME request api: Add nbdkit_string_intern helper file: Utilize nbdkit_string_intern sh, eval: Implement .default_export docs/nbdkit-filter.pod | 37 ++++++--- docs/nbdkit-plugin.pod | 66 +++++++++++++++- plugins/eval/nbdkit-eval-plugin.pod | 2 + plugins/sh/nbdkit-sh-plugin.pod | 20 ++++- include/nbdkit-common.h | 2 + include/nbdkit-filter.h | 9 ++- include/nbdkit-plugin.h | 1 + tests/Makefile.am | 4 +- server/internal.h | 14 +++- server/backend.c | 45 +++++++---- server/connections.c | 2 +- server/exports.c | 8 +- server/filters.c | 12 +++ server/main.c | 27 ++----- server/nbdkit.syms | 1 + server/plugins.c | 33 +++++--- server/protocol-handshake-newstyle.c | 68 ++++++++++++++-- server/public.c | 42 ++++++++++ plugins/sh/methods.h | 1 + plugins/eval/eval.c | 2 + plugins/file/file.c | 20 ++--- plugins/ondemand/ondemand.c | 11 ++- plugins/sh/methods.c | 54 ++++++++++++- plugins/sh/sh.c | 1 + plugins/sh/example.sh | 2 +- filters/log/log.c | 10 +-- filters/tls-fallback/tls-fallback.c | 12 ++- tests/test-eval-exports.sh | 34 +++++--- tests/test-export-info.sh | 114 +++++++++++++++++++++++++++ tests/test-tls-fallback.sh | 11 ++- tests/test-layers-filter.c | 9 +++ tests/test-layers-plugin.c | 8 ++ tests/test-layers.c | 24 +++--- 33 files changed, 573 insertions(+), 133 deletions(-) create mode 100755 tests/test-export-info.sh -- 2.28.0