This increases the size of struct output_ctx quite a bit, but allows to simplify internal functions dealing with the cookies mainly because output_fp becomes accessible from struct cookie. Signed-off-by: Phil Sutter <phil@xxxxxx> --- include/nftables.h | 15 ++++++--- src/libnftables.c | 95 +++++++++++++++++++----------------------------------- 2 files changed, 44 insertions(+), 66 deletions(-) diff --git a/include/nftables.h b/include/nftables.h index 5c181be5a4ec3..75134def9b8d4 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -8,10 +8,11 @@ #include <nftables/nftables.h> struct cookie { + FILE *fp; + FILE *orig_fp; char *buf; size_t buflen; size_t pos; - FILE *orig_fp; }; struct output_ctx { @@ -20,10 +21,14 @@ struct output_ctx { unsigned int ip2name; unsigned int handle; unsigned int echo; - FILE *output_fp; - FILE *error_fp; - struct cookie *output_cookie; - struct cookie *error_cookie; + union { + FILE *output_fp; + struct cookie output_cookie; + }; + union { + FILE *error_fp; + struct cookie error_cookie; + }; }; struct nft_cache { diff --git a/src/libnftables.c b/src/libnftables.c index 73363e3a32f87..44e06e1a50835 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -177,14 +177,6 @@ struct nft_ctx *nft_ctx_new(uint32_t flags) return ctx; } -static void free_cookie(struct cookie *cookie) -{ - if (cookie) { - free(cookie->buf); - free(cookie); - } -} - static ssize_t cookie_write(void *cptr, const char *buf, size_t buflen) { struct cookie *cookie = cptr; @@ -208,20 +200,13 @@ static ssize_t cookie_write(void *cptr, const char *buf, size_t buflen) return buflen; } -static int init_cookie(struct cookie **cpptr, FILE **fp) +static int init_cookie(struct cookie *cookie) { - struct cookie *cookie; cookie_io_functions_t cookie_fops = { .write = cookie_write, }; - FILE *cookie_fp; - - if (!cpptr || !fp) - return 1; - - cookie = *cpptr; - if (cookie) { /* just rewind buffer */ + if (cookie->orig_fp) { /* just rewind buffer */ if (cookie->buflen) { cookie->pos = 0; cookie->buf[0] = '\0'; @@ -229,69 +214,61 @@ static int init_cookie(struct cookie **cpptr, FILE **fp) return 0; } - cookie = xzalloc(sizeof(*cookie)); - cookie->orig_fp = *fp; + cookie->orig_fp = cookie->fp; - cookie_fp = fopencookie(cookie, "w", cookie_fops); - if (!cookie_fp) { - free(cookie); + cookie->fp = fopencookie(cookie, "w", cookie_fops); + if (!cookie->fp) { + cookie->fp = cookie->orig_fp; return 1; } - *cpptr = cookie; - *fp = cookie_fp; return 0; } -int nft_ctx_buffer_output(struct nft_ctx *ctx) +static int exit_cookie(struct cookie *cookie) { - struct output_ctx *octx = &ctx->output; + if (!cookie->orig_fp) + return 1; - return init_cookie(&octx->output_cookie, &octx->output_fp); + fclose(cookie->fp); + cookie->fp = cookie->orig_fp; + free(cookie->buf); + cookie->buf = NULL; + cookie->buflen = 0; + cookie->pos = 0; + return 0; } -int nft_ctx_unbuffer_output(struct nft_ctx *ctx) +int nft_ctx_buffer_output(struct nft_ctx *ctx) { - if (!ctx->output.output_cookie) - return 1; + return init_cookie(&ctx->output.output_cookie); +} - ctx->output.output_fp = ctx->output.output_cookie->orig_fp; - free_cookie(ctx->output.output_cookie); - ctx->output.output_cookie = NULL; - return 0; +int nft_ctx_unbuffer_output(struct nft_ctx *ctx) +{ + return exit_cookie(&ctx->output.output_cookie); } int nft_ctx_buffer_error(struct nft_ctx *ctx) { - struct output_ctx *octx = &ctx->output; - - return init_cookie(&octx->error_cookie, &octx->error_fp); + return init_cookie(&ctx->output.error_cookie); } int nft_ctx_unbuffer_error(struct nft_ctx *ctx) { - if (!ctx->output.error_cookie) - return 1; - - ctx->output.error_fp = ctx->output.error_cookie->orig_fp; - free_cookie(ctx->output.error_cookie); - ctx->output.error_cookie = NULL; - return 0; + return exit_cookie(&ctx->output.error_cookie); } -static const char *get_cookie_buffer(struct cookie *cookie, FILE *cookie_fp) +static const char *get_cookie_buffer(struct cookie *cookie) { - if (!cookie) - return NULL; - - fflush(cookie_fp); + fflush(cookie->fp); /* This is a bit tricky: Rewind the buffer for future use and return - * the old content at the same time. - * Therefore just reset buffer position, don't change it's content. And - * return an empty string if buffer position is zero. */ + * the old content at the same time. Therefore return an empty string + * if buffer position is zero, otherwise just rewind buffer position + * and return the unmodified buffer. */ - if (!cookie->buflen || !cookie->pos) + if (!cookie->pos) return ""; cookie->pos = 0; @@ -300,16 +277,12 @@ static const char *get_cookie_buffer(struct cookie *cookie, FILE *cookie_fp) const char *nft_ctx_get_output_buffer(struct nft_ctx *ctx) { - struct output_ctx *octx = &ctx->output; - - return get_cookie_buffer(octx->output_cookie, octx->output_fp); + return get_cookie_buffer(&ctx->output.output_cookie); } const char *nft_ctx_get_error_buffer(struct nft_ctx *ctx) { - struct output_ctx *octx = &ctx->output; - - return get_cookie_buffer(octx->error_cookie, octx->error_fp); + return get_cookie_buffer(&ctx->output.error_cookie); } void nft_ctx_free(struct nft_ctx *ctx) @@ -317,8 +290,8 @@ void nft_ctx_free(struct nft_ctx *ctx) if (ctx->nf_sock) netlink_close_sock(ctx->nf_sock); - free_cookie(ctx->output.output_cookie); - free_cookie(ctx->output.error_cookie); + exit_cookie(&ctx->output.output_cookie); + exit_cookie(&ctx->output.error_cookie); iface_cache_release(); cache_release(&ctx->cache); nft_ctx_clear_include_paths(ctx); -- 2.16.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html