PostgreSQL Source Code  git master
common.h File Reference
#include "common/username.h"
#include "libpq-fe.h"
#include "getopt_long.h"
#include "pqexpbuffer.h"
Include dependency graph for common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef void(* help_handler) (const char *progname)
 

Enumerations

enum  trivalue {
  TRI_DEFAULT, TRI_NO, TRI_YES, TRI_DEFAULT,
  TRI_NO, TRI_YES, TRI_DEFAULT, TRI_NO,
  TRI_YES, TRI_DEFAULT, TRI_NO, TRI_YES
}
 

Functions

void handle_help_version_opts (int argc, char *argv[], const char *fixed_progname, help_handler hlp)
 
PGconnconnectDatabase (const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo, bool fail_ok, bool allow_password_reuse)
 
PGconnconnectMaintenanceDatabase (const char *maintenance_db, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo)
 
void disconnectDatabase (PGconn *conn)
 
PGresultexecuteQuery (PGconn *conn, const char *query, bool echo)
 
void executeCommand (PGconn *conn, const char *query, bool echo)
 
bool executeMaintenanceCommand (PGconn *conn, const char *query, bool echo)
 
bool consumeQueryResult (PGconn *conn)
 
bool processQueryResult (PGconn *conn, PGresult *result)
 
void splitTableColumnsSpec (const char *spec, int encoding, char **table, const char **columns)
 
void appendQualifiedRelation (PQExpBuffer buf, const char *name, PGconn *conn, bool echo)
 
bool yesno_prompt (const char *question)
 
void setup_cancel_handler (void)
 
void SetCancelConn (PGconn *conn)
 
void ResetCancelConn (void)
 

Variables

bool CancelRequested
 

Typedef Documentation

◆ help_handler

typedef void(* help_handler) (const char *progname)

Definition at line 26 of file common.h.

Enumeration Type Documentation

◆ trivalue

enum trivalue
Enumerator
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 
TRI_DEFAULT 
TRI_NO 
TRI_YES 

Definition at line 17 of file common.h.

18 {
20  TRI_NO,
21  TRI_YES
22 };
Definition: common.h:20
Definition: common.h:21

Function Documentation

◆ appendQualifiedRelation()

void appendQualifiedRelation ( PQExpBuffer  buf,
const char *  name,
PGconn conn,
bool  echo 
)

Definition at line 376 of file common.c.

References ALWAYS_SECURE_SEARCH_PATH_SQL, appendPQExpBufferStr(), appendStringLiteralConn(), PQExpBufferData::data, executeCommand(), executeQuery(), fmtQualifiedId(), initPQExpBuffer(), ngettext, pg_free(), pg_log_error, PQclear(), PQclientEncoding(), PQfinish(), PQgetvalue(), PQntuples(), splitTableColumnsSpec(), and termPQExpBuffer().

Referenced by cluster_one_database(), and run_reindex_command().

378 {
379  char *table;
380  const char *columns;
381  PQExpBufferData sql;
382  PGresult *res;
383  int ntups;
384 
385  splitTableColumnsSpec(spec, PQclientEncoding(conn), &table, &columns);
386 
387  /*
388  * Query must remain ABSOLUTELY devoid of unqualified names. This would
389  * be unnecessary given a regclassin() variant taking a search_path
390  * argument.
391  */
392  initPQExpBuffer(&sql);
394  "SELECT c.relname, ns.nspname\n"
395  " FROM pg_catalog.pg_class c,"
396  " pg_catalog.pg_namespace ns\n"
397  " WHERE c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n"
398  " AND c.oid OPERATOR(pg_catalog.=) ");
399  appendStringLiteralConn(&sql, table, conn);
400  appendPQExpBufferStr(&sql, "::pg_catalog.regclass;");
401 
402  executeCommand(conn, "RESET search_path;", echo);
403 
404  /*
405  * One row is a typical result, as is a nonexistent relation ERROR.
406  * regclassin() unconditionally accepts all-digits input as an OID; if no
407  * relation has that OID; this query returns no rows. Catalog corruption
408  * might elicit other row counts.
409  */
410  res = executeQuery(conn, sql.data, echo);
411  ntups = PQntuples(res);
412  if (ntups != 1)
413  {
414  pg_log_error(ngettext("query returned %d row instead of one: %s",
415  "query returned %d rows instead of one: %s",
416  ntups),
417  ntups, sql.data);
418  PQfinish(conn);
419  exit(1);
420  }
422  fmtQualifiedId(PQgetvalue(res, 0, 1),
423  PQgetvalue(res, 0, 0)));
424  appendPQExpBufferStr(buf, columns);
425  PQclear(res);
426  termPQExpBuffer(&sql);
427  pg_free(table);
428 
430 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQuery(PGconn *conn, const char *query, bool echo)
Definition: common.c:210
void executeCommand(PGconn *conn, const char *query, bool echo)
Definition: common.c:235
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
#define pg_log_error(...)
Definition: logging.h:79
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
int PQclientEncoding(const PGconn *conn)
Definition: fe-connect.c:6677
#define ngettext(s, p, n)
Definition: c.h:1128
void PQclear(PGresult *res)
Definition: fe-exec.c:694
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
Definition: string_utils.c:293
void splitTableColumnsSpec(const char *spec, int encoding, char **table, const char **columns)
Definition: common.c:340
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ connectDatabase()

