Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1icVwc-0000Nv-Qh for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Dec 2019 14:47:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1icVwb-0003IZ-Cx for pgsql-hackers@arkaria.postgresql.org; Wed, 04 Dec 2019 14:47:57 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1icVwa-0003IS-VD for pgsql-hackers@lists.postgresql.org; Wed, 04 Dec 2019 14:47:57 +0000 Received: from mail-qt1-x832.google.com ([2607:f8b0:4864:20::832]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1icVwX-0008Ht-D6 for pgsql-hackers@lists.postgresql.org; Wed, 04 Dec 2019 14:47:56 +0000 Received: by mail-qt1-x832.google.com with SMTP id 38so7923167qtb.13 for ; Wed, 04 Dec 2019 06:47:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:mime-version:content-disposition :content-transfer-encoding:user-agent; bh=NRGt68tpNGx2kj2CCKX9993+7L1vZ++KvkyOSXIHtuY=; b=GImrKUMzXooD6GjlXxHY/LdOFcDPr9F+3ifdO2i7/XQjCxUgdFITLvETxteTkYTwRi lpaT31JBRDlAy/IyCfqNYr8d8fTnlEqtRizFpRUfzLTLr767kXJ8x4cXLi44tCPuU/73 k0qKZNrBsPwZgW+JV8gHx+L0JKhWsABFK+MWtpgoVNa6xoEAxP6/ags0+jUVSAXbWRpD X6bEckU3jQ2FJTejukk8A/Z+Ni3oqX5q91AjWuJm2lIJ3rlGn88t41x7jWcL5u3WXkRL Ihv0PzZCU/BNuKLE/9uF9X73szA7ds0MOYuOneI9RgFHgz+pOOdk8PpGTwGAtGueRrPi c9LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition:content-transfer-encoding:user-agent; bh=NRGt68tpNGx2kj2CCKX9993+7L1vZ++KvkyOSXIHtuY=; b=TiyLtcqfAxSJxTMWS0x3okHsrn5dIDNktj+8zB6BZmMMgUssltN6Wvw5KyF4V/kqcJ pJCzNil9nIqdxCCUu3Ddf3tuTQgMVI83Lvs2Te420uQn+6uczymLSb4GjaUMV2nx1fyx xDKF2QWo1KpfXviCQL7DmCqGDxpdU+4lYCxi/2a/64SnnFWzr/JGtNEVOaDg6o9K4k40 xuVdM/qjdPF9jNMoSihVnxXeKZ5nyORqaxzWbSiTcuqrJjZzJtUfmqtc50esHLo0n9Py tpt/le0M34FCoqKeUtmh5EgLeFDxeagRuf5Kcw9oeJIMUMX+gmvoWfF+sjL0o9UHrJ7m alow== X-Gm-Message-State: APjAAAW4RfnKwrtUxi10bK8Ye88lovdA10zwZfYk6Dhr9XbUhArFvTbj abaSsp3Ws81LZBI2wNC0SHFdQ0u0GnKcCTeszHDcMeilS4rBb7fawkllwP35R0i9x47fOeJySLf BuJwLpweT9O3BQGc70/N+vqxdgCzopGwtNfLxZbVG+QQf6x5Cy+nhTN6+I8JQNOGtUUNFPNzk7q h81K9LcNqPc+/PbDVp X-Google-Smtp-Source: APXvYqxOvbwcqmNJxdOWvvAq/6k1wqbgjA0ZtfPWsCM6PbnEo4jU3bdANmgIlsGbQU/fJPS0Ri6EQw== X-Received: by 2002:aed:33a3:: with SMTP id v32mr3026885qtd.301.1575470424654; Wed, 04 Dec 2019 06:40:24 -0800 (PST) Received: from nimloth.alvh.no-ip.org ([190.217.182.8]) by smtp.gmail.com with ESMTPSA id m6sm3765882qke.80.2019.12.04.06.40.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 06:40:24 -0800 (PST) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 80286300804; Wed, 4 Dec 2019 11:40:21 -0300 (-03) Date: Wed, 4 Dec 2019 11:40:21 -0300 From: Alvaro Herrera To: Pg Hackers Subject: adding strndup Message-ID: <20191204144021.GA17976@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="XsQoSWH+UP9D9v3l" Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --XsQoSWH+UP9D9v3l Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit I just proposed in https://postgr.es/m/0191204143715.GA17312@alvherre.pgsql the addition of strndup() to our src/port. I think this should be pretty uncontroversial, but wanted to give a heads-up outside that thread. I attach the patch here for completeness. -- Álvaro Herrera http://www.twitter.com/alvherre --XsQoSWH+UP9D9v3l Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0001-Add-strndup-pg_strndup.patch" From 9a92076e53a6664ec61c5f475310c5d6edb91d90 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 4 Dec 2019 11:02:34 -0300 Subject: [PATCH v3 1/3] Add strndup / pg_strndup The former is now a POSIX function. We already had pnstrdup, but it was not offered to frontend code. --- configure | 23 +++++++++++++++++++++++ configure.in | 3 ++- src/common/fe_memutils.c | 26 ++++++++++++++++++++++++++ src/include/common/fe_memutils.h | 2 ++ src/include/pg_config.h.in | 7 +++++++ src/include/pg_config.h.win32 | 7 +++++++ src/include/port.h | 4 ++++ src/port/strndup.c | 32 ++++++++++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 src/port/strndup.c diff --git a/configure b/configure index 1d88983b34..fd8c759473 100755 --- a/configure +++ b/configure @@ -15482,6 +15482,16 @@ fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_STRLCPY $ac_have_decl _ACEOF +ac_fn_c_check_decl "$LINENO" "strndup" "ac_cv_have_decl_strndup" "$ac_includes_default" +if test "x$ac_cv_have_decl_strndup" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRNDUP $ac_have_decl +_ACEOF ac_fn_c_check_decl "$LINENO" "strnlen" "ac_cv_have_decl_strnlen" "$ac_includes_default" if test "x$ac_cv_have_decl_strnlen" = xyes; then : ac_have_decl=1 @@ -15815,6 +15825,19 @@ esac fi +ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup" +if test "x$ac_cv_func_strndup" = xyes; then : + $as_echo "#define HAVE_STRNDUP 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strndup.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strndup.$ac_objext" + ;; +esac + +fi + ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" if test "x$ac_cv_func_strnlen" = xyes; then : $as_echo "#define HAVE_STRNLEN 1" >>confdefs.h diff --git a/configure.in b/configure.in index a2cb20b5e3..11f66d19c3 100644 --- a/configure.in +++ b/configure.in @@ -1679,7 +1679,7 @@ AC_CHECK_DECLS(posix_fadvise, [], [], [#include ]) ]) # fi AC_CHECK_DECLS(fdatasync, [], [], [#include ]) -AC_CHECK_DECLS([strlcat, strlcpy, strnlen]) +AC_CHECK_DECLS([strlcat, strlcpy, strndup, strnlen]) # This is probably only present on macOS, but may as well check always AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include ]) @@ -1738,6 +1738,7 @@ AC_REPLACE_FUNCS(m4_normalize([ srandom strlcat strlcpy + strndup strnlen strtof ])) diff --git a/src/common/fe_memutils.c b/src/common/fe_memutils.c index ce99b4f4da..896e5d46ca 100644 --- a/src/common/fe_memutils.c +++ b/src/common/fe_memutils.c @@ -101,6 +101,26 @@ pg_strdup(const char *in) return tmp; } +char * +pg_strndup(const char *in, size_t size) +{ + char *tmp; + + if (!in) + { + fprintf(stderr, + _("cannot duplicate null pointer (internal error)\n")); + exit(EXIT_FAILURE); + } + tmp = strndup(in, size); + if (!tmp) + { + fprintf(stderr, _("out of memory\n")); + exit(EXIT_FAILURE); + } + return tmp; +} + void pg_free(void *ptr) { @@ -142,6 +162,12 @@ pstrdup(const char *in) return pg_strdup(in); } +char * +pnstrdup(const char *in, Size size) +{ + return pg_strndup(in, size); +} + void * repalloc(void *pointer, Size size) { diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h index a1e5940d31..c8797ffe38 100644 --- a/src/include/common/fe_memutils.h +++ b/src/include/common/fe_memutils.h @@ -23,6 +23,7 @@ * (except pg_malloc_extended with MCXT_ALLOC_NO_OOM) */ extern char *pg_strdup(const char *in); +extern char *pg_strndup(const char *in, size_t size); extern void *pg_malloc(size_t size); extern void *pg_malloc0(size_t size); extern void *pg_malloc_extended(size_t size, int flags); @@ -31,6 +32,7 @@ extern void pg_free(void *pointer); /* Equivalent functions, deliberately named the same as backend functions */ extern char *pstrdup(const char *in); +extern char *pnstrdup(const char *in, Size size); extern void *palloc(Size size); extern void *palloc0(Size size); extern void *palloc_extended(Size size, int flags); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index c208dcdfc7..1db3f1b1e8 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -170,6 +170,10 @@ don't. */ #undef HAVE_DECL_STRLCPY +/* Define to 1 if you have the declaration of `strndup', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNDUP + /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #undef HAVE_DECL_STRNLEN @@ -545,6 +549,9 @@ /* Define to 1 if you have the `strlcpy' function. */ #undef HAVE_STRLCPY +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 6c98ef4916..2ff2c3d4a8 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -129,6 +129,10 @@ don't. */ #define HAVE_DECL_RTLD_NOW 0 +/* Define to 1 if you have the declaration of `strndup', and to 0 if you + don't. */ +#undef HAVE_DECL_STRNDUP + /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #define HAVE_DECL_STRNLEN 1 @@ -297,6 +301,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_PAM_PAM_APPL_H */ +/* Define to 1 if you have the `strndup' function. */ +#undef HAVE_STRNDUP + /* Define to 1 if you have the `strnlen' function. */ #define HAVE_STRNLEN 1 diff --git a/src/include/port.h b/src/include/port.h index 10dcb5f0a6..e5d4486eb2 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -430,6 +430,10 @@ extern size_t strlcat(char *dst, const char *src, size_t siz); extern size_t strlcpy(char *dst, const char *src, size_t siz); #endif +#if !HAVE_DECL_STRNDUP +extern char *strndup(char *src, size_t siz); +#endif + #if !HAVE_DECL_STRNLEN extern size_t strnlen(const char *str, size_t maxlen); #endif diff --git a/src/port/strndup.c b/src/port/strndup.c new file mode 100644 index 0000000000..eba41a0498 --- /dev/null +++ b/src/port/strndup.c @@ -0,0 +1,32 @@ +/* + * strndup.c + * Fallback implementation of strndup(). + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/port/strndup.c + */ + +#include "c.h" + +/* + * Implementation of posix' strndup for systems where it's not available. + */ +char * +strndup(const char *str, size_t siz) +{ + char *dst; + int len; + + len = strnlen(str, siz); + dst = malloc(len + 1); + if (dst == NULL) + return NULL; + + memcpy(dst, str, len); + dst[len + 1] = '\0'; + + return dst; +} -- 2.20.1 --XsQoSWH+UP9D9v3l--