]> granicus.if.org Git - postgresql/commitdiff
Add use of asprintf()
authorPeter Eisentraut <peter_e@gmx.net>
Sun, 13 Oct 2013 04:09:18 +0000 (00:09 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Sun, 13 Oct 2013 04:09:18 +0000 (00:09 -0400)
Add asprintf(), pg_asprintf(), and psprintf() to simplify string
allocation and composition.  Replacement implementations taken from
NetBSD.

Reviewed-by: Álvaro Herrera <alvherre@2ndquadrant.com>
Reviewed-by: Asif Naeem <anaeem.it@gmail.com>
47 files changed:
configure
configure.in
contrib/adminpack/adminpack.c
contrib/oid2name/oid2name.c
contrib/pg_upgrade/check.c
contrib/pg_upgrade/tablespace.c
contrib/pg_upgrade/util.c
contrib/pg_upgrade/version_old_8_3.c
contrib/spi/refint.c
contrib/spi/timetravel.c
src/backend/bootstrap/bootstrap.c
src/backend/catalog/catalog.c
src/backend/commands/tablespace.c
src/backend/libpq/auth.c
src/backend/optimizer/plan/subselect.c
src/backend/parser/gram.y
src/backend/postmaster/postmaster.c
src/backend/utils/adt/cash.c
src/backend/utils/adt/dbsize.c
src/backend/utils/adt/misc.c
src/backend/utils/fmgr/dfmgr.c
src/backend/utils/fmgr/fmgr.c
src/backend/utils/init/miscinit.c
src/backend/utils/misc/guc.c
src/backend/utils/mmgr/mcxt.c
src/bin/initdb/initdb.c
src/bin/pg_ctl/pg_ctl.c
src/bin/pg_dump/compress_io.c
src/bin/pg_dump/pg_dump.c
src/bin/psql/command.c
src/bin/psql/common.c
src/bin/psql/copy.c
src/bin/psql/input.c
src/bin/psql/large_obj.c
src/bin/psql/startup.c
src/bin/psql/tab-complete.c
src/common/fe_memutils.c
src/common/relpath.c
src/include/common/fe_memutils.h
src/include/pg_config.h.in
src/include/port.h
src/include/utils/palloc.h
src/interfaces/ecpg/test/expected/pgtypeslib-dt_test2.c
src/interfaces/ecpg/test/pgtypeslib/dt_test2.pgc
src/interfaces/libpq/fe-auth.c
src/test/isolation/isolationtester.c
src/test/regress/pg_regress.c

index cd72545141779d42d23cd3ffc2f62b8d24822eb8..f9da1dec2e1c907245b41de420ad9237e4e5ac88 100755 (executable)
--- a/configure
+++ b/configure
@@ -21502,7 +21502,8 @@ fi
 
 
 
-for ac_func in crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
+
+for ac_func in asprintf crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy
 do
 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5
index ead0908fd9a1ba51ff53b81548cbef6e14ded12d..f8c72061ad13f48f5efa7a3942b23fc7efd80782 100644 (file)
@@ -1346,7 +1346,7 @@ else
   AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
 fi
 
-AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
+AC_REPLACE_FUNCS([asprintf crypt fls getopt getrusage inet_aton random rint srandom strerror strlcat strlcpy])
 
 case $host_os in
 
index ded89c60590322f69281675cdbb506576ca9ac97..1ec0768289e65d5fc4a81783e36de01dff8f3a2a 100644 (file)
@@ -376,8 +376,7 @@ pg_logdir_ls(PG_FUNCTION_ARGS)
                /* Seems the timestamp is OK; prepare and return tuple */
 
                values[0] = timestampbuf;
-               values[1] = palloc(strlen(fctx->location) + strlen(de->d_name) + 2);
-               sprintf(values[1], "%s/%s", fctx->location, de->d_name);
+               values[1] = psprintf("%s/%s", fctx->location, de->d_name);
 
                tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
 
index cdec94205bc13842780f8f4466c2053df9e1e848..ab92c637e591c4fcacf19e8587760bbb41faac25 100644 (file)
@@ -508,8 +508,7 @@ sql_exec_searchtables(PGconn *conn, struct options * opts)
        free(comma_filenodes);
 
        /* now build the query */
-       todo = (char *) pg_malloc(650 + strlen(qualifiers));
-       snprintf(todo, 650 + strlen(qualifiers),
+       pg_asprintf(&todo,
                         "SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s\n"
                         "FROM pg_catalog.pg_class c \n"
                 "      LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n"
index 1a37b79a8b7834fab987b379edce2a567205cd87..464bbe2604fa7727ca20d2548b83411bce5b8ff3 100644 (file)
@@ -455,18 +455,13 @@ create_script_for_cluster_analyze(char **analyze_script_file_name)
        FILE       *script = NULL;
        char       *user_specification = "";
 
-       if (os_info.user_specified)
-       {
-               user_specification = pg_malloc(strlen(os_info.user) + 7);
-               sprintf(user_specification, "-U \"%s\" ", os_info.user);
-       }
-
-       *analyze_script_file_name = pg_malloc(MAXPGPATH);
-
        prep_status("Creating script to analyze new cluster");
 
-       snprintf(*analyze_script_file_name, MAXPGPATH, "analyze_new_cluster.%s",
-                        SCRIPT_EXT);
+       if (os_info.user_specified)
+               pg_asprintf(&user_specification, "-U \"%s\" ", os_info.user);
+
+       pg_asprintf(analyze_script_file_name, "analyze_new_cluster.%s",
+                               SCRIPT_EXT);
 
        if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
                pg_fatal("Could not open file \"%s\": %s\n",
@@ -597,10 +592,8 @@ create_script_for_old_cluster_deletion(char **deletion_script_file_name)
        int                     tblnum;
        char            old_cluster_pgdata[MAXPGPATH];
 
-       *deletion_script_file_name = pg_malloc(MAXPGPATH);
-
-       snprintf(*deletion_script_file_name, MAXPGPATH, "delete_old_cluster.%s",
-                        SCRIPT_EXT);
+       pg_asprintf(deletion_script_file_name, "delete_old_cluster.%s",
+                               SCRIPT_EXT);
 
        /*
         * Some users (oddly) create tablespaces inside the cluster data
index 229f4a8fde3e46fcbb0d02632b17354dc9f567c6..f090f62b29cc7fe3125171514d5f7844184a0331 100644 (file)
@@ -84,12 +84,9 @@ set_tablespace_directory_suffix(ClusterInfo *cluster)
        else
        {
                /* This cluster has a version-specific subdirectory */
-               cluster->tablespace_suffix = pg_malloc(4 +
-                                                                                strlen(cluster->major_version_str) +
-                                                                                          10 /* OIDCHARS */ + 1);
 
                /* The leading slash is needed to start a new directory. */
-               sprintf(cluster->tablespace_suffix, "/PG_%s_%d", cluster->major_version_str,
-                               cluster->controldata.cat_ver);
+               pg_asprintf(&cluster->tablespace_suffix, "/PG_%s_%d",
+                                       cluster->major_version_str,     cluster->controldata.cat_ver);
        }
 }
index 74565ec92e1a45173e41180dc0743fe52124d40c..7bca19b84d0f130b0785d636d528a5bf104b25ff 100644 (file)
@@ -276,10 +276,9 @@ pg_putenv(const char *var, const char *val)
        if (val)
        {
 #ifndef WIN32
-               char       *envstr = (char *) pg_malloc(strlen(var) +
-                                                                                               strlen(val) + 2);
+               char       *envstr;
 
-               sprintf(envstr, "%s=%s", var, val);
+               pg_asprintf(&envstr, "%s=%s", var, val);
                putenv(envstr);
 
                /*
index 6d44266704c36cb9e82be87ac9c444582195d418..83334a09f695b575983254017ca3c6f5f60013dc 100644 (file)
@@ -675,9 +675,9 @@ old_8_3_create_sequence_script(ClusterInfo *cluster)
        int                     dbnum;
        FILE       *script = NULL;
        bool            found = false;
-       char       *output_path = pg_malloc(MAXPGPATH);
+       char       *output_path;
 
-       snprintf(output_path, MAXPGPATH, "adjust_sequences.sql");
+       output_path = pg_strdup("adjust_sequences.sql");
 
        prep_status("Creating script to adjust sequences");
 
index 8dc565a190775f5ba94ae11e684de4da027debfe..fbed3003961aa2671a6fe35d0eff9e0376be636a 100644 (file)
@@ -634,8 +634,7 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
                (*nplans) = i = 0;
        }
 
-       newp->ident = (char *) malloc(strlen(ident) + 1);
-       strcpy(newp->ident, ident);
+       newp->ident = strdup(ident);
        newp->nplans = 0;
        newp->splan = NULL;
        (*nplans)++;
index 34b4453f879111e5ea37d7032e6ee6189680f92b..fa74daba946022ca08b30e91e5c2637dab91a273 100644 (file)
@@ -540,8 +540,7 @@ find_plan(char *ident, EPlan **eplan, int *nplans)
                (*nplans) = i = 0;
        }
 
-       newp->ident = (char *) malloc(strlen(ident) + 1);
-       strcpy(newp->ident, ident);
+       newp->ident = strdup(ident);
        newp->splan = NULL;
        (*nplans)++;
 
index d23dc4504aed1694911022f59f544840fa790152..2a1af63d781c54f23bc6e494acc93b9466f27bb5 100644 (file)
@@ -249,9 +249,9 @@ AuxiliaryProcessMain(int argc, char *argv[])
                        case 'd':
                                {
                                        /* Turn on debugging for the bootstrap process. */
-                                       char       *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
+                                       char       *debugstr;
 
-                                       sprintf(debugstr, "debug%s", optarg);
+                                       debugstr = psprintf("debug%s", optarg);
                                        SetConfigOption("log_min_messages", debugstr,
                                                                        PGC_POSTMASTER, PGC_S_ARGV);
                                        SetConfigOption("client_min_messages", debugstr,
index c1287a77df041a4421756abc15cc0792fe45d227..577206cd26be986e000f0f93393e37a4fe896417 100644 (file)
@@ -75,35 +75,23 @@ forkname_to_number(char *forkName)
 char *
 GetDatabasePath(Oid dbNode, Oid spcNode)
 {
-       int                     pathlen;
-       char       *path;
-
        if (spcNode == GLOBALTABLESPACE_OID)
        {
                /* Shared system relations live in {datadir}/global */
                Assert(dbNode == 0);
-               pathlen = 6 + 1;
-               path = (char *) palloc(pathlen);
-               snprintf(path, pathlen, "global");
+               return pstrdup("global");
        }
        else if (spcNode == DEFAULTTABLESPACE_OID)
        {
                /* The default tablespace is {datadir}/base */
-               pathlen = 5 + OIDCHARS + 1;
-               path = (char *) palloc(pathlen);
-               snprintf(path, pathlen, "base/%u",
-                                dbNode);
+               return psprintf("base/%u", dbNode);
        }
        else
        {
                /* All other tablespaces are accessed via symlinks */
-               pathlen = 9 + 1 + OIDCHARS + 1 + strlen(TABLESPACE_VERSION_DIRECTORY) +
-                       1 + OIDCHARS + 1;
-               path = (char *) palloc(pathlen);
-               snprintf(path, pathlen, "pg_tblspc/%u/%s/%u",
-                                spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
+               return psprintf("pg_tblspc/%u/%s/%u",
+                                               spcNode, TABLESPACE_VERSION_DIRECTORY, dbNode);
        }
-       return path;
 }
 
 
index 155eb7c2481f3626199c72352756c1603d9ef037..ddc8ec759fcc91cc017f47574b0bfb211b03bf0f 100644 (file)
@@ -541,12 +541,11 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 static void
 create_tablespace_directories(const char *location, const Oid tablespaceoid)
 {
-       char       *linkloc = palloc(OIDCHARS + OIDCHARS + 1);
-       char       *location_with_version_dir = palloc(strlen(location) + 1 +
-                                                                  strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
+       char       *linkloc;
+       char       *location_with_version_dir;
 
-       sprintf(linkloc, "pg_tblspc/%u", tablespaceoid);
-       sprintf(location_with_version_dir, "%s/%s", location,
+       linkloc = psprintf("pg_tblspc/%u", tablespaceoid);
+       location_with_version_dir = psprintf("%s/%s", location,
                        TABLESPACE_VERSION_DIRECTORY);
 
        /*
@@ -652,9 +651,7 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
        char       *subfile;
        struct stat st;
 
-       linkloc_with_version_dir = palloc(9 + 1 + OIDCHARS + 1 +
-                                                                         strlen(TABLESPACE_VERSION_DIRECTORY));
-       sprintf(linkloc_with_version_dir, "pg_tblspc/%u/%s", tablespaceoid,
+       linkloc_with_version_dir = psprintf("pg_tblspc/%u/%s", tablespaceoid,
                        TABLESPACE_VERSION_DIRECTORY);
 
        /*
@@ -711,8 +708,7 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo)
                        strcmp(de->d_name, "..") == 0)
                        continue;
 
-               subfile = palloc(strlen(linkloc_with_version_dir) + 1 + strlen(de->d_name) + 1);
-               sprintf(subfile, "%s/%s", linkloc_with_version_dir, de->d_name);
+               subfile = psprintf("%s/%s", linkloc_with_version_dir, de->d_name);
 
                /* This check is just to deliver a friendlier error message */
                if (!redo && !directory_is_empty(subfile))
index 5b6a71c474c932dc8d896e6c5e8c200e3f9fd8a6..7e65d2814c512fa92202c37e6349ede55c2bc95b 100644 (file)
@@ -1015,17 +1015,15 @@ pg_GSS_recvauth(Port *port)
                 */
                if (getenv("KRB5_KTNAME") == NULL)
                {
-                       size_t          kt_len = strlen(pg_krb_server_keyfile) + 14;
-                       char       *kt_path = malloc(kt_len);
+                       char       *kt_path;
 
-                       if (!kt_path)
+                       if (asprintf(&kt_path, "KRB5_KTNAME=%s", pg_krb_server_keyfile) < 0)
                        {
                                ereport(LOG,
                                                (errcode(ERRCODE_OUT_OF_MEMORY),
                                                 errmsg("out of memory")));
                                return STATUS_ERROR;
                        }
-                       snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", pg_krb_server_keyfile);
                        putenv(kt_path);
                }
        }
@@ -1488,8 +1486,7 @@ pg_SSPI_recvauth(Port *port)
                char       *namebuf;
                int                     retval;
 
-               namebuf = palloc(strlen(accountname) + strlen(domainname) + 2);
-               sprintf(namebuf, "%s@%s", accountname, domainname);
+               namebuf = psprintf("%s@%s", accountname, domainname);
                retval = check_usermap(port->hba->usermap, port->user_name, namebuf, true);
                pfree(namebuf);
                return retval;
@@ -2209,8 +2206,7 @@ CheckLDAPAuth(Port *port)
                attributes[0] = port->hba->ldapsearchattribute ? port->hba->ldapsearchattribute : "uid";
                attributes[1] = NULL;
 
-               filter = palloc(strlen(attributes[0]) + strlen(port->user_name) + 4);
-               sprintf(filter, "(%s=%s)",
+               filter = psprintf("(%s=%s)",
                                attributes[0],
                                port->user_name);
 
@@ -2299,17 +2295,10 @@ CheckLDAPAuth(Port *port)
                }
        }
        else
-       {
-               fulluser = palloc((port->hba->ldapprefix ? strlen(port->hba->ldapprefix) : 0) +
-                                                 strlen(port->user_name) +
-                               (port->hba->ldapsuffix ? strlen(port->hba->ldapsuffix) : 0) +
-                                                 1);
-
-               sprintf(fulluser, "%s%s%s",
+               fulluser = psprintf("%s%s%s",
                                port->hba->ldapprefix ? port->hba->ldapprefix : "",
                                port->user_name,
                                port->hba->ldapsuffix ? port->hba->ldapsuffix : "");
-       }
 
        r = ldap_simple_bind_s(ldap, fulluser, passwd);
        ldap_unbind(ldap);
index bafb080d8e40e831fabde5b2e5673d12487c58a6..0df70c4443b171e10bddcc3f1e0cee6b7ed688c7 100644 (file)
@@ -1119,8 +1119,7 @@ SS_process_ctes(PlannerInfo *root)
                root->cte_plan_ids = lappend_int(root->cte_plan_ids, splan->plan_id);
 
                /* Label the subplan for EXPLAIN purposes */
-               splan->plan_name = palloc(4 + strlen(cte->ctename) + 1);
-               sprintf(splan->plan_name, "CTE %s", cte->ctename);
+               splan->plan_name = psprintf("CTE %s", cte->ctename);
 
                /* Lastly, fill in the cost estimates for use later */
                cost_subplan(root, splan, plan);
index 0efe1705e2454b28ea45d5cd33c26d66923eb532..363c603848db457e4510a75b6157346d00607dc0 100644 (file)
@@ -1450,10 +1450,7 @@ set_rest_more:   /* Generic SET syntaxes: */
 
 var_name:      ColId                                                           { $$ = $1; }
                        | var_name '.' ColId
-                               {
-                                       $$ = palloc(strlen($1) + strlen($3) + 2);
-                                       sprintf($$, "%s.%s", $1, $3);
-                               }
+                               { $$ = psprintf("%s.%s", $1, $3); }
                ;
 
 var_list:      var_value                                                               { $$ = list_make1($1); }
@@ -10327,15 +10324,7 @@ ConstCharacter:  CharacterWithLength
 CharacterWithLength:  character '(' Iconst ')' opt_charset
                                {
                                        if (($5 != NULL) && (strcmp($5, "sql_text") != 0))
-                                       {
-                                               char *type;
-
-                                               type = palloc(strlen($1) + 1 + strlen($5) + 1);
-                                               strcpy(type, $1);
-                                               strcat(type, "_");
-                                               strcat(type, $5);
-                                               $1 = type;
-                                       }
+                                               $1 = psprintf("%s_%s", $1, $5);
 
                                        $$ = SystemTypeName($1);
                                        $$->typmods = list_make1(makeIntConst($3, @3));
@@ -10346,15 +10335,7 @@ CharacterWithLength:  character '(' Iconst ')' opt_charset
 CharacterWithoutLength:         character opt_charset
                                {
                                        if (($2 != NULL) && (strcmp($2, "sql_text") != 0))
-                                       {
-                                               char *type;
-
-                                               type = palloc(strlen($1) + 1 + strlen($2) + 1);
-                                               strcpy(type, $1);
-                                               strcat(type, "_");
-                                               strcat(type, $2);
-                                               $1 = type;
-                                       }
+                                               $1 = psprintf("%s_%s", $1, $2);
 
                                        $$ = SystemTypeName($1);
 
@@ -13339,13 +13320,7 @@ doNegateFloat(Value *v)
        if (*oldval == '-')
                v->val.str = oldval+1;  /* just strip the '-' */
        else
-       {
-               char   *newval = (char *) palloc(strlen(oldval) + 2);
-
-               *newval = '-';
-               strcpy(newval+1, oldval);
-               v->val.str = newval;
-       }
+               v->val.str = psprintf("-%s", oldval);
 }
 
 static Node *
index c9a8a8fc459bca448f443e838f73720e70ecaa11..98086f7841055a13cac454bf5032589af742317c 100644 (file)
@@ -1969,12 +1969,7 @@ retry1:
                else
                {
                        /* Append '@' and dbname */
-                       char       *db_user;
-
-                       db_user = palloc(strlen(port->user_name) +
-                                                        strlen(port->database_name) + 2);
-                       sprintf(db_user, "%s@%s", port->user_name, port->database_name);
-                       port->user_name = db_user;
+                       port->user_name = psprintf("%s@%s", port->user_name, port->database_name);
                }
        }
 
index 82551c5f30e6b6b4a40bdff891986fd92499ef9d..015875875be13b636d807be454707cb5438e7a1a 100644 (file)
@@ -377,18 +377,16 @@ cash_out(PG_FUNCTION_ARGS)
         *              from the value.
         *----------
         */
-       result = palloc(strlen(bufptr) + strlen(csymbol) + strlen(signsymbol) + 4);
-
        switch (sign_posn)
        {
                case 0:
                        if (cs_precedes)
-                               sprintf(result, "(%s%s%s)",
+                               result = psprintf("(%s%s%s)",
                                                csymbol,
                                                (sep_by_space == 1) ? " " : "",
                                                bufptr);
                        else
-                               sprintf(result, "(%s%s%s)",
+                               result = psprintf("(%s%s%s)",
                                                bufptr,
                                                (sep_by_space == 1) ? " " : "",
                                                csymbol);
@@ -396,14 +394,14 @@ cash_out(PG_FUNCTION_ARGS)
                case 1:
                default:
                        if (cs_precedes)
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                signsymbol,
                                                (sep_by_space == 2) ? " " : "",
                                                csymbol,
                                                (sep_by_space == 1) ? " " : "",
                                                bufptr);
                        else
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                signsymbol,
                                                (sep_by_space == 2) ? " " : "",
                                                bufptr,
@@ -412,14 +410,14 @@ cash_out(PG_FUNCTION_ARGS)
                        break;
                case 2:
                        if (cs_precedes)
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                csymbol,
                                                (sep_by_space == 1) ? " " : "",
                                                bufptr,
                                                (sep_by_space == 2) ? " " : "",
                                                signsymbol);
                        else
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                bufptr,
                                                (sep_by_space == 1) ? " " : "",
                                                csymbol,
@@ -428,14 +426,14 @@ cash_out(PG_FUNCTION_ARGS)
                        break;
                case 3:
                        if (cs_precedes)
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                signsymbol,
                                                (sep_by_space == 2) ? " " : "",
                                                csymbol,
                                                (sep_by_space == 1) ? " " : "",
                                                bufptr);
                        else
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                bufptr,
                                                (sep_by_space == 1) ? " " : "",
                                                signsymbol,
@@ -444,14 +442,14 @@ cash_out(PG_FUNCTION_ARGS)
                        break;
                case 4:
                        if (cs_precedes)
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                csymbol,
                                                (sep_by_space == 2) ? " " : "",
                                                signsymbol,
                                                (sep_by_space == 1) ? " " : "",
                                                bufptr);
                        else
-                               sprintf(result, "%s%s%s%s%s",
+                               result = psprintf("%s%s%s%s%s",
                                                bufptr,
                                                (sep_by_space == 1) ? " " : "",
                                                csymbol,
index 868474680df3384fd5ad280e72bc0cd4559acb55..08ea457001749014e38d27843aa8df34310b99ae 100644 (file)
@@ -627,18 +627,14 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
        Numeric         size = PG_GETARG_NUMERIC(0);
        Numeric         limit,
                                limit2;
-       char       *buf,
-                          *result;
+       char       *result;
 
        limit = int64_to_numeric(10 * 1024);
        limit2 = int64_to_numeric(10 * 1024 * 2 - 1);
 
        if (numeric_is_less(size, limit))
        {
-               buf = numeric_to_cstring(size);
-               result = palloc(strlen(buf) + 7);
-               strcpy(result, buf);
-               strcat(result, " bytes");
+               result = psprintf("%s bytes", numeric_to_cstring(size));
        }
        else
        {
@@ -650,10 +646,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
                {
                        /* size = (size + 1) / 2 */
                        size = numeric_plus_one_over_two(size);
-                       buf = numeric_to_cstring(size);
-                       result = palloc(strlen(buf) + 4);
-                       strcpy(result, buf);
-                       strcat(result, " kB");
+                       result = psprintf("%s kB", numeric_to_cstring(size));
                }
                else
                {
@@ -663,10 +656,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
                        {
                                /* size = (size + 1) / 2 */
                                size = numeric_plus_one_over_two(size);
-                               buf = numeric_to_cstring(size);
-                               result = palloc(strlen(buf) + 4);
-                               strcpy(result, buf);
-                               strcat(result, " MB");
+                               result = psprintf("%s MB", numeric_to_cstring(size));
                        }
                        else
                        {
@@ -677,10 +667,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
                                {
                                        /* size = (size + 1) / 2 */
                                        size = numeric_plus_one_over_two(size);
-                                       buf = numeric_to_cstring(size);
-                                       result = palloc(strlen(buf) + 4);
-                                       strcpy(result, buf);
-                                       strcat(result, " GB");
+                                       result = psprintf("%s GB", numeric_to_cstring(size));
                                }
                                else
                                {
@@ -688,10 +675,7 @@ pg_size_pretty_numeric(PG_FUNCTION_ARGS)
                                        size = numeric_shift_right(size, 10);
                                        /* size = (size + 1) / 2 */
                                        size = numeric_plus_one_over_two(size);
-                                       buf = numeric_to_cstring(size);
-                                       result = palloc(strlen(buf) + 4);
-                                       strcpy(result, buf);
-                                       strcat(result, " TB");
+                                       result = psprintf("%s TB", numeric_to_cstring(size));
                                }
                        }
                }
index aecdcd056cd3834f88cef9b5a2988d086870fbdd..63a991631de67c6037137ec31fc066fc90d1d0a8 100644 (file)
@@ -242,11 +242,6 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
 
                fctx = palloc(sizeof(ts_db_fctx));
 
-               /*
-                * size = tablespace dirname length + dir sep char + oid + terminator
-                */
-               fctx->location = (char *) palloc(9 + 1 + OIDCHARS + 1 +
-                                                                  strlen(TABLESPACE_VERSION_DIRECTORY) + 1);
                if (tablespaceOid == GLOBALTABLESPACE_OID)
                {
                        fctx->dirdesc = NULL;
@@ -256,9 +251,9 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
                else
                {
                        if (tablespaceOid == DEFAULTTABLESPACE_OID)
-                               sprintf(fctx->location, "base");
+                               fctx->location = psprintf("base");
                        else
-                               sprintf(fctx->location, "pg_tblspc/%u/%s", tablespaceOid,
+                               fctx->location = psprintf("pg_tblspc/%u/%s", tablespaceOid,
                                                TABLESPACE_VERSION_DIRECTORY);
 
                        fctx->dirdesc = AllocateDir(fctx->location);
@@ -297,9 +292,7 @@ pg_tablespace_databases(PG_FUNCTION_ARGS)
 
                /* if database subdir is empty, don't report tablespace as used */
 
-               /* size = path length + dir sep char + file name + terminator */
-               subdir = palloc(strlen(fctx->location) + 1 + strlen(de->d_name) + 1);
-               sprintf(subdir, "%s/%s", fctx->location, de->d_name);
+               subdir = psprintf("%s/%s", fctx->location, de->d_name);
                dirdesc = AllocateDir(subdir);
                while ((de = ReadDir(dirdesc, subdir)) != NULL)
                {
index 562a7c9ab0c10b88d6b3b778722aca15263c1e7f..2dd9f7505627c77ff14182fce7f2468e939e6cb3 100644 (file)
@@ -503,9 +503,7 @@ expand_dynamic_library_name(const char *name)
                pfree(full);
        }
 
-       new = palloc(strlen(name) + strlen(DLSUFFIX) + 1);
-       strcpy(new, name);
-       strcat(new, DLSUFFIX);
+       new = psprintf("%s%s", name, DLSUFFIX);
 
        if (!have_slash)
        {
@@ -554,7 +552,6 @@ static char *
 substitute_libpath_macro(const char *name)
 {
        const char *sep_ptr;
-       char       *ret;
 
        AssertArg(name != NULL);
 
@@ -572,12 +569,7 @@ substitute_libpath_macro(const char *name)
                                 errmsg("invalid macro name in dynamic library path: %s",
                                                name)));
 
-       ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1);
-
-       strcpy(ret, pkglib_path);
-       strcat(ret, sep_ptr);
-
-       return ret;
+       return psprintf("%s%s", pkglib_path, sep_ptr);
 }
 
 
index 42de04c60a8368038d2afdd3cde849251fdcb283..9246a00cbae192a760e44ba5ad9b8e1f7f50a482 100644 (file)
@@ -448,10 +448,7 @@ fetch_finfo_record(void *filehandle, char *funcname)
        const Pg_finfo_record *inforec;
        static Pg_finfo_record default_inforec = {0};
 
-       /* Compute name of info func */
-       infofuncname = (char *) palloc(strlen(funcname) + 10);
-       strcpy(infofuncname, "pg_finfo_");
-       strcat(infofuncname, funcname);
+       infofuncname = psprintf("pg_finfo_%s", funcname);
 
        /* Try to look up the info function */
        infofunc = (PGFInfoFunction) lookup_external_function(filehandle,
index ed514f612803d0b13469436ff2814cb693e786e0..381a629334b9e656bece6e92093de562136156ee 100644 (file)
@@ -165,12 +165,10 @@ make_absolute_path(const char *path)
                        }
                }
 
-               new = malloc(strlen(buf) + strlen(path) + 2);
-               if (!new)
+               if (asprintf(&new, "%s/%s", buf, path) < 0)
                        ereport(FATAL,
                                        (errcode(ERRCODE_OUT_OF_MEMORY),
                                         errmsg("out of memory")));
-               sprintf(new, "%s/%s", buf, path);
                free(buf);
        }
        else
@@ -1286,9 +1284,7 @@ load_libraries(const char *libraries, const char *gucname, bool restricted)
                {
                        char       *expanded;
 
-                       expanded = palloc(strlen("$libdir/plugins/") + strlen(filename) + 1);
-                       strcpy(expanded, "$libdir/plugins/");
-                       strcat(expanded, filename);
+                       expanded = psprintf("$libdir/plugins/%s", filename);
                        pfree(filename);
                        filename = expanded;
                }
index 8db8b3f6ecf087d4feb5dfb5466f491f6df192a3..dfc6704fd4d260eb92e57d7d6b05ce605772db17 100644 (file)
@@ -7938,8 +7938,7 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value)
                name = record->name;
 
        /* build new item for array */
-       newval = palloc(strlen(name) + 1 + strlen(value) + 1);
-       sprintf(newval, "%s=%s", name, value);
+       newval = psprintf("%s=%s", name, value);
        datum = CStringGetTextDatum(newval);
 
        if (array)
index 9574fd3c7a3886fc6900d599fa64ca2eaffce71f..b7beb130ea32f794d93a029e0fde2fbdd750205c 100644 (file)
@@ -852,3 +852,52 @@ pnstrdup(const char *in, Size len)
        out[len] = '\0';
        return out;
 }
+
+/*
+ * asprintf()-like functions around palloc, adapted from
+ * http://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/pkgtools/libnbcompat/files/asprintf.c
+ */
+
+char *
+psprintf(const char *format, ...)
+{
+       va_list ap;
+       char   *retval;
+
+       va_start(ap, format);
+       retval = pvsprintf(format, ap);
+       va_end(ap);
+
+       return retval;
+}
+
+char *
+pvsprintf(const char *format, va_list ap)
+{
+       char *buf, *new_buf;
+       size_t len;
+       int retval;
+       va_list ap2;
+
+       len = 128;
+       buf = palloc(len);
+
+       va_copy(ap2, ap);
+       retval = vsnprintf(buf, len, format, ap);
+       Assert(retval >= 0);
+
+       if (retval < len)
+       {
+               new_buf = repalloc(buf, retval + 1);
+               va_end(ap2);
+               return new_buf;
+       }
+
+       len = (size_t)retval + 1;
+       pfree(buf);
+       buf = palloc(len);
+       retval = vsnprintf(buf, len, format, ap2);
+       va_end(ap2);
+       Assert(retval == len - 1);
+       return buf;
+}
index ebe8a67c0b548f89d7a0abda2e4b2f56112610ce..f2a99ada35d331b0c87cae1d3f87eec6e2ab226d 100644 (file)
@@ -948,13 +948,10 @@ mkdatadir(const char *subdir)
 {
        char       *path;
 
-       path = pg_malloc(strlen(pg_data) + 2 +
-                                        (subdir == NULL ? 0 : strlen(subdir)));
-
-       if (subdir != NULL)
-               sprintf(path, "%s/%s", pg_data, subdir);
+       if (subdir)
+               pg_asprintf(&path, "%s/%s", pg_data, subdir);
        else
-               strcpy(path, pg_data);
+               path = pg_strdup(pg_data);
 
        if (pg_mkdir_p(path, S_IRWXU) == 0)
                return true;
@@ -972,8 +969,7 @@ mkdatadir(const char *subdir)
 static void
 set_input(char **dest, char *filename)
 {
-       *dest = pg_malloc(strlen(share_path) + strlen(filename) + 2);
-       sprintf(*dest, "%s/%s", share_path, filename);
+       pg_asprintf(dest, "%s/%s", share_path, filename);
 }
 
 /*
@@ -1027,15 +1023,9 @@ write_version_file(char *extrapath)
        char       *path;
 
        if (extrapath == NULL)
-       {
-               path = pg_malloc(strlen(pg_data) + 12);
-               sprintf(path, "%s/PG_VERSION", pg_data);
-       }
+               pg_asprintf(&path, "%s/PG_VERSION", pg_data);
        else
-       {
-               path = pg_malloc(strlen(pg_data) + strlen(extrapath) + 13);
-               sprintf(path, "%s/%s/PG_VERSION", pg_data, extrapath);
-       }
+               pg_asprintf(&path, "%s/%s/PG_VERSION", pg_data, extrapath);
 
        if ((version_file = fopen(path, PG_BINARY_W)) == NULL)
        {
@@ -1063,8 +1053,7 @@ set_null_conf(void)
        FILE       *conf_file;
        char       *path;
 
-       path = pg_malloc(strlen(pg_data) + 17);
-       sprintf(path, "%s/postgresql.conf", pg_data);
+       pg_asprintf(&path, "%s/postgresql.conf", pg_data);
        conf_file = fopen(path, PG_BINARY_W);
        if (conf_file == NULL)
        {
@@ -2961,8 +2950,7 @@ setup_pgdata(void)
         * need quotes otherwise on Windows because paths there are most likely to
         * have embedded spaces.
         */
-       pgdata_set_env = pg_malloc(8 + strlen(pg_data));
-       sprintf(pgdata_set_env, "PGDATA=%s", pg_data);
+       pg_asprintf(&pgdata_set_env, "PGDATA=%s", pg_data);
        putenv(pgdata_set_env);
 }
 
@@ -3356,8 +3344,7 @@ create_xlog_symlink(void)
                }
 
                /* form name of the place where the symlink must go */
-               linkloc = (char *) pg_malloc(strlen(pg_data) + 8 + 1);
-               sprintf(linkloc, "%s/pg_xlog", pg_data);
+               pg_asprintf(&linkloc, "%s/pg_xlog", pg_data);
 
 #ifdef HAVE_SYMLINK
                if (symlink(xlog_dir, linkloc) != 0)
index cf50481b746e9c4c054c177accee737396132176..be51dc62ca740aa57552ca137d9849b8688cc127 100644 (file)
@@ -2045,12 +2045,11 @@ main(int argc, char **argv)
                                case 'D':
                                        {
                                                char       *pgdata_D;
-                                               char       *env_var = pg_malloc(strlen(optarg) + 8);
+                                               char       *env_var;
 
                                                pgdata_D = pg_strdup(optarg);
                                                canonicalize_path(pgdata_D);
-                                               snprintf(env_var, strlen(optarg) + 8, "PGDATA=%s",
-                                                                pgdata_D);
+                                               pg_asprintf(&env_var, "PGDATA=%s", pgdata_D);
                                                putenv(env_var);
 
                                                /*
@@ -2058,10 +2057,7 @@ main(int argc, char **argv)
                                                 * variable but we do -D too for clearer postmaster
                                                 * 'ps' display
                                                 */
-                                               pgdata_opt = pg_malloc(strlen(pgdata_D) + 7);
-                                               snprintf(pgdata_opt, strlen(pgdata_D) + 7,
-                                                                "-D \"%s\" ",
-                                                                pgdata_D);
+                                               pg_asprintf(&pgdata_opt,  "-D \"%s\" ", pgdata_D);
                                                break;
                                        }
                                case 'l':
@@ -2102,11 +2098,7 @@ main(int argc, char **argv)
                                                register_username = pg_strdup(optarg);
                                        else
                                                /* Prepend .\ for local accounts */
-                                       {
-                                               register_username = pg_malloc(strlen(optarg) + 3);
-                                               strcpy(register_username, ".\\");
-                                               strcat(register_username, optarg);
-                                       }
+                                               pg_asprintf(&register_username, ".\\%s", optarg);
                                        break;
                                case 'w':
                                        do_wait = true;
index 1dd31fbe2c640dfb3f42f483d430b21fa405a35b..d859c8ee1e96d96fffd5f6b21e1f576f0d6726bf 100644 (file)
@@ -487,10 +487,9 @@ cfopen_read(const char *path, const char *mode)
 #ifdef HAVE_LIBZ
                if (fp == NULL)
                {
-                       int                     fnamelen = strlen(path) + 4;
-                       char       *fname = pg_malloc(fnamelen);
+                       char       *fname;
 
-                       snprintf(fname, fnamelen, "%s%s", path, ".gz");
+                       pg_asprintf(&fname, "%s.gz", path);
                        fp = cfopen(fname, mode, 1);
                        free(fname);
                }
@@ -518,10 +517,9 @@ cfopen_write(const char *path, const char *mode, int compression)
        else
        {
 #ifdef HAVE_LIBZ
-               int                     fnamelen = strlen(path) + 4;
-               char       *fname = pg_malloc(fnamelen);
+               char       *fname;
 
-               snprintf(fname, fnamelen, "%s%s", path, ".gz");
+               pg_asprintf(&fname, "%s.gz", path);
                fp = cfopen(fname, mode, 1);
                free(fname);
 #else
index 57320cc83a6fe625f3b07bfa0ebf50f529b052cc..01c63b133483c0d6a6bbd66490631bc997da9b36 100644 (file)
@@ -10439,8 +10439,7 @@ convertOperatorReference(Archive *fout, const char *opr)
                /* If not schema-qualified, don't need to add OPERATOR() */
                if (!sawdot)
                        return name;
-               oname = pg_malloc(strlen(name) + 11);
-               sprintf(oname, "OPERATOR(%s)", name);
+               pg_asprintf(&oname, "OPERATOR(%s)", name);
                free(name);
                return oname;
        }
@@ -12754,8 +12753,7 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
                                char       *acltag;
 
                                attnamecopy = pg_strdup(fmtId(attname));
-                               acltag = pg_malloc(strlen(tbinfo->dobj.name) + strlen(attname) + 2);
-                               sprintf(acltag, "%s.%s", tbinfo->dobj.name, attname);
+                               pg_asprintf(&acltag, "%s.%s", tbinfo->dobj.name, attname);
                                /* Column's GRANT type is always TABLE */
                                dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, "TABLE",
                                                namecopy, attnamecopy, acltag,
index b22e4f6190a74b59e7b8fe432ee6402705626553..06ed56be683635eb1200745a921575b62ed4611d 100644 (file)
@@ -1186,10 +1186,9 @@ exec_command(const char *cmd,
                else
                {
                        /* Set variable to the value of the next argument */
-                       int                     len = strlen(envvar) + strlen(envval) + 1;
-                       char       *newval = pg_malloc(len + 1);
+                       char       *newval;
 
-                       snprintf(newval, len + 1, "%s=%s", envvar, envval);
+                       pg_asprintf(&newval, "%s=%s", envvar, envval);
                        putenv(newval);
                        success = true;
 
@@ -1550,9 +1549,7 @@ prompt_for_password(const char *username)
        {
                char       *prompt_text;
 
-               prompt_text = pg_malloc(strlen(username) + 100);
-               snprintf(prompt_text, strlen(username) + 100,
-                                _("Password for user %s: "), username);
+               pg_asprintf(&prompt_text, _("Password for user %s: "), username);
                result = simple_prompt(prompt_text, 100, false);
                free(prompt_text);
        }
@@ -1923,14 +1920,6 @@ editFile(const char *fname, int lineno)
                }
        }
 
-       /* Allocate sufficient memory for command line. */
-       if (lineno > 0)
-               sys = pg_malloc(strlen(editorName)
-                                               + strlen(editor_lineno_arg) + 10                /* for integer */
-                                               + 1 + strlen(fname) + 10 + 1);
-       else
-               sys = pg_malloc(strlen(editorName) + strlen(fname) + 10 + 1);
-
        /*
         * On Unix the EDITOR value should *not* be quoted, since it might include
         * switches, eg, EDITOR="pico -t"; it's up to the user to put quotes in it
@@ -1940,18 +1929,18 @@ editFile(const char *fname, int lineno)
         */
 #ifndef WIN32
        if (lineno > 0)
-               sprintf(sys, "exec %s %s%d '%s'",
-                               editorName, editor_lineno_arg, lineno, fname);
+               pg_asprintf(&sys, "exec %s %s%d '%s'",
+                                       editorName, editor_lineno_arg, lineno, fname);
        else
-               sprintf(sys, "exec %s '%s'",
-                               editorName, fname);
+               pg_asprintf(&sys, "exec %s '%s'",
+                                       editorName, fname);
 #else
        if (lineno > 0)
-               sprintf(sys, SYSTEMQUOTE "\"%s\" %s%d \"%s\"" SYSTEMQUOTE,
+               pg_asprintf(&sys, SYSTEMQUOTE "\"%s\" %s%d \"%s\"" SYSTEMQUOTE,
                                editorName, editor_lineno_arg, lineno, fname);
        else
-               sprintf(sys, SYSTEMQUOTE "\"%s\" \"%s\"" SYSTEMQUOTE,
-                               editorName, fname);
+               pg_asprintf(&sys, SYSTEMQUOTE "\"%s\" \"%s\"" SYSTEMQUOTE,
+                                       editorName, fname);
 #endif
        result = system(sys);
        if (result == -1)
@@ -2644,14 +2633,11 @@ do_shell(const char *command)
                if (shellName == NULL)
                        shellName = DEFAULT_SHELL;
 
-               sys = pg_malloc(strlen(shellName) + 16);
-#ifndef WIN32
-               sprintf(sys,
                /* See EDITOR handling comment for an explanation */
-                               "exec %s", shellName);
+#ifndef WIN32
+               pg_asprintf(&sys, "exec %s", shellName);
 #else
-               /* See EDITOR handling comment for an explanation */
-               sprintf(sys, SYSTEMQUOTE "\"%s\"" SYSTEMQUOTE, shellName);
+               pg_asprintf(&sys, SYSTEMQUOTE "\"%s\"" SYSTEMQUOTE, shellName);
 #endif
                result = system(sys);
                free(sys);
index 3dea92c7d8f3bb6868754746f7cc1290713ca885..71f0c8a95a836aafeea289706302c85e54456ee5 100644 (file)
@@ -594,9 +594,7 @@ StoreQueryTuple(const PGresult *result)
                        char       *value;
 
                        /* concate prefix and column name */
-                       varname = pg_malloc(strlen(pset.gset_prefix) + strlen(colname) + 1);
-                       strcpy(varname, pset.gset_prefix);
-                       strcat(varname, colname);
+                       pg_asprintf(&varname, "%s%s", pset.gset_prefix, colname);
 
                        if (!PQgetisnull(result, 0, i))
                                value = PQgetvalue(result, 0, i);
@@ -1687,10 +1685,7 @@ expand_tilde(char **filename)
                {
                        char       *newfn;
 
-                       newfn = pg_malloc(strlen(home) + strlen(p) + 1);
-                       strcpy(newfn, home);
-                       strcat(newfn, p);
-
+                       pg_asprintf(&newfn, "%s%s", home, p);
                        free(fn);
                        *filename = newfn;
                }
index 13123d600dbb89dd84fc49561a8c662ce2fe9bbf..6db063ca95371d8fad9bde84f7c3025005fd7bad 100644 (file)
@@ -79,9 +79,7 @@ xstrcat(char **var, const char *more)
 {
        char       *newvar;
 
-       newvar = pg_malloc(strlen(*var) + strlen(more) + 1);
-       strcpy(newvar, *var);
-       strcat(newvar, more);
+       pg_asprintf(&newvar, "%s%s", *var, more);
        free(*var);
        *var = newvar;
 }
index 07c9e89f36805c3ce71c73161dce654798f91124..f2b6e4ed7fa6764879e729588618168281781f70 100644 (file)
@@ -298,11 +298,7 @@ initializeInput(int flags)
                if (histfile == NULL)
                {
                        if (get_home_path(home))
-                       {
-                               psql_history = pg_malloc(strlen(home) + 1 +
-                                                                                strlen(PSQLHISTORY) + 1);
-                               snprintf(psql_history, MAXPGPATH, "%s/%s", home, PSQLHISTORY);
-                       }
+                               pg_asprintf(&psql_history, "%s/%s", home, PSQLHISTORY);
                }
                else
                {
index faaecce61448b9481b3d7c946019caa3488212cb..065e0c1cb24d2721573bb605fd6acbe85841774a 100644 (file)
@@ -200,12 +200,12 @@ do_lo_import(const char *filename_arg, const char *comment_arg)
                char       *cmdbuf;
                char       *bufptr;
                size_t          slen = strlen(comment_arg);
+               int                     rv;
 
-               cmdbuf = malloc(slen * 2 + 256);
-               if (!cmdbuf)
+               rv = asprintf(&cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
+               if (rv < 0)
                        return fail_lo_xact("\\lo_import", own_transaction);
-               sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid);
-               bufptr = cmdbuf + strlen(cmdbuf);
+               bufptr = cmdbuf + rv;
                bufptr += PQescapeStringConn(pset.db, bufptr, comment_arg, slen, NULL);
                strcpy(bufptr, "'");
 
index dc06f6670274c7fb09c0d41ac3dc8ef8528ff469..a45ec552f4253aec06e4ce34bc124027557b1dc9 100644 (file)
@@ -182,12 +182,8 @@ main(int argc, char *argv[])
        if (options.username == NULL)
                password_prompt = pg_strdup(_("Password: "));
        else
-       {
-               password_prompt = pg_malloc(strlen(_("Password for user %s: ")) - 2 +
-                                                                       strlen(options.username) + 1);
-               sprintf(password_prompt, _("Password for user %s: "),
-                               options.username);
-       }
+               pg_asprintf(&password_prompt, _("Password for user %s: "),
+                                       options.username);
 
        if (pset.getPassword == TRI_YES)
                password = simple_prompt(password_prompt, 100, false);
@@ -642,10 +638,8 @@ process_psqlrc_file(char *filename)
 #define R_OK 4
 #endif
 
-       psqlrc_minor = pg_malloc(strlen(filename) + 1 + strlen(PG_VERSION) + 1);
-       sprintf(psqlrc_minor, "%s-%s", filename, PG_VERSION);
-       psqlrc_major = pg_malloc(strlen(filename) + 1 + strlen(PG_MAJORVERSION) + 1);
-       sprintf(psqlrc_major, "%s-%s", filename, PG_MAJORVERSION);
+       pg_asprintf(&psqlrc_minor, "%s-%s", filename, PG_VERSION);
+       pg_asprintf(&psqlrc_major, "%s-%s", filename, PG_MAJORVERSION);
 
        /* check for minor version first, then major, then no version */
        if (access(psqlrc_minor, R_OK) == 0)
index 255061c1c417835cc3c71e300ffa95195bd4aad9..ae8f8370f9559a060302159e13c081b0df1d6b18 100644 (file)
@@ -3822,7 +3822,6 @@ static char **
 complete_from_variables(char *text, const char *prefix, const char *suffix)
 {
        char      **matches;
-       int                     overhead = strlen(prefix) + strlen(suffix) + 1;
        char      **varnames;
        int                     nvars = 0;
        int                     maxvars = 100;
@@ -3847,8 +3846,7 @@ complete_from_variables(char *text, const char *prefix, const char *suffix)
                        }
                }
 
-               buffer = (char *) pg_malloc(strlen(ptr->name) + overhead);
-               sprintf(buffer, "%s%s%s", prefix, ptr->name, suffix);
+               pg_asprintf(&buffer, "%s%s%s", prefix, ptr->name, suffix);
                varnames[nvars++] = buffer;
        }
 
index bfe79f8e4371068edd1334bab88614b4617e89fb..7b96a4b6ba7aaf48304bfbd7c95e1b485154bf7e 100644 (file)
@@ -93,6 +93,25 @@ pg_free(void *ptr)
                free(ptr);
 }
 
+int
+pg_asprintf(char **ret, const char *format, ...)
+{
+       va_list         ap;
+       int                     rc;
+
+       va_start(ap, format);
+       rc = vasprintf(ret, format, ap);
+       va_end(ap);
+
+       if (rc < 0)
+       {
+               fprintf(stderr, _("out of memory\n"));
+               exit(EXIT_FAILURE);
+       }
+
+       return rc;
+}
+
 /*
  * Frontend emulation of backend memory management functions.  Useful for
  * programs that compile backend files.
@@ -126,3 +145,23 @@ repalloc(void *pointer, Size size)
 {
        return pg_realloc(pointer, size);
 }
+
+char *
+psprintf(const char *format, ...)
+{
+       va_list     ap;
+       int         rc;
+       char       *ret;
+
+       va_start(ap, format);
+       rc = vasprintf(&ret, format, ap);
+       va_end(ap);
+
+       if (rc < 0)
+       {
+               fprintf(stderr, _("out of memory\n"));
+               exit(EXIT_FAILURE);
+       }
+
+       return ret;
+}
index 52f6b751e3b6cfaa1dd04ac3db70db24c49e6fe7..737003aefeade11771d7616231eb1909f9560064 100644 (file)
@@ -74,7 +74,6 @@ forkname_chars(const char *str, ForkNumber *fork)
 char *
 relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
 {
-       int                     pathlen;
        char       *path;
 
        if (rnode.spcNode == GLOBALTABLESPACE_OID)
@@ -82,41 +81,33 @@ relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
                /* Shared system relations live in {datadir}/global */
                Assert(rnode.dbNode == 0);
                Assert(backend == InvalidBackendId);
-               pathlen = 7 + OIDCHARS + 1 + FORKNAMECHARS + 1;
-               path = (char *) palloc(pathlen);
                if (forknum != MAIN_FORKNUM)
-                       snprintf(path, pathlen, "global/%u_%s",
+                       path = psprintf("global/%u_%s",
                                         rnode.relNode, forkNames[forknum]);
                else
-                       snprintf(path, pathlen, "global/%u", rnode.relNode);
+                       path = psprintf("global/%u", rnode.relNode);
        }
        else if (rnode.spcNode == DEFAULTTABLESPACE_OID)
        {
                /* The default tablespace is {datadir}/base */
                if (backend == InvalidBackendId)
                {
-                       pathlen = 5 + OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1;
-                       path = (char *) palloc(pathlen);
                        if (forknum != MAIN_FORKNUM)
-                               snprintf(path, pathlen, "base/%u/%u_%s",
+                               path = psprintf("base/%u/%u_%s",
                                                 rnode.dbNode, rnode.relNode,
                                                 forkNames[forknum]);
                        else
-                               snprintf(path, pathlen, "base/%u/%u",
+                               path = psprintf("base/%u/%u",
                                                 rnode.dbNode, rnode.relNode);
                }
                else
                {
-                       /* OIDCHARS will suffice for an integer, too */
-                       pathlen = 5 + OIDCHARS + 2 + OIDCHARS + 1 + OIDCHARS + 1
-                               + FORKNAMECHARS + 1;
-                       path = (char *) palloc(pathlen);
                        if (forknum != MAIN_FORKNUM)
-                               snprintf(path, pathlen, "base/%u/t%d_%u_%s",
+                               path = psprintf("base/%u/t%d_%u_%s",
                                                 rnode.dbNode, backend, rnode.relNode,
                                                 forkNames[forknum]);
                        else
-                               snprintf(path, pathlen, "base/%u/t%d_%u",
+                               path = psprintf("base/%u/t%d_%u",
                                                 rnode.dbNode, backend, rnode.relNode);
                }
        }
@@ -125,34 +116,25 @@ relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
                /* All other tablespaces are accessed via symlinks */
                if (backend == InvalidBackendId)
                {
-                       pathlen = 9 + 1 + OIDCHARS + 1
-                               + strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 1
-                               + OIDCHARS + 1 + FORKNAMECHARS + 1;
-                       path = (char *) palloc(pathlen);
                        if (forknum != MAIN_FORKNUM)
-                               snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u_%s",
+                               path = psprintf("pg_tblspc/%u/%s/%u/%u_%s",
                                                 rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
                                                 rnode.dbNode, rnode.relNode,
                                                 forkNames[forknum]);
                        else
-                               snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/%u",
+                               path = psprintf("pg_tblspc/%u/%s/%u/%u",
                                                 rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
                                                 rnode.dbNode, rnode.relNode);
                }
                else
                {
-                       /* OIDCHARS will suffice for an integer, too */
-                       pathlen = 9 + 1 + OIDCHARS + 1
-                               + strlen(TABLESPACE_VERSION_DIRECTORY) + 1 + OIDCHARS + 2
-                               + OIDCHARS + 1 + OIDCHARS + 1 + FORKNAMECHARS + 1;
-                       path = (char *) palloc(pathlen);
                        if (forknum != MAIN_FORKNUM)
-                               snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u_%s",
+                               path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s",
                                                 rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
                                                 rnode.dbNode, backend, rnode.relNode,
                                                 forkNames[forknum]);
                        else
-                               snprintf(path, pathlen, "pg_tblspc/%u/%s/%u/t%d_%u",
+                               path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u",
                                                 rnode.spcNode, TABLESPACE_VERSION_DIRECTORY,
                                                 rnode.dbNode, backend, rnode.relNode);
                }
index 82ed8cd9e64c3c2b0002661de1f5daccb801400a..db4e710b465e8a035b9edd523fdcbfb2a8651b59 100644 (file)
@@ -14,6 +14,7 @@ extern void *pg_malloc(size_t size);
 extern void *pg_malloc0(size_t size);
 extern void *pg_realloc(void *pointer, size_t size);
 extern void pg_free(void *pointer);
+extern int pg_asprintf(char **ret, const char *format, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
 
 #include "utils/palloc.h"
 
index 5eac52d93a9c24f78f7324c45d87ffee0da9cb7c..0250e39dbbbb6883f120aec92b786ecaffb475c6 100644 (file)
@@ -87,6 +87,9 @@
 /* Define to 1 if you have the `append_history' function. */
 #undef HAVE_APPEND_HISTORY
 
+/* Define to 1 if you have the `asprintf' function. */
+#undef HAVE_ASPRINTF
+
 /* Define to 1 if you have the `cbrt' function. */
 #undef HAVE_CBRT
 
index 5ef4b0a0b11863d96213e4379ee958109691cb98..0b9dfc81e2a3d23176f90a1b52bda74a5dfea01a 100644 (file)
@@ -404,6 +404,11 @@ extern double rint(double x);
 extern int     inet_aton(const char *cp, struct in_addr * addr);
 #endif
 
+#ifndef HAVE_ASPRINTF
+extern int asprintf(char **ret, const char *fmt, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
+extern int vasprintf(char **ret, const char *fmt, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 0)));
+#endif
+
 #if !HAVE_DECL_STRLCAT
 extern size_t strlcat(char *dst, const char *src, size_t siz);
 #endif
index 01e7db5d4f9cdeccc19af5e5c223409f5024c7cf..03ef87e2d7f591ff1ac58ca85b59c189ecedf5f2 100644 (file)
@@ -101,5 +101,7 @@ extern void *palloc(Size size);
 extern void *palloc0(Size size);
 extern void pfree(void *pointer);
 extern void *repalloc(void *pointer, Size size);
+extern char *psprintf(const char *format, ...) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
+extern char *pvsprintf(const char *format, va_list ap) __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 0)));
 
 #endif   /* PALLOC_H */
index d3ebb0e106c35f6f353f4e17feb539b4f776022b..8d716e58a22fd909f5da9615b49ca215eea6967c 100644 (file)
@@ -127,12 +127,9 @@ main(void)
                {
                        for (j = 0; times[j]; j++)
                        {
-                               int length = strlen(dates[i])
-                                               + 1
-                                               + strlen(times[j])
-                                               + 1;
-                               char* t = malloc(length);
-                               sprintf(t, "%s %s", dates[i], times[j]);
+                               char* t;
+                               if (asprintf(&t, "%s %s", dates[i], times[j]) < 0)
+                                       abort();
                                ts1 = PGTYPEStimestamp_from_asc(t, NULL);
                                text = PGTYPEStimestamp_to_asc(ts1);
                                if (i != 19 || j != 3) /* timestamp as integer or double differ for this case */
index 0edf012fd11253da11ddbae50f8b08bd7d5fa81b..2a1c4a61dd9873db3410657049ff33e9a190a99e 100644 (file)
@@ -92,12 +92,9 @@ main(void)
                {
                        for (j = 0; times[j]; j++)
                        {
-                               int length = strlen(dates[i])
-                                               + 1
-                                               + strlen(times[j])
-                                               + 1;
-                               char* t = malloc(length);
-                               sprintf(t, "%s %s", dates[i], times[j]);
+                               char* t;
+                               if (asprintf(&t, "%s %s", dates[i], times[j]) < 0)
+                                       abort();
                                ts1 = PGTYPEStimestamp_from_asc(t, NULL);
                                text = PGTYPEStimestamp_to_asc(ts1);
                                if (i != 19 || j != 3) /* timestamp as integer or double differ for this case */
index 5666a6b8dd81856b9459aba70dca3f84d08482ac..dfc9cfb1fbe88a62c111768793891eb0cee2877e 100644 (file)
@@ -420,7 +420,6 @@ pg_GSS_startup(PGconn *conn)
 {
        OM_uint32       maj_stat,
                                min_stat;
-       int                     maxlen;
        gss_buffer_desc temp_gbuf;
 
        if (!(conn->pghost && conn->pghost[0] != '\0'))
@@ -441,10 +440,14 @@ pg_GSS_startup(PGconn *conn)
         * Import service principal name so the proper ticket can be acquired by
         * the GSSAPI system.
         */
-       maxlen = NI_MAXHOST + strlen(conn->krbsrvname) + 2;
-       temp_gbuf.value = (char *) malloc(maxlen);
-       snprintf(temp_gbuf.value, maxlen, "%s@%s",
-                        conn->krbsrvname, conn->pghost);
+       if (asprintf((char **)&temp_gbuf.value, "%s@%s",
+                                conn->krbsrvname, conn->pghost) < 0)
+       {
+               printfPQExpBuffer(&conn->errorMessage,
+                                                 libpq_gettext("out of memory"));
+               return STATUS_ERROR;
+       }
+
        temp_gbuf.length = strlen(temp_gbuf.value);
 
        maj_stat = gss_import_name(&min_stat, &temp_gbuf,
@@ -656,13 +659,11 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
                                                  libpq_gettext("host name must be specified\n"));
                return STATUS_ERROR;
        }
-       conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
-       if (!conn->sspitarget)
+       if (asprintf(&conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost) < 0)
        {
                printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
                return STATUS_ERROR;
        }
-       sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);
 
        /*
         * Indicate that we're in SSPI authentication mode to make sure that
index f62565046c3648798c474e80024c56a1a9625d2e..7a3572f0c17b2572760e1fa65c6cc46861d83556 100644 (file)
@@ -466,8 +466,7 @@ report_two_error_messages(Step * step1, Step * step2)
 {
        char       *prefix;
 
-       prefix = malloc(strlen(step1->name) + strlen(step2->name) + 2);
-       sprintf(prefix, "%s %s", step1->name, step2->name);
+       pg_asprintf(&prefix, "%s %s", step1->name, step2->name);
 
        if (step1->errormsg)
        {
@@ -795,12 +794,9 @@ try_complete_step(Step * step, int flags)
                                                                                                        PG_DIAG_MESSAGE_PRIMARY);
 
                                        if (sev && msg)
-                                       {
-                                               step->errormsg = malloc(5 + strlen(sev) + strlen(msg));
-                                               sprintf(step->errormsg, "%s:  %s", sev, msg);
-                                       }
+                                               pg_asprintf(&step->errormsg, "%s:  %s", sev, msg);
                                        else
-                                               step->errormsg = strdup(PQresultErrorMessage(res));
+                                               step->errormsg = pg_strdup(PQresultErrorMessage(res));
                                }
                                break;
                        default:
index b632326e08df4f75a31cd34e8f76c715d3fd90f4..e51d08878dacf848b47376e58e2f776aafae913a 100644 (file)
@@ -654,9 +654,9 @@ get_expectfile(const char *testname, const char *file)
 static void
 doputenv(const char *var, const char *val)
 {
-       char       *s = malloc(strlen(var) + strlen(val) + 2);
+       char       *s;
 
-       sprintf(s, "%s=%s", var, val);
+       pg_asprintf(&s, "%s=%s", var, val);
        putenv(s);
 }
 
@@ -671,16 +671,11 @@ add_to_path(const char *pathname, char separator, const char *addval)
        char       *newval;
 
        if (!oldval || !oldval[0])
-       {
                /* no previous value */
-               newval = malloc(strlen(pathname) + strlen(addval) + 2);
-               sprintf(newval, "%s=%s", pathname, addval);
-       }
+               pg_asprintf(&newval, "%s=%s", pathname, addval);
        else
-       {
-               newval = malloc(strlen(pathname) + strlen(addval) + strlen(oldval) + 3);
-               sprintf(newval, "%s=%s%c%s", pathname, addval, separator, oldval);
-       }
+               pg_asprintf(&newval, "%s=%s%c%s", pathname, addval, separator, oldval);
+
        putenv(newval);
 }
 
@@ -747,8 +742,7 @@ initialize_environment(void)
 
                if (!old_pgoptions)
                        old_pgoptions = "";
-               new_pgoptions = malloc(strlen(old_pgoptions) + strlen(my_pgoptions) + 12);
-               sprintf(new_pgoptions, "PGOPTIONS=%s %s", old_pgoptions, my_pgoptions);
+               pg_asprintf(&new_pgoptions, "PGOPTIONS=%s %s", old_pgoptions, my_pgoptions);
                putenv(new_pgoptions);
        }
 
@@ -798,16 +792,13 @@ initialize_environment(void)
                /*
                 * Adjust path variables to point into the temp-install tree
                 */
-               tmp = malloc(strlen(temp_install) + 32 + strlen(bindir));
-               sprintf(tmp, "%s/install/%s", temp_install, bindir);
+               pg_asprintf(&tmp, "%s/install/%s", temp_install, bindir);
                bindir = tmp;
 
-               tmp = malloc(strlen(temp_install) + 32 + strlen(libdir));
-               sprintf(tmp, "%s/install/%s", temp_install, libdir);
+               pg_asprintf(&tmp, "%s/install/%s", temp_install, libdir);
                libdir = tmp;
 
-               tmp = malloc(strlen(temp_install) + 32 + strlen(datadir));
-               sprintf(tmp, "%s/install/%s", temp_install, datadir);
+               pg_asprintf(&tmp, "%s/install/%s", temp_install, datadir);
                datadir = tmp;
 
                /* psql will be installed into temp-install bindir */
@@ -961,9 +952,9 @@ spawn_process(const char *cmdline)
                 * "exec" the command too.      This saves two useless processes per
                 * parallel test case.
                 */
-               char       *cmdline2 = malloc(strlen(cmdline) + 6);
+               char       *cmdline2;
 
-               sprintf(cmdline2, "exec %s", cmdline);
+               pg_asprintf(&cmdline2, "exec %s", cmdline);
                execl(shellprog, shellprog, "-c", cmdline2, (char *) NULL);
                fprintf(stderr, _("%s: could not exec \"%s\": %s\n"),
                                progname, shellprog, strerror(errno));
@@ -1040,8 +1031,7 @@ spawn_process(const char *cmdline)
                exit(2);
        }
 
-       cmdline2 = malloc(strlen(cmdline) + 8);
-       sprintf(cmdline2, "cmd /c %s", cmdline);
+       pg_asprintf(&cmdline2, "cmd /c %s", cmdline);
 
 #ifndef __CYGWIN__
        AddUserToTokenDacl(restrictedToken);
@@ -1862,8 +1852,7 @@ make_absolute_path(const char *in)
                        }
                }
 
-               result = malloc(strlen(cwdbuf) + strlen(in) + 2);
-               sprintf(result, "%s/%s", cwdbuf, in);
+               pg_asprintf(&result, "%s/%s", cwdbuf, in);
        }
 
        canonicalize_path(result);