PGconn* connectDatabase ( const char *  dbname,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname,
bool  echo,
bool  fail_ok,
bool  allow_password_reuse 
)

Definition at line 71 of file common.c.

References ALWAYS_SECURE_SEARCH_PATH_SQL, conn, CONNECTION_BAD, dbname, executeQuery(), have_password, password, pg_log_error, pghost, pgport, PQclear(), PQconnectdbParams(), PQconnectionNeedsPassword(), PQerrorMessage(), PQfinish(), PQstatus(), progname, simple_prompt(), TRI_NO, TRI_YES, and values.

Referenced by connectMaintenanceDatabase().

75 {
76  PGconn *conn;
77  bool new_pass;
78  static bool have_password = false;
79  static char password[100];
80 
81  if (!allow_password_reuse)
82  have_password = false;
83 
84  if (!have_password && prompt_password == TRI_YES)
85  {
86  simple_prompt("Password: ", password, sizeof(password), false);
87  have_password = true;
88  }
89 
90  /*
91  * Start the connection. Loop until we have a password if requested by
92  * backend.
93  */
94  do
95  {
96  const char *keywords[7];
97  const char *values[7];
98 
99  keywords[0] = "host";
100  values[0] = pghost;
101  keywords[1] = "port";
102  values[1] = pgport;
103  keywords[2] = "user";
104  values[2] = pguser;
105  keywords[3] = "password";
106  values[3] = have_password ? password : NULL;
107  keywords[4] = "dbname";
108  values[4] = dbname;
109  keywords[5] = "fallback_application_name";
110  values[5] = progname;
111  keywords[6] = NULL;
112  values[6] = NULL;
113 
114  new_pass = false;
115  conn = PQconnectdbParams(keywords, values, true);
116 
117  if (!conn)
118  {
119  pg_log_error("could not connect to database %s: out of memory",
120  dbname);
121  exit(1);
122  }
123 
124  /*
125  * No luck? Trying asking (again) for a password.
126  */
127  if (PQstatus(conn) == CONNECTION_BAD &&
129  prompt_password != TRI_NO)
130  {
131  PQfinish(conn);
132  simple_prompt("Password: ", password, sizeof(password), false);
133  have_password = true;
134  new_pass = true;
135  }
136  } while (new_pass);
137 
138  /* check to see that the backend connection was successfully made */
139  if (PQstatus(conn) == CONNECTION_BAD)
140  {
141  if (fail_ok)
142  {
143  PQfinish(conn);
144  return NULL;
145  }
146  pg_log_error("could not connect to database %s: %s",
147  dbname, PQerrorMessage(conn));
148  exit(1);
149  }
150 
152 
153  return conn;
154 }
static char password[100]
Definition: streamutil.c:53
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
PGresult * executeQuery(PGconn *conn, const char *query, bool echo)
Definition: common.c:210
#define pg_log_error(...)
Definition: logging.h:79
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
const char * progname
Definition: pg_standby.c:36
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
Definition: fe-connect.c:620
PGconn * conn
Definition: streamutil.c:54
void simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
Definition: sprompt.c:37
char * pghost
Definition: pgbench.c:242
void PQclear(PGresult *res)
Definition: fe-exec.c:694
static bool have_password
Definition: streamutil.c:52
char * dbname
Definition: streamutil.c:50
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int PQconnectionNeedsPassword(const PGconn *conn)
Definition: fe-connect.c:6651
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6564
char * pgport
Definition: pgbench.c:243

