From patchwork Thu Jan 17 17:30:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bruce Richardson X-Patchwork-Id: 49925 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AB3F92C12; Thu, 17 Jan 2019 18:30:39 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id D835A2A6A for ; Thu, 17 Jan 2019 18:30:37 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2019 09:30:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,489,1539673200"; d="scan'208";a="135513052" Received: from silpixa00399126.ir.intel.com (HELO silpixa00399126.ger.corp.intel.com) ([10.237.222.236]) by fmsmga002.fm.intel.com with ESMTP; 17 Jan 2019 09:30:35 -0800 From: Bruce Richardson To: dev@dpdk.org Cc: Bruce Richardson , Ferruh Yigit , Reshma Pattan Date: Thu, 17 Jan 2019 17:30:32 +0000 Message-Id: <20190117173032.42076-1-bruce.richardson@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190116124836.40132-1-bruce.richardson@intel.com> References: <20190116124836.40132-1-bruce.richardson@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v3] eal: support strlcat function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add the strlcat function to DPDK to exist alongside the strlcpy one. While strncat is generally safe for use for concatenation, the API for the strlcat function is perhaps a little nicer to use, and supports truncation detection. See commit 5364de644a4b ("eal: support strlcpy function") for more details on the function selection logic, since we only should be using the DPDK-provided version when no system-provided version is present. Signed-off-by: Bruce Richardson Reviewed-by: Ferruh Yigit --- V3: fix compiler error by making the test function static CC: Reshma Pattan V2: place ternary operator with regular if statement for readability CC: Ferruh Yigit --- .../common/include/rte_string_fns.h | 16 +++++++ test/test/test_string_fns.c | 45 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/lib/librte_eal/common/include/rte_string_fns.h b/lib/librte_eal/common/include/rte_string_fns.h index 9a2a1ff90..35c6b003c 100644 --- a/lib/librte_eal/common/include/rte_string_fns.h +++ b/lib/librte_eal/common/include/rte_string_fns.h @@ -59,10 +59,25 @@ rte_strlcpy(char *dst, const char *src, size_t size) return (size_t)snprintf(dst, size, "%s", src); } +/** + * @internal + * DPDK-specific version of strlcat for systems without + * libc or libbsd copies of the function + */ +static inline size_t +rte_strlcat(char *dst, const char *src, size_t size) +{ + size_t l = strnlen(dst, size); + if (l < size) + return l + rte_strlcpy(&dst[l], src, size - l); + return l + strlen(src); +} + /* pull in a strlcpy function */ #ifdef RTE_EXEC_ENV_BSDAPP #ifndef __BSD_VISIBLE /* non-standard functions are hidden */ #define strlcpy(dst, src, size) rte_strlcpy(dst, src, size) +#define strlcat(dst, src, size) rte_strlcat(dst, src, size) #endif #else /* non-BSD platforms */ @@ -71,6 +86,7 @@ rte_strlcpy(char *dst, const char *src, size_t size) #else /* no BSD header files, create own */ #define strlcpy(dst, src, size) rte_strlcpy(dst, src, size) +#define strlcat(dst, src, size) rte_strlcat(dst, src, size) #endif /* RTE_USE_LIBBSD */ #endif /* BSDAPP */ diff --git a/test/test/test_string_fns.c b/test/test/test_string_fns.c index 3f091ab92..5e105d2bb 100644 --- a/test/test/test_string_fns.c +++ b/test/test/test_string_fns.c @@ -129,11 +129,56 @@ test_rte_strsplit(void) return 0; } +static int +test_rte_strlcat(void) +{ + /* only run actual unit tests if we have system-provided strlcat */ +#if defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) +#define BUF_LEN 32 + const char dst[BUF_LEN] = "Test string"; + const char src[] = " appended"; + char bsd_dst[BUF_LEN]; + char rte_dst[BUF_LEN]; + size_t i, bsd_ret, rte_ret; + + LOG("dst = '%s', strlen(dst) = %zu\n", dst, strlen(dst)); + LOG("src = '%s', strlen(src) = %zu\n", src, strlen(src)); + LOG("---\n"); + + for (i = 0; i < BUF_LEN; i++) { + /* initialize destination buffers */ + memcpy(bsd_dst, dst, BUF_LEN); + memcpy(rte_dst, dst, BUF_LEN); + /* compare implementations */ + bsd_ret = strlcat(bsd_dst, src, i); + rte_ret = rte_strlcat(rte_dst, src, i); + if (bsd_ret != rte_ret) { + LOG("Incorrect retval for buf length = %zu\n", i); + LOG("BSD: '%zu', rte: '%zu'\n", bsd_ret, rte_ret); + return -1; + } + if (memcmp(bsd_dst, rte_dst, BUF_LEN) != 0) { + LOG("Resulting buffers don't match\n"); + LOG("BSD: '%s', rte: '%s'\n", bsd_dst, rte_dst); + return -1; + } + LOG("buffer size = %zu: dst = '%s', ret = %zu\n", + i, rte_dst, rte_ret); + } + LOG("Checked %zu combinations\n", i); +#undef BUF_LEN +#endif /* defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) */ + + return 0; +} + static int test_string_fns(void) { if (test_rte_strsplit() < 0) return -1; + if (test_rte_strlcat() < 0) + return -1; return 0; }