PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
psprintf.c File Reference
#include "postgres.h"
#include "utils/memutils.h"
Include dependency graph for psprintf.c:

Go to the source code of this file.

Functions

char * psprintf (const char *fmt,...)
 
size_t pvsnprintf (char *buf, size_t len, const char *fmt, va_list args)
 

Function Documentation

char* psprintf ( const char *  fmt,
  ... 
)

Definition at line 46 of file psprintf.c.

References generate_unaccent_rules::args, palloc(), pfree(), pvsnprintf(), and result.

Referenced by _mdfd_segpath(), anytime_typmodout(), anytimestamp_typmodout(), auth_failed(), AuxiliaryProcessMain(), BaseBackup(), brin_desummarize_range(), brin_metapage_info(), brin_page_type(), brin_summarize_range(), bt_metap(), bt_page_print_tuples(), bt_page_stats(), bt_target_page_check(), build_function_result_tupdesc_d(), build_server_final_message(), build_server_first_message(), cash_out(), cfopen_read(), cfopen_write(), complex_out(), convertOperatorReference(), create_script_for_cluster_analyze(), create_script_for_old_cluster_deletion(), create_tablespace_directories(), create_xlog_or_symlink(), datasegpath(), dblink_get_pkey(), defGetString(), destroy_tablespace_directories(), do_shell(), doputenv(), dumpAttrDef(), dumpConstraint(), dumpPolicy(), dumpPublicationTable(), dumpRule(), dumpTable(), dumpTrigger(), editFile(), exec_command_setenv(), expand_dynamic_library_name(), expand_tilde(), ExplainNode(), fetch_finfo_record(), format_type_internal(), get_role_password(), get_user_name(), GetDatabasePath(), gethba_options(), getObjectIdentityParts(), GetRelationPath(), GUCArrayAdd(), HandleParallelMessage(), initialize_data_directory(), initialize_environment(), initializeInput(), line_out(), load_libraries(), log_line_prefix(), LogicalRepSyncTableStart(), LogStreamerMain(), main(), md5_crypt_verify(), parse_hba_auth_opt(), parse_hba_line(), parseCommandLine(), perform_base_backup(), pg_be_scram_init(), pg_control_checkpoint(), pg_get_multixact_members(), pg_import_system_collations(), pg_logdir_ls(), pg_putenv(), pg_size_pretty_numeric(), pg_tablespace_databases(), pgstatindex_impl(), plain_crypt_verify(), printTypmod(), process_psqlrc_file(), ProcessStartupPacket(), prompt_for_password(), pset_value_string(), psql_start_test(), set_input(), set_null_conf(), set_tablespace_directory_suffix(), setup_pgdata(), spawn_process(), sql_exec_searchtables(), SS_make_initplan_from_plan(), SS_process_ctes(), StartupXLOG(), StoreQueryTuple(), substitute_libpath_macro(), tokenize_file(), tokenize_inc_file(), try_complete_step(), typenameTypeMod(), widget_out(), write_version_file(), XLogDumpDisplayRecord(), XLogDumpDisplayStats(), and xstrcat().

47 {
48  size_t len = 128; /* initial assumption about buffer size */
49 
50  for (;;)
51  {
52  char *result;
53  va_list args;
54  size_t newlen;
55 
56  /*
57  * Allocate result buffer. Note that in frontend this maps to malloc
58  * with exit-on-error.
59  */
60  result = (char *) palloc(len);
61 
62  /* Try to format the data. */
63  va_start(args, fmt);
64  newlen = pvsnprintf(result, len, fmt, args);
65  va_end(args);
66 
67  if (newlen < len)
68  return result; /* success */
69 
70  /* Release buffer and loop around to try again with larger len. */
71  pfree(result);
72  len = newlen;
73  }
74 }
return result
Definition: formatting.c:1633
void pfree(void *pointer)
Definition: mcxt.c:950
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:104
void * palloc(Size size)
Definition: mcxt.c:849
size_t pvsnprintf ( char *  buf,
size_t  len,
const char *  fmt,
va_list  args 
)