◆ connectMaintenanceDatabase()

PGconn* connectMaintenanceDatabase ( const char *  maintenance_db,
const char *  pghost,
const char *  pgport,
const char *  pguser,
enum trivalue  prompt_password,
const char *  progname,
bool  echo 
)

Definition at line 160 of file common.c.

References conn, and connectDatabase().

Referenced by cluster_all_databases(), main(), reindex_all_databases(), and vacuum_all_databases().

164 {
165  PGconn *conn;
166 
167  /* If a maintenance database name was specified, just connect to it. */
168  if (maintenance_db)
169  return connectDatabase(maintenance_db, pghost, pgport, pguser,
170  prompt_password, progname, echo, false, false);
171 
172  /* Otherwise, try postgres first and then template1. */
173  conn = connectDatabase("postgres", pghost, pgport, pguser, prompt_password,
174  progname, echo, true, false);
175  if (!conn)
176  conn = connectDatabase("template1", pghost, pgport, pguser,
177  prompt_password, progname, echo, false, false);
178 
179  return conn;
180 }
const char * progname
Definition: pg_standby.c:36
PGconn * conn
Definition: streamutil.c:54
char * pghost
Definition: pgbench.c:242
PGconn * connectDatabase(const char *dbname, const char *pghost, const char *pgport, const char *pguser, enum trivalue prompt_password, const char *progname, bool echo, bool fail_ok, bool allow_password_reuse)
Definition: common.c:71
char * pgport
Definition: pgbench.c:243

◆ consumeQueryResult()

bool consumeQueryResult ( PGconn conn)

Definition at line 288 of file common.c.

References PQgetResult(), processQueryResult(), ResetCancelConn(), and SetCancelConn().

Referenced by ParallelSlotsGetIdle(), and ParallelSlotsWaitCompletion().

289 {
290  bool ok = true;
291  PGresult *result;
292 
293  SetCancelConn(conn);
294  while ((result = PQgetResult(conn)) != NULL)
295  {
296  if (!processQueryResult(conn, result))
297  ok = false;
298  }
299  ResetCancelConn();
300  return ok;
301 }
bool processQueryResult(PGconn *conn, PGresult *result)
Definition: common.c:309
void SetCancelConn(void)
Definition: common.c:437
void ResetCancelConn(void)
Definition: common.c:467
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1778

◆ disconnectDatabase()

void disconnectDatabase ( PGconn conn)

Definition at line 186 of file common.c.

References Assert, PQcancel(), PQfinish(), PQfreeCancel(), PQgetCancel(), PQTRANS_ACTIVE, and PQtransactionStatus().

Referenced by ParallelSlotsTerminate().

187 {
188  char errbuf[256];
189 
190  Assert(conn != NULL);
191 
192  if (PQtransactionStatus(conn) == PQTRANS_ACTIVE)
193  {
194  PGcancel *cancel;
195 
196  if ((cancel = PQgetCancel(conn)))
197  {
198  (void) PQcancel(cancel, errbuf, sizeof(errbuf));
199  PQfreeCancel(cancel);
200  }
201  }
202 
203  PQfinish(conn);
204 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4263
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:4240
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
Definition: fe-connect.c:6572
#define Assert(condition)
Definition: c.h:733
int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize)
Definition: fe-connect.c:4395

◆ executeCommand()

void executeCommand ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 235 of file common.c.

References pg_log_error, pg_log_info, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQfinish(), PQresultStatus(), and printf.

Referenced by appendQualifiedRelation().

236 {
237  PGresult *res;
238 
239  if (echo)
240  printf("%s\n", query);
241 
242  res = PQexec(conn, query);
243  if (!res ||
245  {
246  pg_log_error("query failed: %s", PQerrorMessage(conn));
247  pg_log_info("query was: %s", query);
248  PQfinish(conn);
249  exit(1);
250  }
251 
252  PQclear(res);
253 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
#define pg_log_error(...)
Definition: logging.h:79
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
#define printf(...)
Definition: port.h:198
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_info(...)
Definition: logging.h:87

◆ executeMaintenanceCommand()

bool executeMaintenanceCommand ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 262 of file common.c.

References PGRES_COMMAND_OK, PQclear(), PQexec(), PQresultStatus(), printf, ResetCancelConn(), and SetCancelConn().

Referenced by cluster_one_database(), and run_reindex_command().

263 {
264  PGresult *res;
265  bool r;
266 
267  if (echo)
268  printf("%s\n", query);
269 
270  SetCancelConn(conn);
271  res = PQexec(conn, query);
272  ResetCancelConn();
273 
274  r = (res && PQresultStatus(res) == PGRES_COMMAND_OK);
275 
276  if (res)
277  PQclear(res);
278 
279  return r;
280 }
#define printf(...)
Definition: port.h:198
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void SetCancelConn(void)
Definition: common.c:437
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
void ResetCancelConn(void)
Definition: common.c:467

◆ executeQuery()

PGresult* executeQuery ( PGconn conn,
const char *  query,
bool  echo 
)

Definition at line 210 of file common.c.

References pg_log_error, pg_log_info, PGRES_TUPLES_OK, PQerrorMessage(), PQexec(), PQfinish(), PQresultStatus(), and printf.

Referenced by appendQualifiedRelation(), and connectDatabase().

211 {
212  PGresult *res;
213 
214  if (echo)
215  printf("%s\n", query);
216 
217  res = PQexec(conn, query);
218  if (!res ||
220  {
221  pg_log_error("query failed: %s", PQerrorMessage(conn));
222  pg_log_info("query was: %s", query);
223  PQfinish(conn);
224  exit(1);
225  }
226 
227  return res;
228 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
#define pg_log_error(...)
Definition: logging.h:79
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
#define printf(...)
Definition: port.h:198
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define pg_log_info(...)
Definition: logging.h:87

◆ handle_help_version_opts()

void handle_help_version_opts ( int  argc,
char *  argv[],
const char *  fixed_progname,
help_handler  hlp 
)

Definition at line 40 of file common.c.

References get_progname(), and printf.

Referenced by main().

42 {
43  if (argc > 1)
44  {
45  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
46  {
47  hlp(get_progname(argv[0]));
48  exit(0);
49  }
50  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
51  {
52  printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
53  exit(0);
54  }
55  }
56 }
const char * get_progname(const char *argv0)
Definition: path.c:453
#define printf(...)
Definition: port.h:198

◆ processQueryResult()

bool processQueryResult ( PGconn conn,
PGresult result 
)

Definition at line 309 of file common.c.

References ERRCODE_UNDEFINED_TABLE, PG_DIAG_SQLSTATE, pg_log_error, PGRES_COMMAND_OK, PQclear(), PQdb(), PQerrorMessage(), PQresultErrorField(), and PQresultStatus().

Referenced by consumeQueryResult(), and ParallelSlotsGetIdle().

310 {
311  /*
312  * If it's an error, report it. Errors about a missing table are harmless
313  * so we continue processing; but die for other errors.
314  */
315  if (PQresultStatus(result) != PGRES_COMMAND_OK)
316  {
317  char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE);
318 
319  pg_log_error("processing of database \"%s\" failed: %s",
320  PQdb(conn), PQerrorMessage(conn));
321 
322  if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) != 0)
323  {
324  PQclear(result);
325  return false;
326  }
327  }
328 
329  PQclear(result);
330  return true;
331 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
#define pg_log_error(...)
Definition: logging.h:79
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
#define ERRCODE_UNDEFINED_TABLE
Definition: common.c:25
void PQclear(PGresult *res)
Definition: fe-exec.c:694
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6467
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:2754

◆ ResetCancelConn()

void ResetCancelConn ( void  )

Definition at line 467 of file common.c.

References cancelConn, and PQfreeCancel().

Referenced by CheckConnection(), consumeQueryResult(), do_connect(), do_lo_export(), do_lo_import(), do_lo_unlink(), executeMaintenanceCommand(), ParallelSlotsGetIdle(), ProcessResult(), PSQLexec(), PSQLexecWatch(), and SendQuery().

468 {
469  PGcancel *oldCancelConn;
470 
471 #ifdef WIN32
472  EnterCriticalSection(&cancelConnLock);
473 #endif
474 
475  oldCancelConn = cancelConn;
476  /* be sure handle_sigint doesn't use pointer while freeing */
477  cancelConn = NULL;
478 
479  if (oldCancelConn != NULL)
480  PQfreeCancel(oldCancelConn);
481 
482 #ifdef WIN32
483  LeaveCriticalSection(&cancelConnLock);
484 #endif
485 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4263
static PGcancel *volatile cancelConn
Definition: common.c:255

◆ SetCancelConn()

void SetCancelConn ( PGconn conn)

Definition at line 475 of file common.c.

References cancelConn, PQfreeCancel(), and PQgetCancel().

476 {
477  PGcancel *oldCancelConn;
478 
479 #ifdef WIN32
480  EnterCriticalSection(&cancelConnLock);
481 #endif
482 
483  /* Free the old one if we have one */
484  oldCancelConn = cancelConn;
485 
486  /* be sure handle_sigint doesn't use pointer while freeing */
487  cancelConn = NULL;
488 
489  if (oldCancelConn != NULL)
490  PQfreeCancel(oldCancelConn);
491 
492  cancelConn = PQgetCancel(conn);
493 
494 #ifdef WIN32
495  LeaveCriticalSection(&cancelConnLock);
496 #endif
497 }
void PQfreeCancel(PGcancel *cancel)
Definition: fe-connect.c:4263
PGcancel * PQgetCancel(PGconn *conn)
Definition: fe-connect.c:4240
static PGcancel *volatile cancelConn
Definition: common.c:28

◆ setup_cancel_handler()

void setup_cancel_handler ( void  )

Definition at line 309 of file common.c.

References _, cancel_pressed, CancelRequested, fprintf, handle_sigint(), PQcancel(), pqsignal(), setup_cancel_handler(), and write_stderr.

Referenced by setup_cancel_handler().

310 {
311  pqsignal(SIGINT, handle_sigint);
312 }
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
static void handle_sigint(SIGNAL_ARGS)
Definition: common.c:278

◆ splitTableColumnsSpec()

void splitTableColumnsSpec ( const char *  spec,
int  encoding,
char **  table,
const char **  columns 
)

Definition at line 340 of file common.c.

References pg_strdup(), and PQmblen().

Referenced by appendQualifiedRelation(), and vacuum_one_database().

342 {
343  bool inquotes = false;
344  const char *cp = spec;
345 
346  /*
347  * Find the first '(' not identifier-quoted. Based on
348  * dequote_downcase_identifier().
349  */
350  while (*cp && (*cp != '(' || inquotes))
351  {
352  if (*cp == '"')
353  {
354  if (inquotes && cp[1] == '"')
355  cp++; /* pair does not affect quoting */
356  else
357  inquotes = !inquotes;
358  cp++;
359  }
360  else
361  cp += PQmblen(cp, encoding);
362  }
363  *table = pg_strdup(spec);
364  (*table)[cp - spec] = '\0'; /* no strndup */
365  *columns = cp;
366 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int32 encoding
Definition: pg_database.h:41
int PQmblen(const char *s, int encoding)
Definition: fe-misc.c:1216

◆ yesno_prompt()

bool yesno_prompt ( const char *  question)

Definition at line 443 of file common.c.

References _, PG_NOLETTER, PG_YESLETTER, printf, simple_prompt(), and snprintf.

Referenced by main().

444 {
445  char prompt[256];
446 
447  /*------
448  translator: This is a question followed by the translated options for
449  "yes" and "no". */
450  snprintf(prompt, sizeof(prompt), _("%s (%s/%s) "),
451  _(question), _(PG_YESLETTER), _(PG_NOLETTER));
452 
453  for (;;)
454  {
455  char resp[10];
456 
457  simple_prompt(prompt, resp, sizeof(resp), true);
458 
459  if (strcmp(resp, _(PG_YESLETTER)) == 0)
460  return true;
461  if (strcmp(resp, _(PG_NOLETTER)) == 0)
462  return false;
463 
464  printf(_("Please answer \"%s\" or \"%s\".\n"),
466  }
467 }
#define PG_YESLETTER
Definition: common.c:438
#define printf(...)
Definition: port.h:198
#define PG_NOLETTER
Definition: common.c:440
void simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo)
Definition: sprompt.c:37
#define snprintf
Definition: port.h:192
#define _(x)
Definition: elog.c:87

Variable Documentation

◆ CancelRequested

bool CancelRequested