Offer pnstrdup to frontend code
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 4 Dec 2019 22:36:06 +0000 (19:36 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 4 Dec 2019 22:36:06 +0000 (19:36 -0300)
We already had it on the backend.  Frontend can also use it now.

Discussion: https://postgr.es/m/20191204144021.GA17976@alvherre.pgsql

src/bin/pg_waldump/pg_waldump.c
src/bin/psql/prompt.c
src/bin/scripts/common.c
src/common/fe_memutils.c
src/include/common/fe_memutils.h
src/interfaces/ecpg/compatlib/informix.c

index 30a5851d87cbaf3eaaf02fdbed7e4485b6c3173d..a05fbe69388bed07646af7f937346d367eaafe4f 100644 (file)
@@ -114,8 +114,7 @@ split_path(const char *path, char **dir, char **fname)
    /* directory path */
    if (sep != NULL)
    {
-       *dir = pg_strdup(path);
-       (*dir)[(sep - path) + 1] = '\0';    /* no strndup */
+       *dir = pnstrdup(path, sep - path);
        *fname = pg_strdup(sep + 1);
    }
    /* local directory */
index 41c6f21ecfce421340438bf033bb56f7e4157765..11991815213f35e71aa381f71e11a9a934ad23a7 100644 (file)
@@ -270,13 +270,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
                    /* execute command */
                case '`':
                    {
-                       FILE       *fd;
-                       char       *file = pg_strdup(p + 1);
-                       int         cmdend;
+                       int         cmdend = strcspn(p + 1, "`");
+                       char       *file = pnstrdup(p + 1, cmdend);
+                       FILE       *fd = popen(file, "r");
 
-                       cmdend = strcspn(file, "`");
-                       file[cmdend] = '\0';
-                       fd = popen(file, "r");
                        if (fd)
                        {
                            if (fgets(buf, sizeof(buf), fd) == NULL)
@@ -295,13 +292,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
                    /* interpolate variable */
                case ':':
                    {
-                       char       *name;
+                       int         nameend = strcspn(p + 1, ":");
+                       char       *name = pnstrdup(p + 1, nameend);
                        const char *val;
-                       int         nameend;
 
-                       name = pg_strdup(p + 1);
-                       nameend = strcspn(name, ":");
-                       name[nameend] = '\0';
                        val = GetVariable(pset.vars, name);
                        if (val)
                            strlcpy(buf, val, sizeof(buf));
index 680bbb133a3221705a98ad830584d6d9ccabf6c5..965572897f9f4f7ce1dcccf5b54db2e4b9f0e27b 100644 (file)
@@ -353,8 +353,7 @@ splitTableColumnsSpec(const char *spec, int encoding,
        else
            cp += PQmblen(cp, encoding);
    }
-   *table = pg_strdup(spec);
-   (*table)[cp - spec] = '\0'; /* no strndup */
+   *table = pnstrdup(spec, cp - spec);
    *columns = cp;
 }
 
index ce99b4f4da1d11d922b94f7911704ad6f2fd4e73..2bc6606b80c27fb997b0f2c53a64ee4bbef6a4e6 100644 (file)
@@ -142,6 +142,33 @@ pstrdup(const char *in)
    return pg_strdup(in);
 }
 
+char *
+pnstrdup(const char *in, Size size)
+{
+   char       *tmp;
+   int         len;
+
+   if (!in)
+   {
+       fprintf(stderr,
+               _("cannot duplicate null pointer (internal error)\n"));
+       exit(EXIT_FAILURE);
+   }
+
+   len = strnlen(in, size);
+   tmp = malloc(len + 1);
+   if (tmp == NULL)
+   {
+       fprintf(stderr, _("out of memory\n"));
+       exit(EXIT_FAILURE);
+   }
+
+   memcpy(tmp, in, len);
+   tmp[len] = '\0';
+
+   return tmp;
+}
+
 void *
 repalloc(void *pointer, Size size)
 {
index a1e5940d312090364ac62a0356a243e5346252b9..3181ee17dd5a645abb391e6b5c12765df689988a 100644 (file)
@@ -31,6 +31,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);
index a7bbeb9223f775873572a1d0d759c39b384b9eba..b2a19a1dd3acd6d18f79630679c87a5f24aa935c 100644 (file)
@@ -175,25 +175,6 @@ deccopy(decimal *src, decimal *target)
    memcpy(target, src, sizeof(decimal));
 }
 
-static char *
-ecpg_strndup(const char *str, size_t len)
-{
-   size_t      real_len = strlen(str);
-   int         use_len = (int) ((real_len > len) ? len : real_len);
-
-   char       *new = malloc(use_len + 1);
-
-   if (new)
-   {
-       memcpy(new, str, use_len);
-       new[use_len] = '\0';
-   }
-   else
-       errno = ENOMEM;
-
-   return new;
-}
-
 int
 deccvasc(const char *cp, int len, decimal *np)
 {
@@ -205,7 +186,7 @@ deccvasc(const char *cp, int len, decimal *np)
    if (risnull(CSTRINGTYPE, cp))
        return 0;
 
-   str = ecpg_strndup(cp, len);    /* decimal_in always converts the complete
+   str = pnstrdup(cp, len);        /* decimal_in always converts the complete
                                     * string */
    if (!str)
        ret = ECPG_INFORMIX_NUM_UNDERFLOW;