From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753172AbbFAKAE (ORCPT ); Mon, 1 Jun 2015 06:00:04 -0400 Received: from lhrrgout.huawei.com ([194.213.3.17]:12602 "EHLO lhrrgout.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752728AbbFAJ4H (ORCPT ); Mon, 1 Jun 2015 05:56:07 -0400 From: Wang Nan To: , , , , , , , , , , CC: , , , , Subject: [RFC PATCH v5 05/30] bpf tools: Allow caller to set printing function Date: Mon, 1 Jun 2015 07:37:51 +0000 Message-ID: <1433144296-74992-6-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1433144296-74992-1-git-send-email-wangnan0@huawei.com> References: <1433144296-74992-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org By libbpf_set_print(), users of libbpf are allowed to register he/she own debug, info and warning printing functions. Libbpf will use those functions to print messages. If not provided, default info and warning printing functions are fprintf(stderr, ...); default debug printing is NULL. This API is designed to be used by perf, enables it to register its own logging functions to make all logs uniform, instead of separated logging level control. Acked-by: Alexei Starovoitov Signed-off-by: Wang Nan --- tools/lib/bpf/libbpf.c | 40 ++++++++++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf.h | 12 ++++++++++++ 2 files changed, 52 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index c08d6bc..ded37a0 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -7,8 +7,48 @@ */ #include +#include +#include +#include #include #include #include #include "libbpf.h" + +#define __printf(a, b) __attribute__((format(printf, a, b))) + +__printf(1, 2) +static int __base_pr(const char *format, ...) +{ + va_list args; + int err; + + va_start(args, format); + err = vfprintf(stderr, format, args); + va_end(args); + return err; +} + +static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; +static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr; +static __printf(1, 2) libbpf_print_fn_t __pr_debug = NULL; + +#define __pr(func, fmt, ...) \ +do { \ + if ((func)) \ + (func)("libbpf: " fmt, ##__VA_ARGS__); \ +} while(0) + +#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__) +#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__) + +void libbpf_set_print(libbpf_print_fn_t warn, + libbpf_print_fn_t info, + libbpf_print_fn_t debug) +{ + __pr_warning = warn; + __pr_info = info; + __pr_debug = debug; +} diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index a6f46d9..8d1eeba 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -8,4 +8,16 @@ #ifndef __BPF_LIBBPF_H #define __BPF_LIBBPF_H +/* + * In include/linux/compiler-gcc.h, __printf is defined. However + * it should be better if libbpf.h doesn't depend on Linux header file. + * So instead of __printf, here we use gcc attribute directly. + */ +typedef int (*libbpf_print_fn_t)(const char *, ...) + __attribute__((format(printf, 1, 2))); + +void libbpf_set_print(libbpf_print_fn_t warn, + libbpf_print_fn_t info, + libbpf_print_fn_t debug); + #endif -- 1.8.3.4