pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Pg Hackers <pgsql-hackers@lists.postgresql.org>
Subject: adding strndup
Date: Wed, 4 Dec 2019 11:40:21 -0300
Message-ID: <20191204144021.GA17976@alvherre.pgsql> (raw)

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

Attachments:

v3-0001-Add-strndup-pg_strndup.patch (text/x-diff, 6.8K) download From 9a92076e53a6664ec61c5f475310c5d6edb91d90 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera <alvherre@alvh.no-ip.org> 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 <fcntl.h>]) ]) # fi AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>]) -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 <fcntl.h>]) @@ -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 <pam/pam_appl.h> 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

view thread (7+ messages)  latest in thread

Message-ID: <20191204144021.GA17976@alvherre.pgsql>
Permalink:  ../20191204144021.GA17976@alvherre.pgsql/
Also on:    postgresql.org/message-id/20191204144021.GA17976@alvherre.pgsql

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: alvherre@2ndquadrant.com, pgsql-hackers@lists.postgresql.org
  Subject: Re: adding strndup
  In-Reply-To: <20191204144021.GA17976@alvherre.pgsql>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox