PostgreSQL Source Code  git master
input.c
Go to the documentation of this file.
1 /*
2  * psql - the PostgreSQL interactive terminal
3  *
4  * Copyright (c) 2000-2024, PostgreSQL Global Development Group
5  *
6  * src/bin/psql/input.c
7  */
8 #include "postgres_fe.h"
9 
10 #ifndef WIN32
11 #include <unistd.h>
12 #endif
13 #include <fcntl.h>
14 #include <limits.h>
15 
16 #include "common.h"
17 #include "common/logging.h"
18 #include "input.h"
19 #include "settings.h"
20 #include "tab-complete.h"
21 
22 #ifndef WIN32
23 #define PSQLHISTORY ".psql_history"
24 #else
25 #define PSQLHISTORY "psql_history"
26 #endif
27 
28 /* Runtime options for turning off readline and history */
29 /* (of course there is no runtime command for doing that :) */
30 #ifdef USE_READLINE
31 static bool useReadline;
32 static bool useHistory;
33 
34 static char *psql_history;
35 
36 static int history_lines_added;
37 
38 
39 /*
40  * Preserve newlines in saved queries by mapping '\n' to NL_IN_HISTORY
41  *
42  * It is assumed NL_IN_HISTORY will never be entered by the user
43  * nor appear inside a multi-byte string. 0x00 is not properly
44  * handled by the readline routines so it can not be used
45  * for this purpose.
46  */
47 #define NL_IN_HISTORY 0x01
48 #endif
49 
50 static void finishInput(void);
51 
52 
53 /*
54  * gets_interactive()
55  *
56  * Gets a line of interactive input, using readline if desired.
57  *
58  * prompt: the prompt string to be used
59  * query_buf: buffer containing lines already read in the current command
60  * (query_buf is not modified here, but may be consulted for tab completion)
61  *
62  * The result is a malloc'd string.
63  *
64  * Caller *must* have set up sigint_interrupt_jmp before calling.
65  */
66 char *
67 gets_interactive(const char *prompt, PQExpBuffer query_buf)
68 {
69 #ifdef USE_READLINE
70  if (useReadline)
71  {
72  char *result;
73 
74  /*
75  * Some versions of readline don't notice SIGWINCH signals that arrive
76  * when not actively reading input. The simplest fix is to always
77  * re-read the terminal size. This leaves a window for SIGWINCH to be
78  * missed between here and where readline() enables libreadline's
79  * signal handler, but that's probably short enough to be ignored.
80  */
81 #ifdef HAVE_RL_RESET_SCREEN_SIZE
82  rl_reset_screen_size();
83 #endif
84 
85  /* Make current query_buf available to tab completion callback */
86  tab_completion_query_buf = query_buf;
87 
88  /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
90 
91  result = readline(prompt);
92 
93  /* Disable SIGINT again */
95 
96  /* Pure neatnik-ism */
98 
99  return result;
100  }
101 #endif
102 
103  fputs(prompt, stdout);
104  fflush(stdout);
105  return gets_fromFile(stdin);
106 }
107 
108 
109 /*
110  * Append the line to the history buffer, making sure there is a trailing '\n'
111  */
112 void
113 pg_append_history(const char *s, PQExpBuffer history_buf)
114 {
115 #ifdef USE_READLINE
116  if (useHistory && s)
117  {
118  appendPQExpBufferStr(history_buf, s);
119  if (!s[0] || s[strlen(s) - 1] != '\n')
120  appendPQExpBufferChar(history_buf, '\n');
121  }
122 #endif
123 }
124 
125 
126 /*
127  * Emit accumulated history entry to readline's history mechanism,
128  * then reset the buffer to empty.
129  *
130  * Note: we write nothing if history_buf is empty, so extra calls to this
131  * function don't hurt. There must have been at least one line added by
132  * pg_append_history before we'll do anything.
133  */
134 void
136 {
137 #ifdef USE_READLINE
138  static char *prev_hist = NULL;
139 
140  char *s = history_buf->data;
141  int i;
142 
143  /* Trim any trailing \n's (OK to scribble on history_buf) */
144  for (i = strlen(s) - 1; i >= 0 && s[i] == '\n'; i--)
145  ;
146  s[i + 1] = '\0';
147 
148  if (useHistory && s[0])
149  {
150  if (((pset.histcontrol & hctl_ignorespace) &&
151  s[0] == ' ') ||
153  prev_hist && strcmp(s, prev_hist) == 0))
154  {
155  /* Ignore this line as far as history is concerned */
156  }
157  else
158  {
159  /* Save each previous line for ignoredups processing */
160  free(prev_hist);
161  prev_hist = pg_strdup(s);
162  /* And send it to readline */
163  add_history(s);
164  /* Count lines added to history for use later */
165  history_lines_added++;
166  }
167  }
168 
169  resetPQExpBuffer(history_buf);
170 #endif
171 }
172 
173 
174 /*
175  * gets_fromFile
176  *
177  * Gets a line of noninteractive input from a file (which could be stdin).
178  * The result is a malloc'd string, or NULL on EOF or input error.
179  *
180  * Caller *must* have set up sigint_interrupt_jmp before calling.
181  *
182  * Note: we re-use a static PQExpBuffer for each call. This is to avoid
183  * leaking memory if interrupted by SIGINT.
184  */
185 char *
187 {
188  static PQExpBuffer buffer = NULL;
189 
190  char line[1024];
191 
192  if (buffer == NULL) /* first time through? */
193  buffer = createPQExpBuffer();
194  else
195  resetPQExpBuffer(buffer);
196 
197  for (;;)
198  {
199  char *result;
200 
201  /* Enable SIGINT to longjmp to sigint_interrupt_jmp */
203 
204  /* Get some data */
205  result = fgets(line, sizeof(line), source);
206 
207  /* Disable SIGINT again */
208  sigint_interrupt_enabled = false;
209 
210  /* EOF or error? */
211  if (result == NULL)
212  {
213  if (ferror(source))
214  {
215  pg_log_error("could not read from input file: %m");
216  return NULL;
217  }
218  break;
219  }
220 
221  appendPQExpBufferStr(buffer, line);
222 
223  if (PQExpBufferBroken(buffer))
224  {
225  pg_log_error("out of memory");
226  return NULL;
227  }
228 
229  /* EOL? */
230  if (buffer->len > 0 && buffer->data[buffer->len - 1] == '\n')
231  {
232  buffer->data[buffer->len - 1] = '\0';
233  return pg_strdup(buffer->data);
234  }
235  }
236 
237  if (buffer->len > 0) /* EOF after reading some bufferload(s) */
238  return pg_strdup(buffer->data);
239 
240  /* EOF, so return null */
241  return NULL;
242 }
243 
244 
245 #ifdef USE_READLINE
246 
247 /*
248  * Macros to iterate over each element of the history list in order
249  *
250  * You would think this would be simple enough, but in its inimitable fashion
251  * libedit has managed to break it: in libreadline we must use next_history()
252  * to go from oldest to newest, but in libedit we must use previous_history().
253  * To detect what to do, we make a trial call of previous_history(): if it
254  * fails, then either next_history() is what to use, or there's zero or one
255  * history entry so that it doesn't matter which direction we go.
256  *
257  * In case that wasn't disgusting enough: the code below is not as obvious as
258  * it might appear. In some libedit releases history_set_pos(0) fails until
259  * at least one add_history() call has been done. This is not an issue for
260  * printHistory() or encode_history(), which cannot be invoked before that has
261  * happened. In decode_history(), that's not so, and what actually happens is
262  * that we are sitting on the newest entry to start with, previous_history()
263  * fails, and we iterate over all the entries using next_history(). So the
264  * decode_history() loop iterates over the entries in the wrong order when
265  * using such a libedit release, and if there were another attempt to use
266  * BEGIN_ITERATE_HISTORY() before some add_history() call had happened, it
267  * wouldn't work. Fortunately we don't care about either of those things.
268  *
269  * Usage pattern is:
270  *
271  * BEGIN_ITERATE_HISTORY(varname);
272  * {
273  * loop body referencing varname->line;
274  * }
275  * END_ITERATE_HISTORY();
276  */
277 #define BEGIN_ITERATE_HISTORY(VARNAME) \
278  do { \
279  HIST_ENTRY *VARNAME; \
280  bool use_prev_; \
281  \
282  history_set_pos(0); \
283  use_prev_ = (previous_history() != NULL); \
284  history_set_pos(0); \
285  for (VARNAME = current_history(); VARNAME != NULL; \
286  VARNAME = use_prev_ ? previous_history() : next_history()) \
287  { \
288  (void) 0
289 
290 #define END_ITERATE_HISTORY() \
291  } \
292  } while(0)
293 
294 
295 /*
296  * Convert newlines to NL_IN_HISTORY for safe saving in readline history file
297  */
298 static void
299 encode_history(void)
300 {
301  BEGIN_ITERATE_HISTORY(cur_hist);
302  {
303  char *cur_ptr;
304 
305  /* some platforms declare HIST_ENTRY.line as const char * */
306  for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
307  {
308  if (*cur_ptr == '\n')
309  *cur_ptr = NL_IN_HISTORY;
310  }
311  }
312  END_ITERATE_HISTORY();
313 }
314 
315 /*
316  * Reverse the above encoding
317  */
318 static void
319 decode_history(void)
320 {
321  BEGIN_ITERATE_HISTORY(cur_hist);
322  {
323  char *cur_ptr;
324 
325  /* some platforms declare HIST_ENTRY.line as const char * */
326  for (cur_ptr = (char *) cur_hist->line; *cur_ptr; cur_ptr++)
327  {
328  if (*cur_ptr == NL_IN_HISTORY)
329  *cur_ptr = '\n';
330  }
331  }
332  END_ITERATE_HISTORY();
333 }
334 #endif /* USE_READLINE */
335 
336 
337 /*
338  * Put any startup stuff related to input in here. It's good to maintain
339  * abstraction this way.
340  *
341  * The only "flag" right now is 1 for use readline & history.
342  */
343 void
344 initializeInput(int flags)
345 {
346 #ifdef USE_READLINE
347  if (flags & 1)
348  {
349  const char *histfile;
350  char home[MAXPGPATH];
351 
352  useReadline = true;
353 
354  /* set appropriate values for Readline's global variables */
356 
357 #ifdef HAVE_RL_VARIABLE_BIND
358  /* set comment-begin to a useful value for SQL */
359  (void) rl_variable_bind("comment-begin", "-- ");
360 #endif
361 
362  /* this reads ~/.inputrc, so do it after rl_variable_bind */
363  rl_initialize();
364 
365  useHistory = true;
366  using_history();
367  history_lines_added = 0;
368 
369  histfile = GetVariable(pset.vars, "HISTFILE");
370 
371  if (histfile == NULL)
372  {
373  char *envhist;
374 
375  envhist = getenv("PSQL_HISTORY");
376  if (envhist != NULL && strlen(envhist) > 0)
377  histfile = envhist;
378  }
379 
380  if (histfile == NULL)
381  {
382  if (get_home_path(home))
383  psql_history = psprintf("%s/%s", home, PSQLHISTORY);
384  }
385  else
386  {
387  psql_history = pg_strdup(histfile);
388  expand_tilde(&psql_history);
389  }
390 
391  if (psql_history)
392  {
393  read_history(psql_history);
394  decode_history();
395  }
396  }
397 #endif
398 
399  atexit(finishInput);
400 }
401 
402 
403 /*
404  * This function saves the readline history when psql exits.
405  *
406  * fname: pathname of history file. (Should really be "const char *",
407  * but some ancient versions of readline omit the const-decoration.)
408  *
409  * max_lines: if >= 0, limit history file to that many entries.
410  */
411 #ifdef USE_READLINE
412 static bool
413 saveHistory(char *fname, int max_lines)
414 {
415  int errnum;
416 
417  /*
418  * Suppressing the write attempt when HISTFILE is set to /dev/null may
419  * look like a negligible optimization, but it's necessary on e.g. macOS,
420  * where write_history will fail because it tries to chmod the target
421  * file.
422  */
423  if (strcmp(fname, DEVNULL) != 0)
424  {
425  /*
426  * Encode \n, since otherwise readline will reload multiline history
427  * entries as separate lines. (libedit doesn't really need this, but
428  * we do it anyway since it's too hard to tell which implementation we
429  * are using.)
430  */
431  encode_history();
432 
433  /*
434  * On newer versions of libreadline, truncate the history file as
435  * needed and then append what we've added. This avoids overwriting
436  * history from other concurrent sessions (although there are still
437  * race conditions when two sessions exit at about the same time). If
438  * we don't have those functions, fall back to write_history().
439  */
440 #if defined(HAVE_HISTORY_TRUNCATE_FILE) && defined(HAVE_APPEND_HISTORY)
441  {
442  int nlines;
443  int fd;
444 
445  /* truncate previous entries if needed */
446  if (max_lines >= 0)
447  {
448  nlines = Max(max_lines - history_lines_added, 0);
449  (void) history_truncate_file(fname, nlines);
450  }
451  /* append_history fails if file doesn't already exist :-( */
452  fd = open(fname, O_CREAT | O_WRONLY | PG_BINARY, 0600);
453  if (fd >= 0)
454  close(fd);
455  /* append the appropriate number of lines */
456  if (max_lines >= 0)
457  nlines = Min(max_lines, history_lines_added);
458  else
459  nlines = history_lines_added;
460  errnum = append_history(nlines, fname);
461  if (errnum == 0)
462  return true;
463  }
464 #else /* don't have append support */
465  {
466  /* truncate what we have ... */
467  if (max_lines >= 0)
468  stifle_history(max_lines);
469  /* ... and overwrite file. Tough luck for concurrent sessions. */
470  errnum = write_history(fname);
471  if (errnum == 0)
472  return true;
473  }
474 #endif
475 
476  pg_log_error("could not save history to file \"%s\": %m", fname);
477  }
478  return false;
479 }
480 #endif
481 
482 
483 
484 /*
485  * Print history to the specified file, or to the console if fname is NULL
486  * (psql \s command)
487  *
488  * We used to use saveHistory() for this purpose, but that doesn't permit
489  * use of a pager; moreover libedit's implementation behaves incompatibly
490  * (preferring to encode its output) and may fail outright when the target
491  * file is specified as /dev/tty.
492  */
493 bool
494 printHistory(const char *fname, unsigned short int pager)
495 {
496 #ifdef USE_READLINE
497  FILE *output;
498  bool is_pager;
499 
500  if (!useHistory)
501  return false;
502 
503  if (fname == NULL)
504  {
505  /* use pager, if enabled, when printing to console */
506  output = PageOutput(INT_MAX, pager ? &(pset.popt.topt) : NULL);
507  is_pager = true;
508  }
509  else
510  {
511  output = fopen(fname, "w");
512  if (output == NULL)
513  {
514  pg_log_error("could not save history to file \"%s\": %m", fname);
515  return false;
516  }
517  is_pager = false;
518  }
519 
520  BEGIN_ITERATE_HISTORY(cur_hist);
521  {
522  fprintf(output, "%s\n", cur_hist->line);
523  }
524  END_ITERATE_HISTORY();
525 
526  if (is_pager)
528  else
529  fclose(output);
530 
531  return true;
532 #else
533  pg_log_error("history is not supported by this installation");
534  return false;
535 #endif
536 }
537 
538 
539 static void
541 {
542 #ifdef USE_READLINE
543  if (useHistory && psql_history)
544  {
545  (void) saveHistory(psql_history, pset.histsize);
546  free(psql_history);
547  psql_history = NULL;
548  }
549 #endif
550 }
void expand_tilde(char **filename)
Definition: common.c:2195
volatile sig_atomic_t sigint_interrupt_enabled
Definition: common.c:292
#define Min(x, y)
Definition: c.h:1007
#define Max(x, y)
Definition: c.h:1001
#define PG_BINARY
Definition: c.h:1276
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void ClosePager(FILE *pagerpipe)
Definition: print.c:3141
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3089
#define free(a)
Definition: header.h:65
FILE * output
void pg_send_history(PQExpBuffer history_buf)
Definition: input.c:135
bool printHistory(const char *fname, unsigned short int pager)
Definition: input.c:494
char * gets_interactive(const char *prompt, PQExpBuffer query_buf)
Definition: input.c:67
static void finishInput(void)
Definition: input.c:540
void initializeInput(int flags)
Definition: input.c:344
char * gets_fromFile(FILE *source)
Definition: input.c:186
void pg_append_history(const char *s, PQExpBuffer history_buf)
Definition: input.c:113
#define PSQLHISTORY
Definition: input.c:23
#define close(a)
Definition: win32.h:12
int i
Definition: isn.c:73
static void const char fflush(stdout)
#define pg_log_error(...)
Definition: logging.h:106
#define MAXPGPATH
static rewind_source * source
Definition: pg_rewind.c:89
bool get_home_path(char *ret_path)
Definition: path.c:928
#define DEVNULL
Definition: port.h:160
#define fprintf
Definition: port.h:242
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
#define PQExpBufferBroken(str)
Definition: pqexpbuffer.h:59
static int fd(const char *x, int i)
Definition: preproc-init.c:105
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
@ hctl_ignoredups
Definition: settings.h:78
@ hctl_ignorespace
Definition: settings.h:77
PsqlSettings pset
Definition: startup.c:32
printQueryOpt popt
Definition: settings.h:100
VariableSpace vars
Definition: settings.h:133
HistControl histcontrol
Definition: settings.h:161
printTableOpt topt
Definition: print.h:185
void initialize_readline(void)
PQExpBuffer tab_completion_query_buf
const char * GetVariable(VariableSpace space, const char *name)
Definition: variables.c:71