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-2025, 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
31static bool useReadline;
32static bool useHistory;
33
34static char *psql_history;
35
36static 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
50static 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 */
66char *
67gets_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 */
112void
113pg_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 */
134void
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 {
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 */
185char *
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 */
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 */
298static void
299encode_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 */
318static void
319decode_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 */
343void
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
412static bool
413saveHistory(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 */
493bool
494printHistory(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
539static 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:961
#define Max(x, y)
Definition: c.h:955
#define PG_BINARY
Definition: c.h:1230
#define fprintf(file, fmt, msg)
Definition: cubescan.l:21
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
FILE * PageOutput(int lines, const printTableOpt *topt)
Definition: print.c:3089
void ClosePager(FILE *pagerpipe)
Definition: print.c:3141
#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
static void finishInput(void)
Definition: input.c:540
char * gets_interactive(const char *prompt, PQExpBuffer query_buf)
Definition: input.c:67
char * gets_fromFile(FILE *source)
Definition: input.c:186
void initializeInput(int flags)
Definition: input.c:344
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:72
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
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:43
@ 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