Definition at line 104 of file psprintf.c.

References _, Assert, elog, ereport, errcode(), errmsg(), ERROR, EXIT_FAILURE, MaxAllocSize, strerror(), and vsnprintf().

Referenced by ahprintf(), appendStringInfoVA(), archprintf(), psprintf(), and tarPrintf().

105 {
106  int nprinted;
107 
108  Assert(len > 0);
109 
110  errno = 0;
111 
112  /*
113  * Assert check here is to catch buggy vsnprintf that overruns the
114  * specified buffer length. Solaris 7 in 64-bit mode is an example of a
115  * platform with such a bug.
116  */
117 #ifdef USE_ASSERT_CHECKING
118  buf[len - 1] = '\0';
119 #endif
120 
121  nprinted = vsnprintf(buf, len, fmt, args);
122 
123  Assert(buf[len - 1] == '\0');
124 
125  /*
126  * If vsnprintf reports an error other than ENOMEM, fail. The possible
127  * causes of this are not user-facing errors, so elog should be enough.
128  */
129  if (nprinted < 0 && errno != 0 && errno != ENOMEM)
130  {
131 #ifndef FRONTEND
132  elog(ERROR, "vsnprintf failed: %m");
133 #else
134  fprintf(stderr, "vsnprintf failed: %s\n", strerror(errno));
135  exit(EXIT_FAILURE);
136 #endif
137  }
138 
139  /*
140  * Note: some versions of vsnprintf return the number of chars actually
141  * stored, not the total space needed as C99 specifies. And at least one
142  * returns -1 on failure. Be conservative about believing whether the
143  * print worked.
144  */
145  if (nprinted >= 0 && (size_t) nprinted < len - 1)
146  {
147  /* Success. Note nprinted does not include trailing null. */
148  return (size_t) nprinted;
149  }
150 
151  if (nprinted >= 0 && (size_t) nprinted > len)
152  {
153  /*
154  * This appears to be a C99-compliant vsnprintf, so believe its
155  * estimate of the required space. (If it's wrong, the logic will
156  * still work, but we may loop multiple times.) Note that the space
157  * needed should be only nprinted+1 bytes, but we'd better allocate
158  * one more than that so that the test above will succeed next time.
159  *
160  * In the corner case where the required space just barely overflows,
161  * fall through so that we'll error out below (possibly after
162  * looping).
163  */
164  if ((size_t) nprinted <= MaxAllocSize - 2)
165  return nprinted + 2;
166  }
167 
168  /*
169  * Buffer overrun, and we don't know how much space is needed. Estimate
170  * twice the previous buffer size, but not more than MaxAllocSize; if we
171  * are already at MaxAllocSize, choke. Note we use this palloc-oriented
172  * overflow limit even when in frontend.
173  */
174  if (len >= MaxAllocSize)
175  {
176 #ifndef FRONTEND
177  ereport(ERROR,
178  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
179  errmsg("out of memory")));
180 #else
181  fprintf(stderr, _("out of memory\n"));
182  exit(EXIT_FAILURE);
183 #endif
184  }
185 
186  if (len >= MaxAllocSize / 2)
187  return MaxAllocSize;
188 
189  return len * 2;
190 }
int errcode(int sqlerrcode)
Definition: elog.c:575
int int vsnprintf(char *str, size_t count, const char *fmt, va_list args)
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:66
#define ereport(elevel, rest)
Definition: elog.h:122
#define MaxAllocSize
Definition: memutils.h:40
#define Assert(condition)
Definition: c.h:676
int errmsg(const char *fmt,...)
Definition: elog.c:797
const char * strerror(int errnum)
Definition: strerror.c:19
#define EXIT_FAILURE
Definition: settings.h:151
#define elog
Definition: elog.h:219
#define _(x)
Definition: elog.c:84