-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
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
/* 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);
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"
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",
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
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);
}
}
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);
/*
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");
(*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)++;
(*nplans) = i = 0;
}
- newp->ident = (char *) malloc(strlen(ident) + 1);
- strcpy(newp->ident, ident);
+ newp->ident = strdup(ident);
newp->splan = NULL;
(*nplans)++;
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,
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;
}
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);
/*
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);
/*
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))
*/
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);
}
}
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;
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);
}
}
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);
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);
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); }
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));
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);
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 *
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);
}
}
* 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);
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,
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,
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,
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,
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
{
{
/* 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
{
{
/* 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
{
{
/* 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
{
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));
}
}
}
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;
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);
/* 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)
{
pfree(full);
}
- new = palloc(strlen(name) + strlen(DLSUFFIX) + 1);
- strcpy(new, name);
- strcat(new, DLSUFFIX);
+ new = psprintf("%s%s", name, DLSUFFIX);
if (!have_slash)
{
substitute_libpath_macro(const char *name)
{
const char *sep_ptr;
- char *ret;
AssertArg(name != NULL);
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);
}
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,
}
}
- 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
{
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;
}
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)
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;
+}
{
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;
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);
}
/*
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)
{
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)
{
* 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);
}
}
/* 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)
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);
/*
* 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':
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(®ister_username, ".\\%s", optarg);
break;
case 'w':
do_wait = true;
#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);
}
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
/* 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;
}
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,
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;
{
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);
}
}
}
- /* 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
*/
#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)
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);
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);
{
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;
}
{
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;
}
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
{
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, "'");
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);
#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)
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;
}
}
- 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;
}
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.
{
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;
+}
char *
relpathbackend(RelFileNode rnode, BackendId backend, ForkNumber forknum)
{
- int pathlen;
char *path;
if (rnode.spcNode == GLOBALTABLESPACE_OID)
/* 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);
}
}
/* 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);
}
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"
/* 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
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
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 */
{
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 */
{
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 */
{
OM_uint32 maj_stat,
min_stat;
- int maxlen;
gss_buffer_desc temp_gbuf;
if (!(conn->pghost && conn->pghost[0] != '\0'))
* 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,
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
{
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)
{
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:
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);
}
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);
}
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);
}
/*
* 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 */
* "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));
exit(2);
}
- cmdline2 = malloc(strlen(cmdline) + 8);
- sprintf(cmdline2, "cmd /c %s", cmdline);
+ pg_asprintf(&cmdline2, "cmd /c %s", cmdline);
#ifndef __CYGWIN__
AddUserToTokenDacl(restrictedToken);
}
}
- result = malloc(strlen(cwdbuf) + strlen(in) + 2);
- sprintf(result, "%s/%s", cwdbuf, in);
+ pg_asprintf(&result, "%s/%s", cwdbuf, in);
}
canonicalize_path(result);